Merge pull request #14725 from alalek:update_openexr_2.3.0
authorAlexander Alekhin <alexander.a.alekhin@gmail.com>
Mon, 10 Jun 2019 17:04:23 +0000 (20:04 +0300)
committerGitHub <noreply@github.com>
Mon, 10 Jun 2019 17:04:23 +0000 (20:04 +0300)
3rdparty: update OpenEXR 2.3.0 (#14725)

* openexr 2.2.1

* openexr 2.3.0

* openexr: build fixes

* openexr: build dwa tables on-demand

285 files changed:
3rdparty/openexr/AUTHORS.openexr
3rdparty/openexr/CMakeLists.txt
3rdparty/openexr/ChangeLog.ilmbase
3rdparty/openexr/ChangeLog.openexr
3rdparty/openexr/Half/eLut.h
3rdparty/openexr/Half/half.cpp
3rdparty/openexr/Half/half.h
3rdparty/openexr/Half/halfExport.h [moved from 3rdparty/openexr/Imath/ImathGLU.h with 80% similarity]
3rdparty/openexr/Half/halfFunction.h
3rdparty/openexr/Half/halfLimits.h
3rdparty/openexr/Half/toFloat.cpp [deleted file]
3rdparty/openexr/Iex/Iex.h
3rdparty/openexr/Iex/IexBaseExc.cpp
3rdparty/openexr/Iex/IexBaseExc.h
3rdparty/openexr/Iex/IexErrnoExc.h
3rdparty/openexr/Iex/IexExport.h [new file with mode: 0644]
3rdparty/openexr/Iex/IexForward.h [new file with mode: 0644]
3rdparty/openexr/Iex/IexMacros.h
3rdparty/openexr/Iex/IexMathExc.h
3rdparty/openexr/Iex/IexNamespace.h [new file with mode: 0644]
3rdparty/openexr/Iex/IexThrowErrnoExc.cpp
3rdparty/openexr/Iex/IexThrowErrnoExc.h
3rdparty/openexr/IlmBaseConfig.h.cmakein
3rdparty/openexr/IlmImf/ImfAcesFile.cpp
3rdparty/openexr/IlmImf/ImfAcesFile.h
3rdparty/openexr/IlmImf/ImfArray.h
3rdparty/openexr/IlmImf/ImfAttribute.cpp
3rdparty/openexr/IlmImf/ImfAttribute.h
3rdparty/openexr/IlmImf/ImfAutoArray.h
3rdparty/openexr/IlmImf/ImfB44Compressor.cpp
3rdparty/openexr/IlmImf/ImfB44Compressor.h
3rdparty/openexr/IlmImf/ImfBoxAttribute.cpp
3rdparty/openexr/IlmImf/ImfBoxAttribute.h
3rdparty/openexr/IlmImf/ImfCRgbaFile.cpp
3rdparty/openexr/IlmImf/ImfCRgbaFile.h
3rdparty/openexr/IlmImf/ImfChannelList.cpp
3rdparty/openexr/IlmImf/ImfChannelList.h
3rdparty/openexr/IlmImf/ImfChannelListAttribute.cpp
3rdparty/openexr/IlmImf/ImfChannelListAttribute.h
3rdparty/openexr/IlmImf/ImfCheckedArithmetic.h
3rdparty/openexr/IlmImf/ImfChromaticities.cpp
3rdparty/openexr/IlmImf/ImfChromaticities.h
3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.cpp
3rdparty/openexr/IlmImf/ImfChromaticitiesAttribute.h
3rdparty/openexr/IlmImf/ImfCompositeDeepScanLine.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfCompositeDeepScanLine.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfCompression.h
3rdparty/openexr/IlmImf/ImfCompressionAttribute.cpp
3rdparty/openexr/IlmImf/ImfCompressionAttribute.h
3rdparty/openexr/IlmImf/ImfCompressor.cpp
3rdparty/openexr/IlmImf/ImfCompressor.h
3rdparty/openexr/IlmImf/ImfConvert.cpp
3rdparty/openexr/IlmImf/ImfConvert.h
3rdparty/openexr/IlmImf/ImfDeepCompositing.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepCompositing.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepFrameBuffer.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepFrameBuffer.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepImageState.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepImageStateAttribute.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepImageStateAttribute.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineInputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineInputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineInputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineInputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineOutputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineOutputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineOutputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepScanLineOutputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledInputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledInputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledInputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledInputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledOutputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledOutputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledOutputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDeepTiledOutputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDoubleAttribute.cpp
3rdparty/openexr/IlmImf/ImfDoubleAttribute.h
3rdparty/openexr/IlmImf/ImfDwaCompressor.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDwaCompressor.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfDwaCompressorSimd.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfEnvmap.cpp
3rdparty/openexr/IlmImf/ImfEnvmap.h
3rdparty/openexr/IlmImf/ImfEnvmapAttribute.cpp
3rdparty/openexr/IlmImf/ImfEnvmapAttribute.h
3rdparty/openexr/IlmImf/ImfExport.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfFastHuf.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfFastHuf.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfFloatAttribute.cpp
3rdparty/openexr/IlmImf/ImfFloatAttribute.h
3rdparty/openexr/IlmImf/ImfFloatVectorAttribute.cpp [moved from 3rdparty/openexr/IlmImf/b44ExpLogTable.cpp with 51% similarity]
3rdparty/openexr/IlmImf/ImfFloatVectorAttribute.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfForward.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfFrameBuffer.cpp
3rdparty/openexr/IlmImf/ImfFrameBuffer.h
3rdparty/openexr/IlmImf/ImfFramesPerSecond.cpp
3rdparty/openexr/IlmImf/ImfFramesPerSecond.h
3rdparty/openexr/IlmImf/ImfGenericInputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfGenericInputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfGenericOutputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfGenericOutputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfHeader.cpp
3rdparty/openexr/IlmImf/ImfHeader.h
3rdparty/openexr/IlmImf/ImfHuf.cpp
3rdparty/openexr/IlmImf/ImfHuf.h
3rdparty/openexr/IlmImf/ImfIO.cpp
3rdparty/openexr/IlmImf/ImfIO.h
3rdparty/openexr/IlmImf/ImfInputFile.cpp
3rdparty/openexr/IlmImf/ImfInputFile.h
3rdparty/openexr/IlmImf/ImfInputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfInputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfInputPartData.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfInputPartData.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfInputStreamMutex.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfInt64.h
3rdparty/openexr/IlmImf/ImfIntAttribute.cpp
3rdparty/openexr/IlmImf/ImfIntAttribute.h
3rdparty/openexr/IlmImf/ImfKeyCode.cpp
3rdparty/openexr/IlmImf/ImfKeyCode.h
3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.cpp
3rdparty/openexr/IlmImf/ImfKeyCodeAttribute.h
3rdparty/openexr/IlmImf/ImfLineOrder.h
3rdparty/openexr/IlmImf/ImfLineOrderAttribute.cpp
3rdparty/openexr/IlmImf/ImfLineOrderAttribute.h
3rdparty/openexr/IlmImf/ImfLut.cpp
3rdparty/openexr/IlmImf/ImfLut.h
3rdparty/openexr/IlmImf/ImfMatrixAttribute.cpp
3rdparty/openexr/IlmImf/ImfMatrixAttribute.h
3rdparty/openexr/IlmImf/ImfMisc.cpp
3rdparty/openexr/IlmImf/ImfMisc.h
3rdparty/openexr/IlmImf/ImfMultiPartInputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfMultiPartInputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfMultiPartOutputFile.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfMultiPartOutputFile.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfMultiView.cpp
3rdparty/openexr/IlmImf/ImfMultiView.h
3rdparty/openexr/IlmImf/ImfName.h
3rdparty/openexr/IlmImf/ImfNamespace.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfOpaqueAttribute.cpp
3rdparty/openexr/IlmImf/ImfOpaqueAttribute.h
3rdparty/openexr/IlmImf/ImfOptimizedPixelReading.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfOutputFile.cpp
3rdparty/openexr/IlmImf/ImfOutputFile.h
3rdparty/openexr/IlmImf/ImfOutputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfOutputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfOutputPartData.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfOutputPartData.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfOutputStreamMutex.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfPartHelper.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfPartType.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfPartType.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfPixelType.h
3rdparty/openexr/IlmImf/ImfPizCompressor.cpp
3rdparty/openexr/IlmImf/ImfPizCompressor.h
3rdparty/openexr/IlmImf/ImfPreviewImage.cpp
3rdparty/openexr/IlmImf/ImfPreviewImage.h
3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.cpp
3rdparty/openexr/IlmImf/ImfPreviewImageAttribute.h
3rdparty/openexr/IlmImf/ImfPxr24Compressor.cpp
3rdparty/openexr/IlmImf/ImfPxr24Compressor.h
3rdparty/openexr/IlmImf/ImfRational.cpp
3rdparty/openexr/IlmImf/ImfRational.h
3rdparty/openexr/IlmImf/ImfRationalAttribute.cpp
3rdparty/openexr/IlmImf/ImfRationalAttribute.h
3rdparty/openexr/IlmImf/ImfRgba.h
3rdparty/openexr/IlmImf/ImfRgbaFile.cpp
3rdparty/openexr/IlmImf/ImfRgbaFile.h
3rdparty/openexr/IlmImf/ImfRgbaYca.cpp
3rdparty/openexr/IlmImf/ImfRgbaYca.h
3rdparty/openexr/IlmImf/ImfRle.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfRle.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfRleCompressor.cpp
3rdparty/openexr/IlmImf/ImfRleCompressor.h
3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp
3rdparty/openexr/IlmImf/ImfScanLineInputFile.h
3rdparty/openexr/IlmImf/ImfSimd.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfStandardAttributes.cpp
3rdparty/openexr/IlmImf/ImfStandardAttributes.h
3rdparty/openexr/IlmImf/ImfStdIO.cpp
3rdparty/openexr/IlmImf/ImfStdIO.h
3rdparty/openexr/IlmImf/ImfStringAttribute.cpp
3rdparty/openexr/IlmImf/ImfStringAttribute.h
3rdparty/openexr/IlmImf/ImfStringVectorAttribute.cpp
3rdparty/openexr/IlmImf/ImfStringVectorAttribute.h
3rdparty/openexr/IlmImf/ImfSystemSpecific.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfSystemSpecific.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfTestFile.cpp
3rdparty/openexr/IlmImf/ImfTestFile.h
3rdparty/openexr/IlmImf/ImfThreading.cpp
3rdparty/openexr/IlmImf/ImfThreading.h
3rdparty/openexr/IlmImf/ImfTileDescription.h
3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.cpp
3rdparty/openexr/IlmImf/ImfTileDescriptionAttribute.h
3rdparty/openexr/IlmImf/ImfTileOffsets.cpp
3rdparty/openexr/IlmImf/ImfTileOffsets.h
3rdparty/openexr/IlmImf/ImfTiledInputFile.cpp
3rdparty/openexr/IlmImf/ImfTiledInputFile.h
3rdparty/openexr/IlmImf/ImfTiledInputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfTiledInputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfTiledMisc.cpp
3rdparty/openexr/IlmImf/ImfTiledMisc.h
3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp
3rdparty/openexr/IlmImf/ImfTiledOutputFile.h
3rdparty/openexr/IlmImf/ImfTiledOutputPart.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfTiledOutputPart.h [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfTiledRgbaFile.cpp
3rdparty/openexr/IlmImf/ImfTiledRgbaFile.h
3rdparty/openexr/IlmImf/ImfTimeCode.cpp
3rdparty/openexr/IlmImf/ImfTimeCode.h
3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.cpp
3rdparty/openexr/IlmImf/ImfTimeCodeAttribute.h
3rdparty/openexr/IlmImf/ImfVecAttribute.cpp
3rdparty/openexr/IlmImf/ImfVecAttribute.h
3rdparty/openexr/IlmImf/ImfVersion.cpp
3rdparty/openexr/IlmImf/ImfVersion.h
3rdparty/openexr/IlmImf/ImfWav.cpp
3rdparty/openexr/IlmImf/ImfWav.h
3rdparty/openexr/IlmImf/ImfXdr.h
3rdparty/openexr/IlmImf/ImfZip.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/ImfZip.h [moved from 3rdparty/openexr/Half/eLut.cpp with 53% similarity]
3rdparty/openexr/IlmImf/ImfZipCompressor.cpp
3rdparty/openexr/IlmImf/ImfZipCompressor.h
3rdparty/openexr/IlmImf/dwaLookups.cpp [new file with mode: 0644]
3rdparty/openexr/IlmImf/dwaLookups.h [new file with mode: 0644]
3rdparty/openexr/IlmThread/IlmThread.cpp
3rdparty/openexr/IlmThread/IlmThread.h
3rdparty/openexr/IlmThread/IlmThreadExport.h [new file with mode: 0644]
3rdparty/openexr/IlmThread/IlmThreadForward.h [new file with mode: 0644]
3rdparty/openexr/IlmThread/IlmThreadMutex.cpp
3rdparty/openexr/IlmThread/IlmThreadMutex.h
3rdparty/openexr/IlmThread/IlmThreadMutexPosix.cpp
3rdparty/openexr/IlmThread/IlmThreadMutexWin32.cpp
3rdparty/openexr/IlmThread/IlmThreadNamespace.h [new file with mode: 0644]
3rdparty/openexr/IlmThread/IlmThreadPool.cpp
3rdparty/openexr/IlmThread/IlmThreadPool.h
3rdparty/openexr/IlmThread/IlmThreadPosix.cpp
3rdparty/openexr/IlmThread/IlmThreadSemaphore.cpp
3rdparty/openexr/IlmThread/IlmThreadSemaphore.h
3rdparty/openexr/IlmThread/IlmThreadSemaphorePosix.cpp
3rdparty/openexr/IlmThread/IlmThreadSemaphorePosixCompat.cpp
3rdparty/openexr/IlmThread/IlmThreadSemaphoreWin32.cpp
3rdparty/openexr/IlmThread/IlmThreadWin32.cpp
3rdparty/openexr/Imath/ImathBox.cpp [new file with mode: 0644]
3rdparty/openexr/Imath/ImathBox.h
3rdparty/openexr/Imath/ImathBoxAlgo.h
3rdparty/openexr/Imath/ImathColor.h
3rdparty/openexr/Imath/ImathColorAlgo.cpp
3rdparty/openexr/Imath/ImathColorAlgo.h
3rdparty/openexr/Imath/ImathEuler.h
3rdparty/openexr/Imath/ImathExc.h
3rdparty/openexr/Imath/ImathExport.h [new file with mode: 0644]
3rdparty/openexr/Imath/ImathForward.h [new file with mode: 0644]
3rdparty/openexr/Imath/ImathFrame.h
3rdparty/openexr/Imath/ImathFrustum.h
3rdparty/openexr/Imath/ImathFrustumTest.h
3rdparty/openexr/Imath/ImathFun.cpp
3rdparty/openexr/Imath/ImathFun.h
3rdparty/openexr/Imath/ImathGL.h [deleted file]
3rdparty/openexr/Imath/ImathHalfLimits.h
3rdparty/openexr/Imath/ImathInt64.h
3rdparty/openexr/Imath/ImathInterval.h
3rdparty/openexr/Imath/ImathLimits.h
3rdparty/openexr/Imath/ImathLine.h
3rdparty/openexr/Imath/ImathLineAlgo.h
3rdparty/openexr/Imath/ImathMath.h
3rdparty/openexr/Imath/ImathMatrix.h
3rdparty/openexr/Imath/ImathMatrixAlgo.cpp
3rdparty/openexr/Imath/ImathMatrixAlgo.h
3rdparty/openexr/Imath/ImathNamespace.h [new file with mode: 0644]
3rdparty/openexr/Imath/ImathPlane.h
3rdparty/openexr/Imath/ImathPlatform.h
3rdparty/openexr/Imath/ImathQuat.h
3rdparty/openexr/Imath/ImathRandom.cpp
3rdparty/openexr/Imath/ImathRandom.h
3rdparty/openexr/Imath/ImathRoots.h
3rdparty/openexr/Imath/ImathShear.cpp [new file with mode: 0644]
3rdparty/openexr/Imath/ImathShear.h
3rdparty/openexr/Imath/ImathSphere.h
3rdparty/openexr/Imath/ImathVec.cpp
3rdparty/openexr/Imath/ImathVec.h
3rdparty/openexr/Imath/ImathVecAlgo.h
3rdparty/openexr/OpenEXRConfig.h.cmakein
3rdparty/openexr/fix_msvc2013_errors.patch [deleted file]
CMakeLists.txt
cmake/OpenCVFindLibsGrfmt.cmake

index 2926b13..57299bc 100644 (file)
@@ -8,6 +8,10 @@ Paul Schneider <paultschneider@mac.com>
 Bill Anderson <wja@ilm.com>
 Wojciech Jarosz <wjarosz@ucsd.edu>
 Andrew Kunz <akunz@ilm.com>
+Piotr Stanczyk <pstanczyk@ilm.com>
+Peter Hillman <peterh@weta.co.nz>
+Nick Porcino <nick.porcino@gmail.com>
+Kimball Thurston
 
 Contributors:
 -------------
@@ -20,6 +24,10 @@ Rodrigo Damazio <rdamazio@lsi.usp.br>
 Greg Ward <gward@lmi.net>
 Joseph Goldstone <joseph@lp.com>
 Loren Carpenter, Pixar Animation Studios
+Nicholas Yue <yue.nicholas@gmail.com>
+Yunfeng Bai (ILM)
+Pascal Jette (Autodesk)
+Karl Rasche, DreamWorks Animation <Karl.Rasche@dreamworks.com>
 
 Win32 build system:
 -------------------
index 88e06e9..2ee5146 100644 (file)
@@ -5,15 +5,75 @@
 
 project(openexr CXX)
 
-if(UNIX)
-  if(APPLE)
-    set(HAVE_POSIX_SEMAPHORES 0)  # Unnamed semaphores are not supported: https://github.com/opencv/opencv/issues/9361
+
+if(NOT HAVE_CXX11)
+  ocv_check_compiler_flag(CXX "-std=c++11" HAVE_STD_CXX11 "${OpenCV_SOURCE_DIR}/cmake/checks/cxx11.cpp")
+  if(HAVE_STD_CXX11)
+    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
   else()
-    include(CheckIncludeFile)
-    check_include_file(semaphore.h HAVE_POSIX_SEMAPHORES)
+    if(BUILD_OPENEXR)
+      message(WARNING "OpenCV: builtin OpenEXR requires C++11 support. OpenEXR is disabled.")
+    endif()
+    return()
   endif()
 endif()
 
+
+
+set(ILMBASE_VERSION_MAJOR "2")
+set(ILMBASE_VERSION_MINOR "3")
+set(ILMBASE_VERSION_PATCH "0")
+
+set(ILMBASE_VERSION "${ILMBASE_VERSION_MAJOR}.${ILMBASE_VERSION_MINOR}.${ILMBASE_VERSION_PATCH}")
+set(ILMBASE_VERSION_API ${ILMBASE_VERSION_MAJOR}_${ILMBASE_VERSION_MINOR})
+
+set(OPENEXR_VERSION_MAJOR "2")
+set(OPENEXR_VERSION_MINOR "3")
+set(OPENEXR_VERSION_PATCH "0")
+
+set(OPENEXR_VERSION "${OPENEXR_VERSION_MAJOR}.${OPENEXR_VERSION_MINOR}.${OPENEXR_VERSION_PATCH}")
+set(OPENEXR_VERSION_API ${OPENEXR_VERSION_MAJOR}_${OPENEXR_VERSION_MINOR})
+
+set(OPENEXR_VERSION "${OPENEXR_VERSION}" PARENT_SCOPE)
+
+if(WIN32)
+  set(HAVE_COMPLETE_IOMANIP 1)
+  set(OPENEXR_IMF_HAVE_COMPLETE_IOMANIP 1)
+  set(PLATFORM_WINDOWS 1)
+elseif(APPLE)
+  set(HAVE_POSIX_SEMAPHORES 0)  # Unnamed semaphores are not supported: https://github.com/opencv/opencv/issues/9361
+  if(DARWIN)
+    set(OPENEXR_IMF_HAVE_DARWIN 1)
+  endif()
+elseif(UNIX)
+  include(CheckIncludeFile)
+  check_include_file(semaphore.h HAVE_POSIX_SEMAPHORES)
+endif()
+
+set(ILMBASE_VERSION_API "opencv")
+set(ILMBASE_INTERNAL_NAMESPACE_CUSTOM 1)
+set(IMATH_INTERNAL_NAMESPACE "Imath_${ILMBASE_VERSION_API}")
+set(IEX_INTERNAL_NAMESPACE "Iex_${ILMBASE_VERSION_API}")
+set(ILMTHREAD_INTERNAL_NAMESPACE "IlmThread_${ILMBASE_VERSION_API}")
+
+set(ILMBASE_NAMESPACE_CUSTOM 0)
+set(IMATH_NAMESPACE "Imath")
+set(IEX_NAMESPACE "Iex")
+set(ILMTHREAD_NAMESPACE "IlmThread")
+set(ILMBASE_VERSION_STRING "\"${ILMBASE_VERSION}\"" )
+set(ILMBASE_PACKAGE_STRING "\"IlmBase ${ILMBASE_VERSION}\"" )
+
+
+set(OPENEXR_VERSION_API "opencv")
+set(OPENEXR_IMF_INTERNAL_NAMESPACE_CUSTOM 1)
+set(OPENEXR_IMF_INTERNAL_NAMESPACE "Imf_${ILMBASE_VERSION_API}")
+set(OPENEXR_IMF_NAMESPACE_CUSTOM 0)
+set(OPENEXR_IMF_NAMESPACE "Imf")
+
+set(OPENEXR_VERSION_STRING "\"${OPENEXR_VERSION}\"" )
+set(OPENEXR_PACKAGE_STRING "\"OpenEXR ${OPENEXR_VERSION}\"" )
+
+
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/IlmBaseConfig.h.cmakein"
                "${CMAKE_CURRENT_BINARY_DIR}/IlmBaseConfig.h" @ONLY)
 configure_file("${CMAKE_CURRENT_SOURCE_DIR}/OpenEXRConfig.h.cmakein"
@@ -23,7 +83,8 @@ set(OPENEXR_INCLUDE_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/Half"
                           "${CMAKE_CURRENT_SOURCE_DIR}/Iex"
                           "${CMAKE_CURRENT_SOURCE_DIR}/IlmThread"
                           "${CMAKE_CURRENT_SOURCE_DIR}/Imath"
-                          "${CMAKE_CURRENT_SOURCE_DIR}/IlmImf")
+                          "${CMAKE_CURRENT_SOURCE_DIR}/IlmImf"
+                          "${CMAKE_CURRENT_BINARY_DIR}")
 
 ocv_include_directories("${CMAKE_CURRENT_BINARY_DIR}" ${ZLIB_INCLUDE_DIRS} ${OPENEXR_INCLUDE_PATHS})
 
@@ -31,8 +92,6 @@ file(GLOB lib_srcs Half/half.cpp Iex/*.cpp IlmThread/*.cpp Imath/*.cpp IlmImf/*.
 file(GLOB lib_hdrs Half/*.h Iex/Iex*.h IlmThread/IlmThread*.h Imath/Imath*.h IlmImf/*.h)
 list(APPEND lib_hdrs "${CMAKE_CURRENT_BINARY_DIR}/IlmBaseConfig.h" "${CMAKE_CURRENT_BINARY_DIR}/OpenEXRConfig.h")
 
-ocv_list_filterout(lib_srcs IlmImf/b44ExpLogTable.cpp)
-
 if(WIN32)
   ocv_list_filterout(lib_srcs Posix.*cpp)
 else()
@@ -46,6 +105,10 @@ ocv_warnings_disable(CMAKE_CXX_FLAGS -Wshadow -Wunused -Wsign-compare -Wundef -W
                                      -Wdeprecated-declarations -Wmisleading-indentation -Wdeprecated
                                      -Wsuggest-override -Winconsistent-missing-override
                                      -Wimplicit-fallthrough
+                                     -Wtautological-compare  # clang
+                                     -Wmissing-prototypes  # gcc/clang
+                                     -Wreorder
+                                     -Wunused-result
 )
 if(CV_GCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 8.0)
   ocv_warnings_disable(CMAKE_CXX_FLAGS -Wclass-memaccess)
@@ -82,7 +145,6 @@ if(NOT BUILD_SHARED_LIBS)
   ocv_install_target(IlmImf EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev)
 endif()
 
-ocv_install_3rdparty_licenses(openexr LICENSE AUTHORS.ilmbase AUTHORS.openexr fix_msvc2013_errors.patch)
+ocv_install_3rdparty_licenses(openexr LICENSE AUTHORS.ilmbase AUTHORS.openexr)
 
 set(OPENEXR_INCLUDE_PATHS ${OPENEXR_INCLUDE_PATHS} PARENT_SCOPE)
-set(OPENEXR_VERSION "1.7.1" PARENT_SCOPE)
index 2e409d2..2e79c0f 100644 (file)
@@ -1,3 +1,30 @@
+Version 2.x.x
+       * Bumped version to track OpenEXR
+         (Piotr Stanczyk)
+
+Version 2.0.1
+       * Bumped version to track OpenEXR
+         (Piotr Stanczyk)
+
+Version 2.0.0
+       * Bumped version to track OpenEXR
+         (Piotr Stanczyk)
+       * Numerous minor fixes, missing includes etc
+
+Version 1.1.0.beta.1
+       * Added new module PyIlmBase : python bindings for IlmBase
+         (Nick Rasmussen)
+       * Added git specific files 
+         (Piotr Stanczyk)
+       * Minor fixes for newer gcc versions and OS X.
+         (misc)
+       * Preparation for OpenEXR v2 release { remove message for final release }
+         (Piotr Stanczyk)
+        * Updated the so verison to 10
+         (Piotr Stanczyk)
+       * Initial use of the CMake build system 
+         (Nicholas Yue)
+
 Version 1.0.3
         * Added support for enabling/disabling large stack optimisations, used in
           halfFunction.h.
index 58212f4..32a2cae 100644 (file)
@@ -1,5 +1,43 @@
+Version 2.0.1
+       * Temporarily turning off optimisation code path
+         (Piotr Stanczyk)
+       * Added additional tests for future optimisation refactoring
+         (Piotr Stanczyk / Peter Hillman)
+       * Fixes for StringVectors
+         (Peter Hillman)
+       * Additional checks for type mismatches
+         (Peter Hillman)
+       * Fix for Composite Deep Scanline
+         (Brendan Bolles)
+
+Version 2.0.0
+       * Updated Documentation
+          (Peter Hillman)
+       * Updated Namespacing mechanism
+          (Piotr Stanczyk)
+       * Fixes for succd & predd
+          (Peter Hillman)
+       * Fixes for FPE control registers
+          (Piotr Stanczyk)
+       * Additional checks and tests on DeepImages, scanlines and tiles
+          (Peter Hillman)
+       * Folded in Autodesk read optimisations for RGB(A) files
+         (Pascal Jette, Peter Hillman)
+       * Updated the bootstrap scripts to use libtoolize if glibtoolize isn't available on darwin. 
+         (Nick Rasmussen)
+       * Numerous minor fixes, missing includes etc
+
+Version 2.0.0.beta.1:
+* Please read the separate file for v2 additions and changes.
+       * Added git specific files 
+         (Piotr Stanczyk)
+       * Updated the so verison to 20
+         (Piotr Stanczyk)
+       * Initial use of the CMake build system 
+         (Nicholas Yue)
+
 Version 1.7.1:
-        * Updated the .so verison to 7.
+       * Updated the .so verison to 7.
          (Piotr Stanczyk)     
 
 Version 1.7.0:
index 845bdd0..f028cdb 100644 (file)
@@ -4,68 +4,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,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,  1024,  2048,  3072,  4096,  5120,  6144,  7168,
-     8192,  9216, 10240, 11264, 12288, 13312, 14336, 15360,
-    16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552,
-    24576, 25600, 26624, 27648, 28672, 29696,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0, 33792, 34816, 35840, 36864, 37888, 38912, 39936,
-    40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128,
-    49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320,
-    57344, 58368, 59392, 60416, 61440, 62464,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
-        0,     0,     0,     0,     0,     0,     0,     0,
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,  1024,  2048,  3072,  4096,  5120,  6144,  7168, 
+     8192,  9216, 10240, 11264, 12288, 13312, 14336, 15360, 
+    16384, 17408, 18432, 19456, 20480, 21504, 22528, 23552, 
+    24576, 25600, 26624, 27648, 28672, 29696,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0, 33792, 34816, 35840, 36864, 37888, 38912, 39936, 
+    40960, 41984, 43008, 44032, 45056, 46080, 47104, 48128, 
+    49152, 50176, 51200, 52224, 53248, 54272, 55296, 56320, 
+    57344, 58368, 59392, 60416, 61440, 62464,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
+        0,     0,     0,     0,     0,     0,     0,     0, 
 };
index 281fe57..09a50aa 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -53,11 +53,10 @@ using namespace std;
 // Lookup tables for half-to-float and float-to-half conversion
 //-------------------------------------------------------------
 
-HALF_EXPORT_CONST half::uif half::_toFloat[1 << 16] =
-#include "toFloat.h"
-HALF_EXPORT_CONST unsigned short half::_eLut[1 << 9] =
-#include "eLut.h"
-
+HALF_EXPORT const half::uif half::_toFloat[1 << 16] =
+    #include "toFloat.h"
+HALF_EXPORT const unsigned short half::_eLut[1 << 9] =
+    #include "eLut.h"
 
 //-----------------------------------------------
 // Overflow handler for float-to-half conversion;
@@ -65,14 +64,14 @@ HALF_EXPORT_CONST unsigned short half::_eLut[1 << 9] =
 // which may be trapped by the operating system.
 //-----------------------------------------------
 
-float
+HALF_EXPORT float
 half::overflow ()
 {
     volatile float f = 1e10;
 
-    for (int i = 0; i < 10; i++)
-    f *= f;                            // this will overflow before
-                    // the for­loop terminates
+    for (int i = 0; i < 10; i++)       
+       f *= f;                         // this will overflow before
+                                       // the for­loop terminates
     return f;
 }
 
@@ -82,7 +81,7 @@ half::overflow ()
 // zeroes, denormalized numbers and exponent overflows.
 //-----------------------------------------------------
 
-short
+HALF_EXPORT short
 half::convert (int i)
 {
     //
@@ -95,9 +94,9 @@ half::convert (int i)
     // of float and half (127 versus 15).
     //
 
-    register int s =  (i >> 16) & 0x00008000;
-    register int e = ((i >> 23) & 0x000000ff) - (127 - 15);
-    register int m =   i        & 0x007fffff;
+    int s =  (i >> 16) & 0x00008000;
+    int e = ((i >> 23) & 0x000000ff) - (127 - 15);
+    int m =   i        & 0x007fffff;
 
     //
     // Now reassemble s, e and m into a half:
@@ -105,115 +104,115 @@ half::convert (int i)
 
     if (e <= 0)
     {
-    if (e < -10)
-    {
-        //
-        // E is less than -10.  The absolute value of f is
-        // less than HALF_MIN (f may be a small normalized
-        // float, a denormalized float or a zero).
-        //
-        // We convert f to a half zero with the same sign as f.
-        //
-
-        return s;
-    }
-
-    //
-    // E is between -10 and 0.  F is a normalized float
-    // whose magnitude is less than HALF_NRM_MIN.
-    //
-    // We convert f to a denormalized half.
-    //
-
-    //
-    // Add an explicit leading 1 to the significand.
-    //
-
-    m = m | 0x00800000;
-
-    //
-    // Round to m to the nearest (10+e)-bit value (with e between
-    // -10 and 0); in case of a tie, round to the nearest even value.
-    //
-    // Rounding may cause the significand to overflow and make
-    // our number normalized.  Because of the way a half's bits
-    // are laid out, we don't have to treat this case separately;
-    // the code below will handle it correctly.
-    //
-
-    int t = 14 - e;
-    int a = (1 << (t - 1)) - 1;
-    int b = (m >> t) & 1;
-
-    m = (m + a + b) >> t;
-
-    //
-    // Assemble the half from s, e (zero) and m.
-    //
-
-    return s | m;
+       if (e < -10)
+       {
+           //
+           // E is less than -10.  The absolute value of f is
+           // less than HALF_MIN (f may be a small normalized
+           // float, a denormalized float or a zero).
+           //
+           // We convert f to a half zero with the same sign as f.
+           //
+
+           return s;
+       }
+
+       //
+       // E is between -10 and 0.  F is a normalized float
+       // whose magnitude is less than HALF_NRM_MIN.
+       //
+       // We convert f to a denormalized half.
+       //
+
+       //
+       // Add an explicit leading 1 to the significand.
+       // 
+
+       m = m | 0x00800000;
+
+       //
+       // Round to m to the nearest (10+e)-bit value (with e between
+       // -10 and 0); in case of a tie, round to the nearest even value.
+       //
+       // Rounding may cause the significand to overflow and make
+       // our number normalized.  Because of the way a half's bits
+       // are laid out, we don't have to treat this case separately;
+       // the code below will handle it correctly.
+       // 
+
+       int t = 14 - e;
+       int a = (1 << (t - 1)) - 1;
+       int b = (m >> t) & 1;
+
+       m = (m + a + b) >> t;
+
+       //
+       // Assemble the half from s, e (zero) and m.
+       //
+
+       return s | m;
     }
     else if (e == 0xff - (127 - 15))
     {
-    if (m == 0)
-    {
-        //
-        // F is an infinity; convert f to a half
-        // infinity with the same sign as f.
-        //
-
-        return s | 0x7c00;
-    }
-    else
-    {
-        //
-        // F is a NAN; we produce a half NAN that preserves
-        // the sign bit and the 10 leftmost bits of the
-        // significand of f, with one exception: If the 10
-        // leftmost bits are all zero, the NAN would turn
-        // into an infinity, so we have to set at least one
-        // bit in the significand.
-        //
-
-        m >>= 13;
-        return s | 0x7c00 | m | (m == 0);
-    }
+       if (m == 0)
+       {
+           //
+           // F is an infinity; convert f to a half
+           // infinity with the same sign as f.
+           //
+
+           return s | 0x7c00;
+       }
+       else
+       {
+           //
+           // F is a NAN; we produce a half NAN that preserves
+           // the sign bit and the 10 leftmost bits of the
+           // significand of f, with one exception: If the 10
+           // leftmost bits are all zero, the NAN would turn 
+           // into an infinity, so we have to set at least one
+           // bit in the significand.
+           //
+
+           m >>= 13;
+           return s | 0x7c00 | m | (m == 0);
+       }
     }
     else
     {
-    //
-    // E is greater than zero.  F is a normalized float.
-    // We try to convert f to a normalized half.
-    //
-
-    //
-    // Round to m to the nearest 10-bit value.  In case of
-    // a tie, round to the nearest even value.
-    //
-
-    m = m + 0x00000fff + ((m >> 13) & 1);
-
-    if (m & 0x00800000)
-    {
-        m =  0;                // overflow in significand,
-        e += 1;                // adjust exponent
-    }
-
-    //
-    // Handle exponent overflow
-    //
-
-    if (e > 30)
-    {
-        overflow ();   // Cause a hardware floating point overflow;
-        return s | 0x7c00;     // if this returns, the half becomes an
-    }                          // infinity with the same sign as f.
-
-    //
-    // Assemble the half from s, e and m.
-    //
-
-    return s | (e << 10) | (m >> 13);
+       //
+       // E is greater than zero.  F is a normalized float.
+       // We try to convert f to a normalized half.
+       //
+
+       //
+       // Round to m to the nearest 10-bit value.  In case of
+       // a tie, round to the nearest even value.
+       //
+
+       m = m + 0x00000fff + ((m >> 13) & 1);
+
+       if (m & 0x00800000)
+       {
+           m =  0;             // overflow in significand,
+           e += 1;             // adjust exponent
+       }
+
+       //
+       // Handle exponent overflow
+       //
+
+       if (e > 30)
+       {
+           overflow ();        // Cause a hardware floating point overflow;
+           return s | 0x7c00;  // if this returns, the half becomes an
+       }                       // infinity with the same sign as f.
+
+       //
+       // Assemble the half from s, e and m.
+       //
+
+       return s | (e << 10) | (m >> 13);
     }
 }
 
@@ -222,7 +221,7 @@ half::convert (int i)
 // Stream I/O operators
 //---------------------
 
-ostream &
+HALF_EXPORT ostream &
 operator << (ostream &os, half h)
 {
     os << float (h);
@@ -230,7 +229,7 @@ operator << (ostream &os, half h)
 }
 
 
-istream &
+HALF_EXPORT istream &
 operator >> (istream &is, half &h)
 {
     float f;
@@ -245,22 +244,22 @@ operator >> (istream &is, half &h)
 // floats and halfs, mostly for debugging
 //---------------------------------------
 
-void
+HALF_EXPORT void
 printBits (ostream &os, half h)
 {
     unsigned short b = h.bits();
 
     for (int i = 15; i >= 0; i--)
     {
-    os << (((b >> i) & 1)? '1': '0');
+       os << (((b >> i) & 1)? '1': '0');
 
-    if (i == 15 || i == 10)
-        os << ' ';
+       if (i == 15 || i == 10)
+           os << ' ';
     }
 }
 
 
-void
+HALF_EXPORT void
 printBits (ostream &os, float f)
 {
     half::uif x;
@@ -268,32 +267,32 @@ printBits (ostream &os, float f)
 
     for (int i = 31; i >= 0; i--)
     {
-    os << (((x.i >> i) & 1)? '1': '0');
+       os << (((x.i >> i) & 1)? '1': '0');
 
-    if (i == 31 || i == 23)
-        os << ' ';
+       if (i == 31 || i == 23)
+           os << ' ';
     }
 }
 
 
-void
+HALF_EXPORT void
 printBits (char c[19], half h)
 {
     unsigned short b = h.bits();
 
     for (int i = 15, j = 0; i >= 0; i--, j++)
     {
-    c[j] = (((b >> i) & 1)? '1': '0');
+       c[j] = (((b >> i) & 1)? '1': '0');
 
-    if (i == 15 || i == 10)
-        c[++j] = ' ';
+       if (i == 15 || i == 10)
+           c[++j] = ' ';
     }
-
+    
     c[18] = 0;
 }
 
 
-void
+HALF_EXPORT void
 printBits (char c[35], float f)
 {
     half::uif x;
@@ -301,10 +300,10 @@ printBits (char c[35], float f)
 
     for (int i = 31, j = 0; i >= 0; i--, j++)
     {
-    c[j] = (((x.i >> i) & 1)? '1': '0');
+       c[j] = (((x.i >> i) & 1)? '1': '0');
 
-    if (i == 31 || i == 23)
-        c[++j] = ' ';
+       if (i == 31 || i == 23)
+           c[++j] = ' ';
     }
 
     c[34] = 0;
index da5500e..fe8c0a1 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #ifndef _HALF_H_
 #define _HALF_H_
 
+#include "halfExport.h"    // for definition of HALF_EXPORT
 #include <iostream>
 
-#if defined(OPENEXR_DLL)
-    #if defined(HALF_EXPORTS)
-    #define HALF_EXPORT __declspec(dllexport)
-    #else
-    #define HALF_EXPORT __declspec(dllimport)
-    #endif
-    #define HALF_EXPORT_CONST
-#else
-    #define HALF_EXPORT
-    #define HALF_EXPORT_CONST const
-#endif
-
-class HALF_EXPORT half
+class half
 {
   public:
 
@@ -208,45 +197,47 @@ class HALF_EXPORT half
     // Access to the internal representation
     //--------------------------------------
 
-    unsigned short     bits () const;
-    void               setBits (unsigned short bits);
+    HALF_EXPORT unsigned short bits () const;
+    HALF_EXPORT void           setBits (unsigned short bits);
 
 
   public:
 
     union uif
     {
-    unsigned int       i;
-    float              f;
+       unsigned int    i;
+       float           f;
     };
 
   private:
 
-    static short       convert (int i);
-    static float       overflow ();
+    HALF_EXPORT static short                  convert (int i);
+    HALF_EXPORT static float                  overflow ();
 
-    unsigned short     _h;
+    unsigned short                            _h;
 
-    static HALF_EXPORT_CONST uif               _toFloat[1 << 16];
-    static HALF_EXPORT_CONST unsigned short _eLut[1 << 9];
+    HALF_EXPORT static const uif              _toFloat[1 << 16];
+    HALF_EXPORT static const unsigned short   _eLut[1 << 9];
 };
 
+
+
 //-----------
 // Stream I/O
 //-----------
 
-HALF_EXPORT std::ostream &             operator << (std::ostream &os, half  h);
-HALF_EXPORT std::istream &             operator >> (std::istream &is, half &h);
+HALF_EXPORT std::ostream &      operator << (std::ostream &os, half  h);
+HALF_EXPORT std::istream &      operator >> (std::istream &is, half &h);
 
 
 //----------
 // Debugging
 //----------
 
-HALF_EXPORT void                       printBits   (std::ostream &os, half  h);
-HALF_EXPORT void                       printBits   (std::ostream &os, float f);
-HALF_EXPORT void                       printBits   (char  c[19], half  h);
-HALF_EXPORT void                       printBits   (char  c[35], float f);
+HALF_EXPORT void        printBits   (std::ostream &os, half  h);
+HALF_EXPORT void        printBits   (std::ostream &os, float f);
+HALF_EXPORT void        printBits   (char  c[19], half  h);
+HALF_EXPORT void        printBits   (char  c[35], float f);
 
 
 //-------------------------------------------------------------------------
@@ -266,7 +257,7 @@ HALF_EXPORT void                    printBits   (char  c[35], float f);
   #define HALF_MAX     65504.0f        // Largest positive half
 
   #define HALF_EPSILON 0.00097656f     // Smallest positive e for which
-                    // half (1.0 + e) != half (1.0)
+                                       // half (1.0 + e) != half (1.0)
 #else
 
   #define HALF_MIN     5.96046448e-08  // Smallest positive half
@@ -276,35 +267,39 @@ HALF_EXPORT void                  printBits   (char  c[35], float f);
   #define HALF_MAX     65504.0         // Largest positive half
 
   #define HALF_EPSILON 0.00097656      // Smallest positive e for which
-                    // half (1.0 + e) != half (1.0)
+                                       // half (1.0 + e) != half (1.0)
 #endif
 
 
 #define HALF_MANT_DIG  11              // Number of digits in mantissa
-                    // (significand + hidden leading 1)
+                                       // (significand + hidden leading 1)
 
 #define HALF_DIG       2               // Number of base 10 digits that
-                    // can be represented without change
+                                       // can be represented without change
+
+#define HALF_DECIMAL_DIG       5       // Number of base-10 digits that are
+                                       // necessary to uniquely represent all
+                                       // distinct values
 
 #define HALF_RADIX     2               // Base of the exponent
 
 #define HALF_MIN_EXP   -13             // Minimum negative integer such that
-                    // HALF_RADIX raised to the power of
-                    // one less than that integer is a
-                    // normalized half
+                                       // HALF_RADIX raised to the power of
+                                       // one less than that integer is a
+                                       // normalized half
 
 #define HALF_MAX_EXP   16              // Maximum positive integer such that
-                    // HALF_RADIX raised to the power of
-                    // one less than that integer is a
-                    // normalized half
+                                       // HALF_RADIX raised to the power of
+                                       // one less than that integer is a
+                                       // normalized half
 
 #define HALF_MIN_10_EXP        -4              // Minimum positive integer such
-                    // that 10 raised to that power is
-                    // a normalized half
+                                       // that 10 raised to that power is
+                                       // a normalized half
 
 #define HALF_MAX_10_EXP        4               // Maximum positive integer such
-                    // that 10 raised to that power is
-                    // a normalized half
+                                       // that 10 raised to that power is
+                                       // a normalized half
 
 
 //---------------------------------------------------------------------------
@@ -317,9 +312,9 @@ HALF_EXPORT void                    printBits   (char  c[35], float f);
 //     floating point number, whose bits are arranged as follows:
 //
 //         31 (msb)
-//         |
+//         | 
 //         | 30     23
-//         | |      |
+//         | |      | 
 //         | |      | 22                    0 (lsb)
 //         | |      | |                     |
 //         X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX
@@ -363,7 +358,7 @@ HALF_EXPORT void                    printBits   (char  c[35], float f);
 //     Here is the bit-layout for a half number, h:
 //
 //         15 (msb)
-//         |
+//         | 
 //         | 14  10
 //         | |   |
 //         | |   | 9        0 (lsb)
@@ -443,53 +438,53 @@ half::half (float f)
 
     if (f == 0)
     {
-    //
-    // Common special case - zero.
-    // Preserve the zero's sign bit.
-    //
+       //
+       // Common special case - zero.
+       // Preserve the zero's sign bit.
+       //
 
-    _h = (x.i >> 16);
+       _h = (x.i >> 16);
     }
     else
     {
-    //
-    // We extract the combined sign and exponent, e, from our
-    // floating-point number, f.  Then we convert e to the sign
-    // and exponent of the half number via a table lookup.
-    //
-    // For the most common case, where a normalized half is produced,
-    // the table lookup returns a non-zero value; in this case, all
-    // we have to do is round f's significand to 10 bits and combine
-    // the result with e.
-    //
-    // For all other cases (overflow, zeroes, denormalized numbers
-    // resulting from underflow, infinities and NANs), the table
-    // lookup returns zero, and we call a longer, non-inline function
-    // to do the float-to-half conversion.
-    //
-
-    register int e = (x.i >> 23) & 0x000001ff;
-
-    e = _eLut[e];
-
-    if (e)
-    {
-        //
-        // Simple case - round the significand, m, to 10
-        // bits and combine it with the sign and exponent.
-        //
-
-        register int m = x.i & 0x007fffff;
-        _h = e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13);
-    }
-    else
-    {
-        //
-        // Difficult case - call a function.
-        //
-
-        _h = convert (x.i);
-    }
+       //
+       // We extract the combined sign and exponent, e, from our
+       // floating-point number, f.  Then we convert e to the sign
+       // and exponent of the half number via a table lookup.
+       //
+       // For the most common case, where a normalized half is produced,
+       // the table lookup returns a non-zero value; in this case, all
+       // we have to do is round f's significand to 10 bits and combine
+       // the result with e.
+       //
+       // For all other cases (overflow, zeroes, denormalized numbers
+       // resulting from underflow, infinities and NANs), the table
+       // lookup returns zero, and we call a longer, non-inline function
+       // to do the float-to-half conversion.
+       //
+
+       int e = (x.i >> 23) & 0x000001ff;
+
+       e = _eLut[e];
+
+       if (e)
+       {
+           //
+           // Simple case - round the significand, m, to 10
+           // bits and combine it with the sign and exponent.
+           //
+
+           int m = x.i & 0x007fffff;
+           _h = (unsigned short)(e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13));
+       }
+       else
+       {
+           //
+           // Difficult case - call a function.
+           //
+
+           _h = convert (x.i);
+       }
     }
 }
 
@@ -517,7 +512,7 @@ half::round (unsigned int n) const
     //
 
     if (n >= 10)
-    return *this;
+       return *this;
 
     //
     // Disassemble h into the sign, s,
@@ -544,13 +539,13 @@ half::round (unsigned int n) const
 
     if (e >= 0x7c00)
     {
-    //
-    // Overflow occurred -- truncate instead of rounding.
-    //
+       //
+       // Overflow occurred -- truncate instead of rounding.
+       //
 
-    e = _h;
-    e >>= 10 - n;
-    e <<= 10 - n;
+       e = _h;
+       e >>= 10 - n;
+       e <<= 10 - n;
     }
 
     //
@@ -568,7 +563,7 @@ half::round (unsigned int n) const
 // Other inline functions
 //-----------------------
 
-inline half
+inline half    
 half::operator - () const
 {
     half h;
@@ -657,7 +652,7 @@ half::operator /= (float f)
 }
 
 
-inline bool
+inline bool    
 half::isFinite () const
 {
     unsigned short e = (_h >> 10) & 0x001f;
@@ -707,7 +702,7 @@ half::isInfinity () const
 }
 
 
-inline bool
+inline bool    
 half::isNegative () const
 {
     return (_h & 0x8000) != 0;
similarity index 80%
rename from 3rdparty/openexr/Imath/ImathGLU.h
rename to 3rdparty/openexr/Half/halfExport.h
index 1c01697..6ae84e7 100644 (file)
@@ -1,6 +1,6 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2008, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
 //
 // All rights reserved.
 //
 ///////////////////////////////////////////////////////////////////////////
 
+#ifndef HALFEXPORT_H
+#define HALFEXPORT_H
 
+#if defined(OPENEXR_DLL)
+    #if defined(HALF_EXPORTS)
+    #define HALF_EXPORT __declspec(dllexport)
+    #else
+    #define HALF_EXPORT __declspec(dllimport)
+    #endif
+    #define HALF_EXPORT_CONST
+#else
+    #define HALF_EXPORT
+    #define HALF_EXPORT_CONST const
+#endif
 
-#ifndef INCLUDED_IMATHGLU_H
-#define INCLUDED_IMATHGLU_H
-
-#include <GL/gl.h>
-#include <GL/glu.h>
-
-#include "ImathVec.h"
-
-inline
-void
-gluLookAt(const Imath::V3f &pos, const Imath::V3f &interest, const Imath::V3f &up)
-{
-    gluLookAt(pos.x,      pos.y,      pos.z,
-              interest.x, interest.y, interest.z,
-              up.x,       up.y,       up.z);
-}
+#endif // #ifndef HALFEXPORT_H
 
-#endif
index 6e0b990..98c1d17 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "half.h"
 
-#include <IlmBaseConfig.h>
-#ifndef ILMBASE_HAVE_LARGE_STACK
+#include "IlmBaseConfig.h"
+#ifndef ILMBASE_HAVE_LARGE_STACK  
 #include <string.h>     // need this for memset
-#else
+#else 
 #endif
 
 #include <float.h>
@@ -105,17 +105,17 @@ class halfFunction
 
     template <class Function>
     halfFunction (Function f,
-          half domainMin = -HALF_MAX,
-          half domainMax =  HALF_MAX,
-          T defaultValue = 0,
-          T posInfValue  = 0,
-          T negInfValue  = 0,
-          T nanValue     = 0);
+                 half domainMin = -HALF_MAX,
+                 half domainMax =  HALF_MAX,
+                 T defaultValue = 0,
+                 T posInfValue  = 0,
+                 T negInfValue  = 0,
+                 T nanValue     = 0);
 
 #ifndef ILMBASE_HAVE_LARGE_STACK
-    ~halfFunction () { delete [] _lut; }
+    ~halfFunction () { delete [] _lut; }    
 #endif
-
+    
     //-----------
     // Evaluation
     //-----------
@@ -123,6 +123,7 @@ class halfFunction
     T          operator () (half x) const;
 
   private:
+
 #ifdef ILMBASE_HAVE_LARGE_STACK
     T          _lut[1 << 16];
 #else
@@ -138,31 +139,31 @@ class halfFunction
 template <class T>
 template <class Function>
 halfFunction<T>::halfFunction (Function f,
-                   half domainMin,
-                   half domainMax,
-                   T defaultValue,
-                   T posInfValue,
-                   T negInfValue,
-                   T nanValue)
+                              half domainMin,
+                              half domainMax,
+                              T defaultValue,
+                              T posInfValue,
+                              T negInfValue,
+                              T nanValue)
 {
 #ifndef ILMBASE_HAVE_LARGE_STACK
     _lut = new T[1<<16];
     memset (_lut, 0 , (1<<16) * sizeof(T));
 #endif
-
+    
     for (int i = 0; i < (1 << 16); i++)
     {
-    half x;
-    x.setBits (i);
-
-    if (x.isNan())
-        _lut[i] = nanValue;
-    else if (x.isInfinity())
-        _lut[i] = x.isNegative()? negInfValue: posInfValue;
-    else if (x < domainMin || x > domainMax)
-        _lut[i] = defaultValue;
-    else
-        _lut[i] = f (x);
+       half x;
+       x.setBits (i);
+
+       if (x.isNan())
+           _lut[i] = nanValue;
+       else if (x.isInfinity())
+           _lut[i] = x.isNegative()? negInfValue: posInfValue;
+       else if (x < domainMin || x > domainMax)
+           _lut[i] = defaultValue;
+       else
+           _lut[i] = f (x);
     }
 }
 
index 77dafff..351db8f 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -94,6 +94,15 @@ class numeric_limits <half>
     static const bool traps = true;
     static const bool tinyness_before = false;
     static const float_round_style round_style = round_to_nearest;
+
+#if __cplusplus >= 201103L
+
+    // C++11 additions.
+    static constexpr int max_digits10 = HALF_DECIMAL_DIG;
+    static half lowest () {return -HALF_MAX;}
+
+#endif
+
 };
 
 
diff --git a/3rdparty/openexr/Half/toFloat.cpp b/3rdparty/openexr/Half/toFloat.cpp
deleted file mode 100644 (file)
index 1327f56..0000000
+++ /dev/null
@@ -1,164 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
-// Digital Ltd. LLC
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// *       Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// *       Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-
-
-//---------------------------------------------------------------------------
-//
-//     toFloat
-//
-//     A program to generate the lookup table for half-to-float
-//     conversion needed by class half.
-//     The program loops over all 65536 possible half numbers,
-//     converts each of them to a float, and prints the result.
-//
-//---------------------------------------------------------------------------
-
-
-#include <iostream>
-#include <iomanip>
-
-using namespace std;
-
-//---------------------------------------------------
-// Interpret an unsigned short bit pattern as a half,
-// and convert that half to the corresponding float's
-// bit pattern.
-//---------------------------------------------------
-
-unsigned int
-halfToFloat (unsigned short y)
-{
-
-    int s = (y >> 15) & 0x00000001;
-    int e = (y >> 10) & 0x0000001f;
-    int m =  y        & 0x000003ff;
-
-    if (e == 0)
-    {
-    if (m == 0)
-    {
-        //
-        // Plus or minus zero
-        //
-
-        return s << 31;
-    }
-    else
-    {
-        //
-        // Denormalized number -- renormalize it
-        //
-
-        while (!(m & 0x00000400))
-        {
-        m <<= 1;
-        e -=  1;
-        }
-
-        e += 1;
-        m &= ~0x00000400;
-    }
-    }
-    else if (e == 31)
-    {
-    if (m == 0)
-    {
-        //
-        // Positive or negative infinity
-        //
-
-        return (s << 31) | 0x7f800000;
-    }
-    else
-    {
-        //
-        // Nan -- preserve sign and significand bits
-        //
-
-        return (s << 31) | 0x7f800000 | (m << 13);
-    }
-    }
-
-    //
-    // Normalized number
-    //
-
-    e = e + (127 - 15);
-    m = m << 13;
-
-    //
-    // Assemble s, e and m.
-    //
-
-    return (s << 31) | (e << 23) | m;
-}
-
-
-//---------------------------------------------
-// Main - prints the half-to-float lookup table
-//---------------------------------------------
-
-int
-main ()
-{
-    cout.precision (9);
-    cout.setf (ios_base::hex, ios_base::basefield);
-
-    cout << "//\n"
-        "// This is an automatically generated file.\n"
-        "// Do not edit.\n"
-        "//\n\n";
-
-    cout << "{\n    ";
-
-    const int iMax = (1 << 16);
-
-    for (int i = 0; i < iMax; i++)
-    {
-    cout << "{0x" << setfill ('0') << setw (8) << halfToFloat (i) << "}, ";
-
-    if (i % 4 == 3)
-    {
-        cout << "\n";
-
-        if (i < iMax - 1)
-        cout << "    ";
-    }
-    }
-
-    cout << "};\n";
-    return 0;
-}
index 9f68576..a0fd31d 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
index eb0a1e4..cd975c3 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //---------------------------------------------------------------------
 
+#include "IexExport.h"
 #include "IexBaseExc.h"
+#include "IexMacros.h"
 
-namespace Iex {
-namespace {
+#ifdef PLATFORM_WINDOWS
+#include <windows.h>
+#endif
 
+#include <stdlib.h>
+
+IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-StackTracer currentStackTracer = 0;
 
+namespace {
+
+StackTracer currentStackTracer = 0;
 
 } // namespace
 
 
-void
+void   
 setStackTracer (StackTracer stackTracer)
 {
     currentStackTracer = stackTracer;
@@ -67,7 +75,7 @@ stackTracer ()
 
 
 BaseExc::BaseExc (const char* s) throw () :
-    std::string (s? s: ""),
+    _message (s? s: ""),
     _stackTrace (currentStackTracer? currentStackTracer(): "")
 {
     // empty
@@ -75,7 +83,7 @@ BaseExc::BaseExc (const char* s) throw () :
 
 
 BaseExc::BaseExc (const std::string &s) throw () :
-    std::string (s),
+    _message (s),
     _stackTrace (currentStackTracer? currentStackTracer(): "")
 {
     // empty
@@ -83,7 +91,7 @@ BaseExc::BaseExc (const std::string &s) throw () :
 
 
 BaseExc::BaseExc (std::stringstream &s) throw () :
-    std::string (s.str()),
+    _message (s.str()),
     _stackTrace (currentStackTracer? currentStackTracer(): "")
 {
     // empty
@@ -91,7 +99,7 @@ BaseExc::BaseExc (std::stringstream &s) throw () :
 
 
 BaseExc::BaseExc (const BaseExc &be) throw () :
-    std::string (be),
+    _message (be._message),
     _stackTrace (be._stackTrace)
 {
     // empty
@@ -107,23 +115,99 @@ BaseExc::~BaseExc () throw ()
 const char *
 BaseExc::what () const throw ()
 {
-    return c_str();
+    return _message.c_str();
 }
 
 
 BaseExc &
 BaseExc::assign (std::stringstream &s)
 {
-    std::string::assign (s.str());
+    _message.assign (s.str());
     return *this;
 }
 
 BaseExc &
 BaseExc::append (std::stringstream &s)
 {
-    std::string::append (s.str());
+    _message.append (s.str());
     return *this;
 }
 
+const std::string &
+BaseExc::message() const
+{
+       return _message;
+}
 
-} // namespace Iex
+BaseExc &
+BaseExc::operator = (std::stringstream &s)
+{
+    return assign (s);
+}
+
+
+BaseExc &
+BaseExc::operator += (std::stringstream &s)
+{
+    return append (s);
+}
+
+
+BaseExc &
+BaseExc::assign (const char *s)
+{
+    _message.assign(s);
+    return *this;
+}
+
+
+BaseExc &
+BaseExc::operator = (const char *s)
+{
+    return assign(s);
+}
+
+
+BaseExc &
+BaseExc::append (const char *s)
+{
+    _message.append(s);
+    return *this;
+}
+
+
+BaseExc &
+BaseExc::operator += (const char *s)
+{
+    return append(s);
+}
+
+
+const std::string &
+BaseExc::stackTrace () const
+{
+    return _stackTrace;
+}
+
+
+IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+
+#ifdef PLATFORM_WINDOWS
+
+#pragma optimize("", off)
+void
+iex_debugTrap()
+{
+    if (0 != getenv("IEXDEBUGTHROW"))
+        ::DebugBreak();
+}
+#else
+void
+iex_debugTrap()
+{
+    // how to in Linux?
+    if (0 != ::getenv("IEXDEBUGTHROW"))
+        __builtin_trap();
+}
+#endif
index 0956e3b..30cb17f 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 ///////////////////////////////////////////////////////////////////////////
 
 
-
 #ifndef INCLUDED_IEXBASEEXC_H
 #define INCLUDED_IEXBASEEXC_H
 
+#include "IexNamespace.h"
+#include "IexExport.h"
 
 //----------------------------------------------------------
 //
 #include <exception>
 #include <sstream>
 
-namespace Iex {
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
-#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
-// Tell MS VC++ to suppress exception specification warnings
-#pragma warning(disable:4290)
-#endif
 
 //-------------------------------
 // Our most basic exception class
 //-------------------------------
 
-class BaseExc: public std::string, public std::exception
+class BaseExc: public std::exception
 {
   public:
 
@@ -68,29 +65,29 @@ class BaseExc: public std::string, public std::exception
     // Constructors and destructor
     //----------------------------
 
-    BaseExc (const char *s = 0) throw();       // std::string (s)
-    BaseExc (const std::string &s) throw();    // std::string (s)
-    BaseExc (std::stringstream &s) throw();    // std::string (s.str())
+    IEX_EXPORT BaseExc (const char *s = 0) throw();     // std::string (s)
+    IEX_EXPORT BaseExc (const std::string &s) throw();  // std::string (s)
+    IEX_EXPORT BaseExc (std::stringstream &s) throw();  // std::string (s.str())
 
-    BaseExc (const BaseExc &be) throw();
-    virtual ~BaseExc () throw ();
+    IEX_EXPORT BaseExc (const BaseExc &be) throw();
+    IEX_EXPORT virtual ~BaseExc () throw ();
 
-    //--------------------------------------------
-    // what() method -- e.what() returns e.c_str()
-    //--------------------------------------------
+    //---------------------------------------------------
+    // what() method -- e.what() returns _message.c_str()
+    //---------------------------------------------------
 
-    virtual const char * what () const throw ();
+    IEX_EXPORT virtual const char * what () const throw ();
 
 
     //--------------------------------------------------
     // Convenient methods to change the exception's text
     //--------------------------------------------------
 
-    BaseExc &          assign (std::stringstream &s);  // assign (s.str())
-    BaseExc &          operator = (std::stringstream &s);
+    IEX_EXPORT BaseExc &            assign (std::stringstream &s);     // assign (s.str())
+    IEX_EXPORT BaseExc &            operator = (std::stringstream &s);
 
-    BaseExc &          append (std::stringstream &s);  // append (s.str())
-    BaseExc &          operator += (std::stringstream &s);
+    IEX_EXPORT BaseExc &            append (std::stringstream &s);     // append (s.str())
+    IEX_EXPORT BaseExc &            operator += (std::stringstream &s);
 
 
     //--------------------------------------------------
@@ -98,12 +95,17 @@ class BaseExc: public std::string, public std::exception
     // the definitions above.
     //--------------------------------------------------
 
-    BaseExc &          assign (const char *s);
-    BaseExc &          operator = (const char *s);
+    IEX_EXPORT BaseExc &            assign (const char *s);
+    IEX_EXPORT BaseExc &            operator = (const char *s);
 
-    BaseExc &          append (const char *s);
-    BaseExc &          operator += (const char *s);
+    IEX_EXPORT BaseExc &            append (const char *s);
+    IEX_EXPORT BaseExc &            operator += (const char *s);
 
+    //---------------------------------------------------
+    // Access to the string representation of the message
+    //---------------------------------------------------
+
+    IEX_EXPORT const std::string &  message () const;
 
     //--------------------------------------------------
     // Stack trace for the point at which the exception
@@ -112,11 +114,12 @@ class BaseExc: public std::string, public std::exception
     // has been installed (see below, setStackTracer()).
     //--------------------------------------------------
 
-    const std::string &        stackTrace () const;
+    IEX_EXPORT const std::string &  stackTrace () const;
 
   private:
 
-    std::string                _stackTrace;
+    std::string                     _message;
+    std::string                     _stackTrace;
 };
 
 
@@ -125,55 +128,59 @@ class BaseExc: public std::string, public std::exception
 // class derived directly or indirectly from BaseExc:
 //-----------------------------------------------------
 
-#define DEFINE_EXC(name, base)                                 \
-    class name: public base                                    \
-    {                                                          \
-      public:                                                   \
-    name (const char* text=0)      throw(): base (text) {}     \
-    name (const std::string &text) throw(): base (text) {}     \
-    name (std::stringstream &text) throw(): base (text) {}     \
+#define DEFINE_EXC_EXP(exp, name, base)                             \
+    class name: public base                                         \
+    {                                                               \
+      public:                                                       \
+        exp name()                         throw(): base (0)    {}  \
+        exp name (const char* text)        throw(): base (text) {}  \
+        exp name (const std::string &text) throw(): base (text) {}  \
+        exp name (std::stringstream &text) throw(): base (text) {}  \
+        exp ~name() throw() { }                                     \
     };
 
+// For backward compatibility.
+#define DEFINE_EXC(name, base) DEFINE_EXC_EXP(, name, base)
+
 
 //--------------------------------------------------------
 // Some exceptions which should be useful in most programs
 //--------------------------------------------------------
+DEFINE_EXC_EXP (IEX_EXPORT, ArgExc, BaseExc)    // Invalid arguments to a function call
 
-DEFINE_EXC (ArgExc,   BaseExc)          // Invalid arguments to a function call
+DEFINE_EXC_EXP (IEX_EXPORT, LogicExc, BaseExc)  // General error in a program's logic,
+                                                // for example, a function was called
+                                                // in a context where the call does
+                                                // not make sense.
 
-DEFINE_EXC (LogicExc, BaseExc)          // General error in a program's logic,
-                 // for example, a function was called
-                 // in a context where the call does
-                 // not make sense.
+DEFINE_EXC_EXP (IEX_EXPORT, InputExc, BaseExc)  // Invalid input data, e.g. from a file
 
-DEFINE_EXC (InputExc, BaseExc)          // Invalid input data, e.g. from a file
+DEFINE_EXC_EXP (IEX_EXPORT, IoExc, BaseExc)     // Input or output operation failed
 
-DEFINE_EXC (IoExc, BaseExc)     // Input or output operation failed
+DEFINE_EXC_EXP (IEX_EXPORT, MathExc, BaseExc)  // Arithmetic exception; more specific
+                                                // exceptions derived from this class
+                                                // are defined in ExcMath.h
 
-DEFINE_EXC (MathExc,  BaseExc)          // Arithmetic exception; more specific
-                 // exceptions derived from this class
-                 // are defined in ExcMath.h
+DEFINE_EXC_EXP (IEX_EXPORT, ErrnoExc, BaseExc)  // Base class for exceptions corresponding
+                                                // to errno values (see errno.h); more
+                                                // specific exceptions derived from this
+                                                // class are defined in ExcErrno.h
 
-DEFINE_EXC (ErrnoExc, BaseExc)          // Base class for exceptions corresponding
-                 // to errno values (see errno.h); more
-                 // specific exceptions derived from this
-                 // class are defined in ExcErrno.h
+DEFINE_EXC_EXP (IEX_EXPORT, NoImplExc, BaseExc) // Missing method exception e.g. from a
+                                                // call to a method that is only partially
+                                                // or not at all implemented. A reminder
+                                                // to lazy software people to get back
+                                                // to work.
 
-DEFINE_EXC (NoImplExc, BaseExc)  // Missing method exception e.g. from a
-                 // call to a method that is only partially
-                 // or not at all implemented. A reminder
-                 // to lazy software people to get back
-                 // to work.
+DEFINE_EXC_EXP (IEX_EXPORT, NullExc, BaseExc)   // A pointer is inappropriately null.
 
-DEFINE_EXC (NullExc, BaseExc)   // A pointer is inappropriately null.
-
-DEFINE_EXC (TypeExc, BaseExc)   // An object is an inappropriate type,
-                 // i.e. a dynamnic_cast failed.
+DEFINE_EXC_EXP (IEX_EXPORT, TypeExc, BaseExc)   // An object is an inappropriate type,
+                                                // i.e. a dynamnic_cast failed.
 
 
 //----------------------------------------------------------------------
 // Stack-tracing support:
-//
+// 
 // setStackTracer(st)
 //
 //     installs a stack-tracing routine, st, which will be called from
@@ -194,73 +201,15 @@ DEFINE_EXC (TypeExc, BaseExc)      // An object is an inappropriate type,
 //
 //     returns a pointer to the current stack-tracing routine, or 0
 //     if there is no current stack stack-tracing routine.
-//
+// 
 //----------------------------------------------------------------------
 
 typedef std::string (* StackTracer) ();
 
-void           setStackTracer (StackTracer stackTracer);
-StackTracer    stackTracer ();
-
-
-//-----------------
-// Inline functions
-//-----------------
-
-inline BaseExc &
-BaseExc::operator = (std::stringstream &s)
-{
-    return assign (s);
-}
-
-
-inline BaseExc &
-BaseExc::operator += (std::stringstream &s)
-{
-    return append (s);
-}
-
-
-inline BaseExc &
-BaseExc::assign (const char *s)
-{
-    std::string::assign(s);
-    return *this;
-}
-
-
-inline BaseExc &
-BaseExc::operator = (const char *s)
-{
-    return assign(s);
-}
-
-
-inline BaseExc &
-BaseExc::append (const char *s)
-{
-    std::string::append(s);
-    return *this;
-}
-
-
-inline BaseExc &
-BaseExc::operator += (const char *s)
-{
-    return append(s);
-}
-
-
-inline const std::string &
-BaseExc::stackTrace () const
-{
-    return _stackTrace;
-}
+IEX_EXPORT void        setStackTracer (StackTracer stackTracer);
+IEX_EXPORT StackTracer stackTracer ();
 
-#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
-#pragma warning(default:4290)
-#endif
 
-} // namespace Iex
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IEXBASEEXC_H
index 7f2ac75..027c7a4 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -45,8 +45,7 @@
 
 #include "IexBaseExc.h"
 
-namespace Iex {
-
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
 DEFINE_EXC (EpermExc, ErrnoExc)
 DEFINE_EXC (EnoentExc, ErrnoExc)
@@ -204,7 +203,6 @@ DEFINE_EXC (EcantextentExc, ErrnoExc)
 DEFINE_EXC (EinvaltimeExc, ErrnoExc)
 DEFINE_EXC (EdestroyedExc, ErrnoExc)
 
-
-} // namespace Iex
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/3rdparty/openexr/Iex/IexExport.h b/3rdparty/openexr/Iex/IexExport.h
new file mode 100644 (file)
index 0000000..270c1cf
--- /dev/null
@@ -0,0 +1,51 @@
+#ifndef IEXEXPORT_H
+#define IEXEXPORT_H
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(IEX_EXPORTS)
+    #define IEX_EXPORT __declspec(dllexport)
+    #else
+    #define IEX_EXPORT __declspec(dllimport)
+    #endif
+    #define IEX_EXPORT_CONST
+#else
+    #define IEX_EXPORT
+    #define IEX_EXPORT_CONST const
+#endif
+
+#endif // #ifndef IEXEXPORT_H
+
diff --git a/3rdparty/openexr/Iex/IexForward.h b/3rdparty/openexr/Iex/IexForward.h
new file mode 100644 (file)
index 0000000..743771c
--- /dev/null
@@ -0,0 +1,229 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IEXFORWARD_H
+#define INCLUDED_IEXFORWARD_H
+
+#include "IexNamespace.h"
+
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Base exceptions.
+//
+
+class BaseExc;
+class ArgExc;
+class LogicExc;
+class InputExc;
+class IoExc;
+class MathExc;
+class ErrnoExc;
+class NoImplExc;
+class NullExc;
+class TypeExc;
+
+//
+// Math exceptions.
+//
+
+class OverflowExc;
+class UnderflowExc;
+class DivzeroExc;
+class InexactExc;
+class InvalidFpOpExc;
+
+//
+// Errno exceptions.
+//
+
+class EpermExc;
+class EnoentExc;
+class EsrchExc;
+class EintrExc;
+class EioExc;
+class EnxioExc;
+class E2bigExc;
+class EnoexecExc;
+class EbadfExc;
+class EchildExc;
+class EagainExc;
+class EnomemExc;
+class EaccesExc;
+class EfaultExc;
+class EnotblkExc;
+class EbusyExc;
+class EexistExc;
+class ExdevExc;
+class EnodevExc;
+class EnotdirExc;
+class EisdirExc;
+class EinvalExc;
+class EnfileExc;
+class EmfileExc;
+class EnottyExc;
+class EtxtbsyExc;
+class EfbigExc;
+class EnospcExc;
+class EspipeExc;
+class ErofsExc;
+class EmlinkExc;
+class EpipeExc;
+class EdomExc;
+class ErangeExc;
+class EnomsgExc;
+class EidrmExc;
+class EchrngExc;
+class El2nsyncExc;
+class El3hltExc;
+class El3rstExc;
+class ElnrngExc;
+class EunatchExc;
+class EnocsiExc;
+class El2hltExc;
+class EdeadlkExc;
+class EnolckExc;
+class EbadeExc;
+class EbadrExc;
+class ExfullExc;
+class EnoanoExc;
+class EbadrqcExc;
+class EbadsltExc;
+class EdeadlockExc;
+class EbfontExc;
+class EnostrExc;
+class EnodataExc;
+class EtimeExc;
+class EnosrExc;
+class EnonetExc;
+class EnopkgExc;
+class EremoteExc;
+class EnolinkExc;
+class EadvExc;
+class EsrmntExc;
+class EcommExc;
+class EprotoExc;
+class EmultihopExc;
+class EbadmsgExc;
+class EnametoolongExc;
+class EoverflowExc;
+class EnotuniqExc;
+class EbadfdExc;
+class EremchgExc;
+class ElibaccExc;
+class ElibbadExc;
+class ElibscnExc;
+class ElibmaxExc;
+class ElibexecExc;
+class EilseqExc;
+class EnosysExc;
+class EloopExc;
+class ErestartExc;
+class EstrpipeExc;
+class EnotemptyExc;
+class EusersExc;
+class EnotsockExc;
+class EdestaddrreqExc;
+class EmsgsizeExc;
+class EprototypeExc;
+class EnoprotooptExc;
+class EprotonosupportExc;
+class EsocktnosupportExc;
+class EopnotsuppExc;
+class EpfnosupportExc;
+class EafnosupportExc;
+class EaddrinuseExc;
+class EaddrnotavailExc;
+class EnetdownExc;
+class EnetunreachExc;
+class EnetresetExc;
+class EconnabortedExc;
+class EconnresetExc;
+class EnobufsExc;
+class EisconnExc;
+class EnotconnExc;
+class EshutdownExc;
+class EtoomanyrefsExc;
+class EtimedoutExc;
+class EconnrefusedExc;
+class EhostdownExc;
+class EhostunreachExc;
+class EalreadyExc;
+class EinprogressExc;
+class EstaleExc;
+class EioresidExc;
+class EucleanExc;
+class EnotnamExc;
+class EnavailExc;
+class EisnamExc;
+class EremoteioExc;
+class EinitExc;
+class EremdevExc;
+class EcanceledExc;
+class EnolimfileExc;
+class EproclimExc;
+class EdisjointExc;
+class EnologinExc;
+class EloginlimExc;
+class EgrouploopExc;
+class EnoattachExc;
+class EnotsupExc;
+class EnoattrExc;
+class EdircorruptedExc;
+class EdquotExc;
+class EnfsremoteExc;
+class EcontrollerExc;
+class EnotcontrollerExc;
+class EenqueuedExc;
+class EnotenqueuedExc;
+class EjoinedExc;
+class EnotjoinedExc;
+class EnoprocExc;
+class EmustrunExc;
+class EnotstoppedExc;
+class EclockcpuExc;
+class EinvalstateExc;
+class EnoexistExc;
+class EendofminorExc;
+class EbufsizeExc;
+class EemptyExc;
+class EnointrgroupExc;
+class EinvalmodeExc;
+class EcantextentExc;
+class EinvaltimeExc;
+class EdestroyedExc;
+
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IEXFORWARD_H
index aee1433..5de57c9 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2018, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 // Example:
 //
 //     THROW (InputExc, "Syntax error in line " << line ", " << file << ".");
-//
+//     
 //----------------------------------------------------------------------------
 
-#define THROW(type, text)      \
-    do                         \
-    {                          \
-    std::stringstream s;       \
-    s << text;         \
-    throw type (s);            \
-    }                          \
+#include "IexExport.h"
+#include "IexForward.h"
+
+IEX_EXPORT void iex_debugTrap();
+
+#define THROW(type, text)                  \
+    do                                     \
+    {                                      \
+        iex_debugTrap();                   \
+        std::stringstream _iex_throw_s;           \
+        _iex_throw_s << text;              \
+        throw type (_iex_throw_s);         \
+    }                                      \
     while (0)
 
 
 //     }
 //----------------------------------------------------------------------------
 
-#define APPEND_EXC(exc, text)  \
-    do                         \
-    {                          \
-    std::stringstream s;       \
-    s << text;         \
-    exc.append (s);            \
-    }                          \
+#define APPEND_EXC(exc, text)               \
+    do                                      \
+    {                                       \
+        std::stringstream _iex_append_s;    \
+        _iex_append_s << text;              \
+        exc.append (_iex_append_s);         \
+    }                                       \
     while (0)
 
-#define REPLACE_EXC(exc, text) \
-    do                         \
-    {                          \
-    std::stringstream s;       \
-    s << text;         \
-    exc.assign (s);            \
-    }                          \
+#define REPLACE_EXC(exc, text)               \
+    do                                       \
+    {                                        \
+        std::stringstream _iex_replace_s;    \
+        _iex_replace_s << text;              \
+        exc.assign (_iex_replace_s);         \
+    }                                        \
     while (0)
 
 
 //
 //-------------------------------------------------------------
 
-#define THROW_ERRNO(text)              \
-    do                                 \
-    {                                  \
-    std::stringstream s;               \
-    s << text;                 \
-    ::Iex::throwErrnoExc (s.str());    \
-    }                                  \
+#define THROW_ERRNO(text)                                          \
+    do                                                             \
+    {                                                              \
+        std::stringstream _iex_throw_errno_s;                      \
+        _iex_throw_errno_s << text;                                \
+        ::IEX_NAMESPACE::throwErrnoExc (_iex_throw_errno_s.str()); \
+    }                                                              \
     while (0)
 
 
 //
 // Example:
 //
-//     ASSERT (ptr != NULL, NullExc, "Null pointer" );
+//     ASSERT (ptr != 0, NullExc, "Null pointer" );
 //
 //-------------------------------------------------------------
 
 #define ASSERT(assertion, type, text)   \
     do                                  \
     {                                   \
-    if ((assertion) == false)       \
-        THROW (type, text);         \
+        if( bool(assertion) == false )      \
+        {                               \
+            THROW( type, text );        \
+        }                               \
     }                                   \
     while (0)
 
+//-------------------------------------------------------------
+// A macro to throw an IEX_NAMESPACE::LogicExc if an assertion is false,
+// with the text composed from the source code file, line number,
+// and assertion argument text.
+//
+// Example:
+//
+//      LOGIC_ASSERT (i < n);
+//
+//-------------------------------------------------------------
+#define LOGIC_ASSERT(assertion)           \
+    ASSERT(assertion,                     \
+           IEX_NAMESPACE::LogicExc,       \
+           __FILE__ << "(" << __LINE__ << "): logical assertion failed: " << #assertion )
 
 #endif
index 5f76ae6..795f500 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -39,7 +39,7 @@
 
 #include "IexBaseExc.h"
 
-namespace Iex {
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //---------------------------------------------------------
 // Exception classess which correspond to specific floating
@@ -52,7 +52,6 @@ DEFINE_EXC (DivzeroExc,     MathExc)  // Division by zero
 DEFINE_EXC (InexactExc,     MathExc)   // Inexact result
 DEFINE_EXC (InvalidFpOpExc, MathExc)   // Invalid operation
 
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Iex
-
-#endif
+#endif // INCLUDED_IEXMATHEXC_H
diff --git a/3rdparty/openexr/Iex/IexNamespace.h b/3rdparty/openexr/Iex/IexNamespace.h
new file mode 100644 (file)
index 0000000..bef1572
--- /dev/null
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IEXNAMESPACE_H
+#define INCLUDED_IEXNAMESPACE_H
+
+//
+// The purpose of this file is to make it possible to specify an
+// IEX_INTERNAL_NAMESPACE as a preprocessor definition and have all of the
+// Iex symbols defined within that namespace rather than the standard
+// Iex namespace.  Those symbols are made available to client code through
+// the IEX_NAMESPACE in addition to the IEX_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the IEX_NAMESPACE defaults to Iex
+// and then "using namespace IEX_INTERNAL_NAMESPACE;" brings all of the
+// declarations from the IEX_INTERNAL_NAMESPACE into the IEX_NAMESPACE.  This
+// means that client code can continue to use syntax like Iex::BaseExc, but
+// at link time it will resolve to a mangled symbol based on the
+// IEX_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of Iex and
+// have it run alongside an older version in the same application, it is now
+// possible to use an internal namespace to prevent collisions between the
+// older versions of Iex symbols and the newer ones.  To do this, the
+// following could be defined at build time:
+//
+// IEX_INTERNAL_NAMESPACE = Iex_v2
+//
+// This means that declarations inside Iex headers look like this (after the
+// preprocessor has done its work):
+//
+// namespace Iex_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace Iex {
+//     using namespace Iex_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the IlmBaseConfig.h file
+// for the configure time options.
+//
+#include "IlmBaseConfig.h"
+
+#ifndef IEX_NAMESPACE
+#define IEX_NAMESPACE Iex
+#endif
+
+#ifndef IEX_INTERNAL_NAMESPACE
+#define IEX_INTERNAL_NAMESPACE IEX_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// IEX_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// IEX_NAMESPACE and pulls the internal symbols into the public namespace.
+//
+
+namespace IEX_INTERNAL_NAMESPACE {}
+namespace IEX_NAMESPACE {
+    using namespace IEX_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define IEX_INTERNAL_NAMESPACE_HEADER_ENTER namespace IEX_INTERNAL_NAMESPACE {
+#define IEX_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define IEX_INTERNAL_NAMESPACE_SOURCE_ENTER namespace IEX_INTERNAL_NAMESPACE {
+#define IEX_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+#endif // INCLUDED_IEXNAMESPACE_H
index 1033659..32e7fb2 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <string.h>
 #include <errno.h>
 
-namespace Iex {
+#ifdef PLATFORM_WINDOWS
+#include <windows.h>
+#endif
+
+IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 void throwErrnoExc (const std::string &text, int errnum)
 {
+#ifdef PLATFORM_WINDOWS
+    if (0 != getenv("IEXDEBUGTHROW"))
+        DebugBreak();
+#endif
+
     const char *entext = strerror (errnum);
     std::string tmp (text);
     std::string::size_type pos;
 
     while (std::string::npos != (pos = tmp.find ("%T")))
-    tmp.replace (pos, 2, entext, strlen (entext));
+       tmp.replace (pos, 2, entext, strlen (entext));
 
     switch (errnum)
     {
       #if defined (EPERM)
-      case EPERM:
-        throw EpermExc (tmp);
+         case EPERM:
+           throw EpermExc (tmp);
       #endif
 
       #if defined (ENOENT)
-      case ENOENT:
-        throw EnoentExc (tmp);
+         case ENOENT:
+           throw EnoentExc (tmp);
       #endif
 
       #if defined (ESRCH)
-      case ESRCH:
-        throw EsrchExc (tmp);
+         case ESRCH:
+           throw EsrchExc (tmp);
       #endif
 
       #if defined (EINTR)
-      case EINTR:
-        throw EintrExc (tmp);
+         case EINTR:
+           throw EintrExc (tmp);
       #endif
 
       #if defined (EIO)
-      case EIO:
-        throw EioExc (tmp);
+         case EIO:
+           throw EioExc (tmp);
       #endif
 
       #if defined (ENXIO)
-      case ENXIO:
-        throw EnxioExc (tmp);
+         case ENXIO:
+           throw EnxioExc (tmp);
       #endif
 
       #if defined (E2BIG)
-      case E2BIG:
-        throw E2bigExc (tmp);
+         case E2BIG:
+           throw E2bigExc (tmp);
       #endif
 
       #if defined (ENOEXEC)
-      case ENOEXEC:
-        throw EnoexecExc (tmp);
+         case ENOEXEC:
+           throw EnoexecExc (tmp);
       #endif
 
       #if defined (EBADF)
-      case EBADF:
-        throw EbadfExc (tmp);
+         case EBADF:
+           throw EbadfExc (tmp);
       #endif
 
       #if defined (ECHILD)
-      case ECHILD:
-        throw EchildExc (tmp);
+         case ECHILD:
+           throw EchildExc (tmp);
       #endif
 
       #if defined (EAGAIN)
-      case EAGAIN:
-        throw EagainExc (tmp);
+         case EAGAIN:
+           throw EagainExc (tmp);
       #endif
 
       #if defined (ENOMEM)
-      case ENOMEM:
-        throw EnomemExc (tmp);
+         case ENOMEM:
+           throw EnomemExc (tmp);
       #endif
 
       #if defined (EACCES)
-      case EACCES:
-        throw EaccesExc (tmp);
+         case EACCES:
+           throw EaccesExc (tmp);
       #endif
 
       #if defined (EFAULT)
-      case EFAULT:
-        throw EfaultExc (tmp);
+         case EFAULT:
+           throw EfaultExc (tmp);
       #endif
 
       #if defined (ENOTBLK)
-      case ENOTBLK:
-        throw EnotblkExc (tmp);
+         case ENOTBLK:
+           throw EnotblkExc (tmp);
       #endif
 
       #if defined (EBUSY)
-      case EBUSY:
-        throw EbusyExc (tmp);
+         case EBUSY:
+           throw EbusyExc (tmp);
       #endif
 
       #if defined (EEXIST)
-      case EEXIST:
-        throw EexistExc (tmp);
+         case EEXIST:
+           throw EexistExc (tmp);
       #endif
 
       #if defined (EXDEV)
-      case EXDEV:
-        throw ExdevExc (tmp);
+         case EXDEV:
+           throw ExdevExc (tmp);
       #endif
 
       #if defined (ENODEV)
-      case ENODEV:
-        throw EnodevExc (tmp);
+         case ENODEV:
+           throw EnodevExc (tmp);
       #endif
 
       #if defined (ENOTDIR)
-      case ENOTDIR:
-        throw EnotdirExc (tmp);
+         case ENOTDIR:
+           throw EnotdirExc (tmp);
       #endif
 
       #if defined (EISDIR)
-      case EISDIR:
-        throw EisdirExc (tmp);
+         case EISDIR:
+           throw EisdirExc (tmp);
       #endif
 
       #if defined (EINVAL)
-      case EINVAL:
-        throw EinvalExc (tmp);
+         case EINVAL:
+           throw EinvalExc (tmp);
       #endif
 
       #if defined (ENFILE)
-      case ENFILE:
-        throw EnfileExc (tmp);
+         case ENFILE:
+           throw EnfileExc (tmp);
       #endif
 
       #if defined (EMFILE)
-      case EMFILE:
-        throw EmfileExc (tmp);
+         case EMFILE:
+           throw EmfileExc (tmp);
       #endif
 
       #if defined (ENOTTY)
-      case ENOTTY:
-        throw EnottyExc (tmp);
+         case ENOTTY:
+           throw EnottyExc (tmp);
       #endif
 
       #if defined (ETXTBSY)
-      case ETXTBSY:
-        throw EtxtbsyExc (tmp);
+         case ETXTBSY:
+           throw EtxtbsyExc (tmp);
       #endif
 
       #if defined (EFBIG)
-      case EFBIG:
-        throw EfbigExc (tmp);
+         case EFBIG:
+           throw EfbigExc (tmp);
       #endif
 
       #if defined (ENOSPC)
-      case ENOSPC:
-        throw EnospcExc (tmp);
+         case ENOSPC:
+           throw EnospcExc (tmp);
       #endif
 
       #if defined (ESPIPE)
-      case ESPIPE:
-        throw EspipeExc (tmp);
+         case ESPIPE:
+           throw EspipeExc (tmp);
       #endif
 
       #if defined (EROFS)
-      case EROFS:
-        throw ErofsExc (tmp);
+         case EROFS:
+           throw ErofsExc (tmp);
       #endif
 
       #if defined (EMLINK)
-      case EMLINK:
-        throw EmlinkExc (tmp);
+         case EMLINK:
+           throw EmlinkExc (tmp);
       #endif
 
       #if defined (EPIPE)
-      case EPIPE:
-        throw EpipeExc (tmp);
+         case EPIPE:
+           throw EpipeExc (tmp);
       #endif
 
       #if defined (EDOM)
-      case EDOM:
-        throw EdomExc (tmp);
+         case EDOM:
+           throw EdomExc (tmp);
       #endif
 
       #if defined (ERANGE)
-      case ERANGE:
-        throw ErangeExc (tmp);
+         case ERANGE:
+           throw ErangeExc (tmp);
       #endif
 
       #if defined (ENOMSG)
-      case ENOMSG:
-        throw EnomsgExc (tmp);
+         case ENOMSG:
+           throw EnomsgExc (tmp);
       #endif
 
       #if defined (EIDRM)
-      case EIDRM:
-        throw EidrmExc (tmp);
+         case EIDRM:
+           throw EidrmExc (tmp);
       #endif
 
       #if defined (ECHRNG)
-      case ECHRNG:
-        throw EchrngExc (tmp);
+         case ECHRNG:
+           throw EchrngExc (tmp);
       #endif
 
       #if defined (EL2NSYNC)
-      case EL2NSYNC:
-        throw El2nsyncExc (tmp);
+         case EL2NSYNC:
+           throw El2nsyncExc (tmp);
       #endif
 
       #if defined (EL3HLT)
-      case EL3HLT:
-        throw El3hltExc (tmp);
+         case EL3HLT:
+           throw El3hltExc (tmp);
       #endif
 
       #if defined (EL3RST)
-      case EL3RST:
-        throw El3rstExc (tmp);
+         case EL3RST:
+           throw El3rstExc (tmp);
       #endif
 
       #if defined (ELNRNG)
-      case ELNRNG:
-        throw ElnrngExc (tmp);
+         case ELNRNG:
+           throw ElnrngExc (tmp);
       #endif
 
       #if defined (EUNATCH)
-      case EUNATCH:
-        throw EunatchExc (tmp);
+         case EUNATCH:
+           throw EunatchExc (tmp);
       #endif
 
       #if defined (ENOSCI)
-      case ENOCSI:
-        throw EnocsiExc (tmp);
+         case ENOCSI:
+           throw EnocsiExc (tmp);
       #endif
 
       #if defined (EL2HLT)
-      case EL2HLT:
-        throw El2hltExc (tmp);
+         case EL2HLT:
+           throw El2hltExc (tmp);
       #endif
 
       #if defined (EDEADLK)
-      case EDEADLK:
-        throw EdeadlkExc (tmp);
+         case EDEADLK:
+           throw EdeadlkExc (tmp);
       #endif
 
       #if defined (ENOLCK)
-      case ENOLCK:
-        throw EnolckExc (tmp);
+         case ENOLCK:
+           throw EnolckExc (tmp);
       #endif
 
       #if defined (EBADE)
-      case EBADE:
-        throw EbadeExc (tmp);
+         case EBADE:
+           throw EbadeExc (tmp);
       #endif
 
       #if defined (EBADR)
-      case EBADR:
-        throw EbadrExc (tmp);
+         case EBADR:
+           throw EbadrExc (tmp);
       #endif
 
       #if defined (EXFULL)
-      case EXFULL:
-        throw ExfullExc (tmp);
+         case EXFULL:
+           throw ExfullExc (tmp);
       #endif
 
       #if defined (ENOANO)
-      case ENOANO:
-        throw EnoanoExc (tmp);
+         case ENOANO:
+           throw EnoanoExc (tmp);
       #endif
 
       #if defined (EBADRQC)
-      case EBADRQC:
-        throw EbadrqcExc (tmp);
+         case EBADRQC:
+           throw EbadrqcExc (tmp);
       #endif
 
       #if defined (EBADSLT)
-      case EBADSLT:
-        throw EbadsltExc (tmp);
+         case EBADSLT:
+           throw EbadsltExc (tmp);
       #endif
 
       #if defined (EDEADLOCK) && defined (EDEADLK)
-      #if EDEADLOCK != EDEADLK
-          case EDEADLOCK:
-        throw EdeadlockExc (tmp);
-      #endif
+         #if EDEADLOCK != EDEADLK
+             case EDEADLOCK:
+               throw EdeadlockExc (tmp);
+         #endif
       #elif defined (EDEADLOCK)
-      case EDEADLOCK:
-        throw EdeadlockExc (tmp);
+         case EDEADLOCK:
+           throw EdeadlockExc (tmp);
       #endif
 
       #if defined (EBFONT)
-      case EBFONT:
-        throw EbfontExc (tmp);
+         case EBFONT:
+           throw EbfontExc (tmp);
       #endif
 
       #if defined (ENOSTR)
-      case ENOSTR:
-        throw EnostrExc (tmp);
+         case ENOSTR:
+           throw EnostrExc (tmp);
       #endif
 
       #if defined (ENODATA)
-      case ENODATA:
-        throw EnodataExc (tmp);
+         case ENODATA:
+           throw EnodataExc (tmp);
       #endif
 
       #if defined (ETIME)
-      case ETIME:
-        throw EtimeExc (tmp);
+         case ETIME:
+           throw EtimeExc (tmp);
       #endif
 
       #if defined (ENOSR)
-      case ENOSR:
-        throw EnosrExc (tmp);
+         case ENOSR:
+           throw EnosrExc (tmp);
       #endif
 
       #if defined (ENONET)
-      case ENONET:
-        throw EnonetExc (tmp);
+         case ENONET:
+           throw EnonetExc (tmp);
       #endif
 
       #if defined (ENOPKG)
-      case ENOPKG:
-        throw EnopkgExc (tmp);
+         case ENOPKG:
+           throw EnopkgExc (tmp);
       #endif
 
       #if defined (EREMOTE)
-      case EREMOTE:
-        throw EremoteExc (tmp);
+         case EREMOTE:
+           throw EremoteExc (tmp);
       #endif
 
       #if defined (ENOLINK)
-      case ENOLINK:
-        throw EnolinkExc (tmp);
+         case ENOLINK:
+           throw EnolinkExc (tmp);
       #endif
 
       #if defined (EADV)
-      case EADV:
-        throw EadvExc (tmp);
+         case EADV:
+           throw EadvExc (tmp);
       #endif
 
       #if defined (ESRMNT)
-      case ESRMNT:
-        throw EsrmntExc (tmp);
+         case ESRMNT:
+           throw EsrmntExc (tmp);
       #endif
 
       #if defined (ECOMM)
-      case ECOMM:
-        throw EcommExc (tmp);
+         case ECOMM:
+           throw EcommExc (tmp);
       #endif
 
       #if defined (EPROTO)
-      case EPROTO:
-        throw EprotoExc (tmp);
+         case EPROTO:
+           throw EprotoExc (tmp);
       #endif
 
       #if defined (EMULTIHOP)
-      case EMULTIHOP:
-        throw EmultihopExc (tmp);
+         case EMULTIHOP:
+           throw EmultihopExc (tmp);
       #endif
 
       #if defined (EBADMSG)
-      case EBADMSG:
-        throw EbadmsgExc (tmp);
+         case EBADMSG:
+           throw EbadmsgExc (tmp);
       #endif
 
       #if defined (ENAMETOOLONG)
-      case ENAMETOOLONG:
-        throw EnametoolongExc (tmp);
+         case ENAMETOOLONG:
+           throw EnametoolongExc (tmp);
       #endif
 
       #if defined (EOVERFLOW)
-      case EOVERFLOW:
-        throw EoverflowExc (tmp);
+         case EOVERFLOW:
+           throw EoverflowExc (tmp);
       #endif
 
       #if defined (ENOTUNIQ)
-      case ENOTUNIQ:
-        throw EnotuniqExc (tmp);
+         case ENOTUNIQ:
+           throw EnotuniqExc (tmp);
       #endif
 
       #if defined (EBADFD)
-      case EBADFD:
-        throw EbadfdExc (tmp);
+         case EBADFD:
+           throw EbadfdExc (tmp);
       #endif
 
       #if defined (EREMCHG)
-      case EREMCHG:
-        throw EremchgExc (tmp);
+         case EREMCHG:
+           throw EremchgExc (tmp);
       #endif
 
       #if defined (ELIBACC)
-      case ELIBACC:
-        throw ElibaccExc (tmp);
+         case ELIBACC:
+           throw ElibaccExc (tmp);
       #endif
 
       #if defined (ELIBBAD)
-      case ELIBBAD:
-        throw ElibbadExc (tmp);
+         case ELIBBAD:
+           throw ElibbadExc (tmp);
       #endif
 
       #if defined (ELIBSCN)
-      case ELIBSCN:
-        throw ElibscnExc (tmp);
+         case ELIBSCN:
+           throw ElibscnExc (tmp);
       #endif
 
       #if defined (ELIBMAX)
-      case ELIBMAX:
-        throw ElibmaxExc (tmp);
+         case ELIBMAX:
+           throw ElibmaxExc (tmp);
       #endif
 
       #if defined (ELIBEXEC)
-      case ELIBEXEC:
-        throw ElibexecExc (tmp);
+         case ELIBEXEC:
+           throw ElibexecExc (tmp);
       #endif
 
       #if defined (EILSEQ)
-      case EILSEQ:
-        throw EilseqExc (tmp);
+         case EILSEQ:
+           throw EilseqExc (tmp);
       #endif
 
       #if defined (ENOSYS)
-      case ENOSYS:
-        throw EnosysExc (tmp);
+         case ENOSYS:
+           throw EnosysExc (tmp);
       #endif
 
       #if defined (ELOOP)
-      case ELOOP:
-        throw EloopExc (tmp);
+         case ELOOP:
+           throw EloopExc (tmp);
       #endif
 
       #if defined (ERESTART)
-      case ERESTART:
-        throw ErestartExc (tmp);
+         case ERESTART:
+           throw ErestartExc (tmp);
       #endif
 
       #if defined (ESTRPIPE)
-      case ESTRPIPE:
-        throw EstrpipeExc (tmp);
+         case ESTRPIPE:
+           throw EstrpipeExc (tmp);
       #endif
 
       #if defined (ENOTEMPTY)
-      case ENOTEMPTY:
-        throw EnotemptyExc (tmp);
+         case ENOTEMPTY:
+           throw EnotemptyExc (tmp);
       #endif
 
       #if defined (EUSERS)
-      case EUSERS:
-        throw EusersExc (tmp);
+         case EUSERS:
+           throw EusersExc (tmp);
       #endif
 
       #if defined (ENOTSOCK)
-      case ENOTSOCK:
-        throw EnotsockExc (tmp);
+         case ENOTSOCK:
+           throw EnotsockExc (tmp);
       #endif
 
       #if defined (EDESTADDRREQ)
-      case EDESTADDRREQ:
-        throw EdestaddrreqExc (tmp);
+         case EDESTADDRREQ:
+           throw EdestaddrreqExc (tmp);
       #endif
 
       #if defined (EMSGSIZE)
-      case EMSGSIZE:
-        throw EmsgsizeExc (tmp);
+         case EMSGSIZE:
+           throw EmsgsizeExc (tmp);
       #endif
 
       #if defined (EPROTOTYPE)
-      case EPROTOTYPE:
-        throw EprototypeExc (tmp);
+         case EPROTOTYPE:
+           throw EprototypeExc (tmp);
       #endif
 
       #if defined (ENOPROTOOPT)
-      case ENOPROTOOPT:
-        throw EnoprotooptExc (tmp);
+         case ENOPROTOOPT:
+           throw EnoprotooptExc (tmp);
       #endif
 
       #if defined (EPROTONOSUPPORT)
-      case EPROTONOSUPPORT:
-        throw EprotonosupportExc (tmp);
+         case EPROTONOSUPPORT:
+           throw EprotonosupportExc (tmp);
       #endif
 
       #if defined (ESOCKTNOSUPPORT)
-      case ESOCKTNOSUPPORT:
-        throw EsocktnosupportExc (tmp);
+         case ESOCKTNOSUPPORT:
+           throw EsocktnosupportExc (tmp);
       #endif
 
       #if defined (EOPNOTSUPP)
-      case EOPNOTSUPP:
-        throw EopnotsuppExc (tmp);
+         case EOPNOTSUPP:
+           throw EopnotsuppExc (tmp);
       #endif
 
       #if defined (EPFNOSUPPORT)
-      case EPFNOSUPPORT:
-        throw EpfnosupportExc (tmp);
+         case EPFNOSUPPORT:
+           throw EpfnosupportExc (tmp);
       #endif
 
       #if defined (EAFNOSUPPORT)
-      case EAFNOSUPPORT:
-        throw EafnosupportExc (tmp);
+         case EAFNOSUPPORT:
+           throw EafnosupportExc (tmp);
       #endif
 
       #if defined (EADDRINUSE)
-      case EADDRINUSE:
-        throw EaddrinuseExc (tmp);
+         case EADDRINUSE:
+           throw EaddrinuseExc (tmp);
       #endif
 
       #if defined (EADDRNOTAVAIL)
-      case EADDRNOTAVAIL:
-        throw EaddrnotavailExc (tmp);
+         case EADDRNOTAVAIL:
+           throw EaddrnotavailExc (tmp);
       #endif
 
       #if defined (ENETDOWN)
-      case ENETDOWN:
-        throw EnetdownExc (tmp);
+         case ENETDOWN:
+           throw EnetdownExc (tmp);
       #endif
 
       #if defined (ENETUNREACH)
-      case ENETUNREACH:
-        throw EnetunreachExc (tmp);
+         case ENETUNREACH:
+           throw EnetunreachExc (tmp);
       #endif
 
       #if defined (ENETRESET)
-      case ENETRESET:
-        throw EnetresetExc (tmp);
+         case ENETRESET:
+           throw EnetresetExc (tmp);
       #endif
 
       #if defined (ECONNABORTED)
-      case ECONNABORTED:
-        throw EconnabortedExc (tmp);
+         case ECONNABORTED:
+           throw EconnabortedExc (tmp);
       #endif
 
       #if defined (ECONNRESET)
-      case ECONNRESET:
-        throw EconnresetExc (tmp);
+         case ECONNRESET:
+           throw EconnresetExc (tmp);
       #endif
 
       #if defined (ENOBUFS)
-      case ENOBUFS:
-        throw EnobufsExc (tmp);
+         case ENOBUFS:
+           throw EnobufsExc (tmp);
       #endif
 
       #if defined (EISCONN)
-      case EISCONN:
-        throw EisconnExc (tmp);
+         case EISCONN:
+           throw EisconnExc (tmp);
       #endif
 
       #if defined (ENOTCONN)
-      case ENOTCONN:
-        throw EnotconnExc (tmp);
+         case ENOTCONN:
+           throw EnotconnExc (tmp);
       #endif
 
       #if defined (ESHUTDOWN)
-      case ESHUTDOWN:
-        throw EshutdownExc (tmp);
+         case ESHUTDOWN:
+           throw EshutdownExc (tmp);
       #endif
 
       #if defined (ETOOMANYREFS)
-      case ETOOMANYREFS:
-        throw EtoomanyrefsExc (tmp);
+         case ETOOMANYREFS:
+           throw EtoomanyrefsExc (tmp);
       #endif
 
       #if defined (ETIMEDOUT)
-      case ETIMEDOUT:
-        throw EtimedoutExc (tmp);
+         case ETIMEDOUT:
+           throw EtimedoutExc (tmp);
       #endif
 
       #if defined (ECONNREFUSED)
-      case ECONNREFUSED:
-        throw EconnrefusedExc (tmp);
+         case ECONNREFUSED:
+           throw EconnrefusedExc (tmp);
       #endif
 
       #if defined (EHOSTDOWN)
-      case EHOSTDOWN:
-        throw EhostdownExc (tmp);
+         case EHOSTDOWN:
+           throw EhostdownExc (tmp);
       #endif
 
       #if defined (EHOSTUNREACH)
-      case EHOSTUNREACH:
-        throw EhostunreachExc (tmp);
+         case EHOSTUNREACH:
+           throw EhostunreachExc (tmp);
       #endif
 
       #if defined (EALREADY)
-      case EALREADY:
-        throw EalreadyExc (tmp);
+         case EALREADY:
+           throw EalreadyExc (tmp);
       #endif
 
       #if defined (EINPROGRESS)
-      case EINPROGRESS:
-        throw EinprogressExc (tmp);
+         case EINPROGRESS:
+           throw EinprogressExc (tmp);
       #endif
 
       #if defined (ESTALE)
-      case ESTALE:
-        throw EstaleExc (tmp);
+         case ESTALE:
+           throw EstaleExc (tmp);
       #endif
 
       #if defined (EIORESID)
-      case EIORESID:
-        throw EioresidExc (tmp);
+         case EIORESID:
+           throw EioresidExc (tmp);
       #endif
 
       #if defined (EUCLEAN)
-      case EUCLEAN:
-        throw EucleanExc (tmp);
+         case EUCLEAN:
+           throw EucleanExc (tmp);
       #endif
 
       #if defined (ENOTNAM)
-      case ENOTNAM:
-        throw EnotnamExc (tmp);
+         case ENOTNAM:
+           throw EnotnamExc (tmp);
       #endif
 
       #if defined (ENAVAIL)
-      case ENAVAIL:
-        throw EnavailExc (tmp);
+         case ENAVAIL:
+           throw EnavailExc (tmp);
       #endif
 
       #if defined (EISNAM)
-      case EISNAM:
-        throw EisnamExc (tmp);
+         case EISNAM:
+           throw EisnamExc (tmp);
       #endif
 
       #if defined (EREMOTEIO)
-      case EREMOTEIO:
-        throw EremoteioExc (tmp);
+         case EREMOTEIO:
+           throw EremoteioExc (tmp);
       #endif
 
       #if defined (EINIT)
-      case EINIT:
-        throw EinitExc (tmp);
+         case EINIT:
+           throw EinitExc (tmp);
       #endif
 
       #if defined (EREMDEV)
-      case EREMDEV:
-        throw EremdevExc (tmp);
+         case EREMDEV:
+           throw EremdevExc (tmp);
       #endif
 
       #if defined (ECANCELED)
-      case ECANCELED:
-        throw EcanceledExc (tmp);
+         case ECANCELED:
+           throw EcanceledExc (tmp);
       #endif
 
       #if defined (ENOLIMFILE)
-      case ENOLIMFILE:
-        throw EnolimfileExc (tmp);
+         case ENOLIMFILE:
+           throw EnolimfileExc (tmp);
       #endif
 
       #if defined (EPROCLIM)
-      case EPROCLIM:
-        throw EproclimExc (tmp);
+         case EPROCLIM:
+           throw EproclimExc (tmp);
       #endif
 
       #if defined (EDISJOINT)
-      case EDISJOINT:
-        throw EdisjointExc (tmp);
+         case EDISJOINT:
+           throw EdisjointExc (tmp);
       #endif
 
       #if defined (ENOLOGIN)
-      case ENOLOGIN:
-        throw EnologinExc (tmp);
+         case ENOLOGIN:
+           throw EnologinExc (tmp);
       #endif
 
       #if defined (ELOGINLIM)
-      case ELOGINLIM:
-        throw EloginlimExc (tmp);
+         case ELOGINLIM:
+           throw EloginlimExc (tmp);
       #endif
 
       #if defined (EGROUPLOOP)
-      case EGROUPLOOP:
-        throw EgrouploopExc (tmp);
+         case EGROUPLOOP:
+           throw EgrouploopExc (tmp);
       #endif
 
       #if defined (ENOATTACH)
-      case ENOATTACH:
-        throw EnoattachExc (tmp);
+         case ENOATTACH:
+           throw EnoattachExc (tmp);
       #endif
 
       #if defined (ENOTSUP) && defined (EOPNOTSUPP)
-      #if ENOTSUP != EOPNOTSUPP
-          case ENOTSUP:
-        throw EnotsupExc (tmp);
-      #endif
+         #if ENOTSUP != EOPNOTSUPP
+             case ENOTSUP:
+               throw EnotsupExc (tmp);
+         #endif
       #elif defined (ENOTSUP)
-      case ENOTSUP:
-        throw EnotsupExc (tmp);
+         case ENOTSUP:
+           throw EnotsupExc (tmp);
       #endif
 
       #if defined (ENOATTR)
-      case ENOATTR:
-        throw EnoattrExc (tmp);
+         case ENOATTR:
+           throw EnoattrExc (tmp);
       #endif
 
       #if defined (EDIRCORRUPTED)
-      case EDIRCORRUPTED:
-        throw EdircorruptedExc (tmp);
+         case EDIRCORRUPTED:
+           throw EdircorruptedExc (tmp);
       #endif
 
       #if defined (EDQUOT)
-      case EDQUOT:
-        throw EdquotExc (tmp);
+         case EDQUOT:
+           throw EdquotExc (tmp);
       #endif
 
       #if defined (ENFSREMOTE)
-      case ENFSREMOTE:
-        throw EnfsremoteExc (tmp);
+         case ENFSREMOTE:
+           throw EnfsremoteExc (tmp);
       #endif
 
       #if defined (ECONTROLLER)
-      case ECONTROLLER:
-        throw EcontrollerExc (tmp);
+         case ECONTROLLER:
+           throw EcontrollerExc (tmp);
       #endif
 
       #if defined (ENOTCONTROLLER)
-      case ENOTCONTROLLER:
-        throw EnotcontrollerExc (tmp);
+         case ENOTCONTROLLER:
+           throw EnotcontrollerExc (tmp);
       #endif
 
       #if defined (EENQUEUED)
-      case EENQUEUED:
-        throw EenqueuedExc (tmp);
+         case EENQUEUED:
+           throw EenqueuedExc (tmp);
       #endif
 
       #if defined (ENOTENQUEUED)
-      case ENOTENQUEUED:
-        throw EnotenqueuedExc (tmp);
+         case ENOTENQUEUED:
+           throw EnotenqueuedExc (tmp);
       #endif
 
       #if defined (EJOINED)
-      case EJOINED:
-        throw EjoinedExc (tmp);
+         case EJOINED:
+           throw EjoinedExc (tmp);
       #endif
 
       #if defined (ENOTJOINED)
-      case ENOTJOINED:
-        throw EnotjoinedExc (tmp);
+         case ENOTJOINED:
+           throw EnotjoinedExc (tmp);
       #endif
 
       #if defined (ENOPROC)
-      case ENOPROC:
-        throw EnoprocExc (tmp);
+         case ENOPROC:
+           throw EnoprocExc (tmp);
       #endif
 
       #if defined (EMUSTRUN)
-      case EMUSTRUN:
-        throw EmustrunExc (tmp);
+         case EMUSTRUN:
+           throw EmustrunExc (tmp);
       #endif
 
       #if defined (ENOTSTOPPED)
-      case ENOTSTOPPED:
-        throw EnotstoppedExc (tmp);
+         case ENOTSTOPPED:
+           throw EnotstoppedExc (tmp);
       #endif
 
       #if defined (ECLOCKCPU)
-      case ECLOCKCPU:
-        throw EclockcpuExc (tmp);
+         case ECLOCKCPU:
+           throw EclockcpuExc (tmp);
       #endif
 
       #if defined (EINVALSTATE)
-      case EINVALSTATE:
-        throw EinvalstateExc (tmp);
+         case EINVALSTATE:
+           throw EinvalstateExc (tmp);
       #endif
 
       #if defined (ENOEXIST)
-      case ENOEXIST:
-        throw EnoexistExc (tmp);
+         case ENOEXIST:
+           throw EnoexistExc (tmp);
       #endif
 
       #if defined (EENDOFMINOR)
-      case EENDOFMINOR:
-        throw EendofminorExc (tmp);
+         case EENDOFMINOR:
+           throw EendofminorExc (tmp);
       #endif
 
       #if defined (EBUFSIZE)
-      case EBUFSIZE:
-        throw EbufsizeExc (tmp);
+         case EBUFSIZE:
+           throw EbufsizeExc (tmp);
       #endif
 
       #if defined (EEMPTY)
-      case EEMPTY:
-        throw EemptyExc (tmp);
+         case EEMPTY:
+           throw EemptyExc (tmp);
       #endif
 
       #if defined (ENOINTRGROUP)
-      case ENOINTRGROUP:
-        throw EnointrgroupExc (tmp);
+         case ENOINTRGROUP:
+           throw EnointrgroupExc (tmp);
       #endif
 
       #if defined (EINVALMODE)
-      case EINVALMODE:
-        throw EinvalmodeExc (tmp);
+         case EINVALMODE:
+           throw EinvalmodeExc (tmp);
       #endif
 
       #if defined (ECANTEXTENT)
-      case ECANTEXTENT:
-        throw EcantextentExc (tmp);
+         case ECANTEXTENT:
+           throw EcantextentExc (tmp);
       #endif
 
       #if defined (EINVALTIME)
-      case EINVALTIME:
-        throw EinvaltimeExc (tmp);
+         case EINVALTIME:
+           throw EinvaltimeExc (tmp);
       #endif
 
       #if defined (EDESTROYED)
-      case EDESTROYED:
-        throw EdestroyedExc (tmp);
+         case EDESTROYED:
+           throw EdestroyedExc (tmp);
       #endif
     }
 
@@ -855,5 +864,10 @@ void throwErrnoExc (const std::string &text)
     throwErrnoExc (text, errno);
 }
 
+void throwErrnoExc()
+{
+    std::string txt = "%T.";
+    throwErrnoExc (txt);
+}
 
-} // namespace Iex
+IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
index 2c718ac..224ed2b 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -44,8 +44,9 @@
 //----------------------------------------------------------
 
 #include "IexBaseExc.h"
+#include "IexExport.h"
 
-namespace Iex {
+IEX_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //--------------------------------------------------------------------------
@@ -56,7 +57,7 @@ namespace Iex {
 // "%T" have been replaced with the output of strerror(oserror()).
 //
 // Example:
-//
+//   
 // If opening file /tmp/output failed with an ENOENT error code,
 // calling
 //
@@ -87,10 +88,10 @@ namespace Iex {
 //
 //--------------------------------------------------------------------------
 
-void throwErrnoExc (const std::string &txt, int errnum);
-void throwErrnoExc (const std::string &txt = "%T." /*, int errnum = oserror() */);
-
+IEX_EXPORT void throwErrnoExc(const std::string &txt, int errnum);
+IEX_EXPORT void throwErrnoExc(const std::string &txt);
+IEX_EXPORT void throwErrnoExc();
 
-} // namespace Iex
+IEX_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IEXTHROWERRNOEXC_H
index ebbd539..b1f94db 100644 (file)
@@ -1,3 +1,15 @@
+#cmakedefine PLATFORM_WINDOWS
+
+//
+// Define and set to 1 if the target system has c++11/14 support
+// and you want IlmBase to NOT use it's features
+//
+
+#cmakedefine01 ILMBASE_FORCE_CXX03
+#if ILMBASE_FORCE_CXX03 == 0
+#undef ILMBASE_FORCE_CXX03
+#endif
+
 //
 // Define and set to 1 if the target system has POSIX thread support
 // and you want IlmBase to use it for multithreaded file I/O.
 
 #cmakedefine01 HAVE_POSIX_SEMAPHORES
 
-#undef HAVE_UCONTEXT_H
+
+#cmakedefine HAVE_UCONTEXT_H
+
+
+//
+// Dealing with FPEs
+//
+#cmakedefine01 ILMBASE_HAVE_CONTROL_REGISTER_SUPPORT
+
+
+//
+// Define and set to 1 if the target system has support for large
+// stack sizes.
+//
+
+#cmakedefine ILMBASE_HAVE_LARGE_STACK
+
+//
+// Current (internal) library namepace name and corresponding public
+// client namespaces.
+//
+#define ILMBASE_INTERNAL_NAMESPACE_CUSTOM @ILMBASE_INTERNAL_NAMESPACE_CUSTOM@
+#define IMATH_INTERNAL_NAMESPACE @IMATH_INTERNAL_NAMESPACE@
+#define IEX_INTERNAL_NAMESPACE @IEX_INTERNAL_NAMESPACE@
+#define ILMTHREAD_INTERNAL_NAMESPACE @ILMTHREAD_INTERNAL_NAMESPACE@
+
+#define ILMBASE_NAMESPACE_CUSTOM @ILMBASE_NAMESPACE_CUSTOM@
+#define IMATH_NAMESPACE @IMATH_NAMESPACE@
+#define IEX_NAMESPACE @IEX_NAMESPACE@
+#define ILMTHREAD_NAMESPACE @ILMTHREAD_NAMESPACE@
+
 
 //
 // Define and set to 1 if the target system has support for large
 // stack sizes.
 //
 
-#undef ILMBASE_HAVE_LARGE_STACK
+#cmakedefine ILMBASE_HAVE_LARGE_STACK
 
 
 //
-// Version string for runtime access
+// Version information
 //
-#define ILMBASE_VERSION_STRING "1.0.3"
-#define ILMBASE_PACKAGE_STRING "IlmBase 1.0.3"
+#define ILMBASE_VERSION_STRING @ILMBASE_VERSION_STRING@
+#define ILMBASE_PACKAGE_STRING @ILMBASE_PACKAGE_STRING@
+
+#define ILMBASE_VERSION_MAJOR @ILMBASE_VERSION_MAJOR@
+#define ILMBASE_VERSION_MINOR @ILMBASE_VERSION_MINOR@
+#define ILMBASE_VERSION_PATCH @ILMBASE_VERSION_PATCH@
+
+// Version as a single hex number, e.g. 0x01000300 == 1.0.3
+#define ILMBASE_VERSION_HEX ((ILMBASE_VERSION_MAJOR << 24) | \
+                             (ILMBASE_VERSION_MINOR << 16) | \
+                             (ILMBASE_VERSION_PATCH <<  8))
+
+
index 9418b9d..8f33fb0 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2007, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 //
 //     ACES image file I/O.
-//
+//     
 //-----------------------------------------------------------------------------
 
 #include <ImfAcesFile.h>
 #include <ImfRgbaFile.h>
 #include <ImfStandardAttributes.h>
 #include <Iex.h>
-#include <algorithm> // for std::max()
+#include <algorithm>
 
 using namespace std;
-using namespace Imath;
-using namespace Iex;
+using namespace IMATH_NAMESPACE;
+using namespace IEX_NAMESPACE;
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 const Chromaticities &
 acesChromaticities ()
 {
-    static const Chromaticities acesChr
-        (V2f (0.73470,  0.26530),      // red
-         V2f (0.00000,  1.00000),      // green
-         V2f (0.00010, -0.07700),      // blue
-         V2f (0.32168,  0.33767));     // white
+    static const Chromaticities acesChr 
+           (V2f (0.73470,  0.26530),   // red
+            V2f (0.00000,  1.00000),   // green
+            V2f (0.00010, -0.07700),   // blue
+            V2f (0.32168,  0.33767));  // white
 
     return acesChr;
 }
@@ -102,10 +103,10 @@ checkCompression (Compression compression)
       case NO_COMPRESSION:
       case PIZ_COMPRESSION:
       case B44A_COMPRESSION:
-    break;
+       break;
 
       default:
-    throw ArgExc ("Invalid compression type for ACES file.");
+       throw ArgExc ("Invalid compression type for ACES file.");
     }
 }
 
@@ -127,16 +128,16 @@ AcesOutputFile::AcesOutputFile
     addAdoptedNeutral (newHeader, acesChromaticities().white);
 
     _data->rgbaFile = new RgbaOutputFile (name.c_str(),
-                      newHeader,
-                      rgbaChannels,
-                      numThreads);
+                                         newHeader,
+                                         rgbaChannels,
+                                         numThreads);
 
     _data->rgbaFile->setYCRounding (7, 6);
 }
 
 
 AcesOutputFile::AcesOutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      RgbaChannels rgbaChannels,
      int numThreads)
@@ -150,9 +151,9 @@ AcesOutputFile::AcesOutputFile
     addAdoptedNeutral (newHeader, acesChromaticities().white);
 
     _data->rgbaFile = new RgbaOutputFile (os,
-                      header,
-                      rgbaChannels,
-                      numThreads);
+                                         header,
+                                         rgbaChannels,
+                                         numThreads);
 
     _data->rgbaFile->setYCRounding (7, 6);
 }
@@ -160,11 +161,11 @@ AcesOutputFile::AcesOutputFile
 
 AcesOutputFile::AcesOutputFile
     (const std::string &name,
-     const Imath::Box2i &displayWindow,
-     const Imath::Box2i &dataWindow,
+     const IMATH_NAMESPACE::Box2i &displayWindow,
+     const IMATH_NAMESPACE::Box2i &dataWindow,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -175,20 +176,20 @@ AcesOutputFile::AcesOutputFile
     checkCompression (compression);
 
     Header newHeader (displayWindow,
-              dataWindow.isEmpty()? displayWindow: dataWindow,
-              pixelAspectRatio,
-              screenWindowCenter,
-              screenWindowWidth,
-              lineOrder,
-              compression);
+                     dataWindow.isEmpty()? displayWindow: dataWindow,
+                     pixelAspectRatio,
+                     screenWindowCenter,
+                     screenWindowWidth,
+                     lineOrder,
+                     compression);
 
     addChromaticities (newHeader, acesChromaticities());
     addAdoptedNeutral (newHeader, acesChromaticities().white);
 
     _data->rgbaFile = new RgbaOutputFile (name.c_str(),
-                      newHeader,
-                      rgbaChannels,
-                      numThreads);
+                                         newHeader,
+                                         rgbaChannels,
+                                         numThreads);
 
     _data->rgbaFile->setYCRounding (7, 6);
 }
@@ -200,7 +201,7 @@ AcesOutputFile::AcesOutputFile
      int height,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -211,20 +212,20 @@ AcesOutputFile::AcesOutputFile
     checkCompression (compression);
 
     Header newHeader (width,
-              height,
-              pixelAspectRatio,
-              screenWindowCenter,
-              screenWindowWidth,
-              lineOrder,
-              compression);
+                     height,
+                     pixelAspectRatio,
+                     screenWindowCenter,
+                     screenWindowWidth,
+                     lineOrder,
+                     compression);
 
     addChromaticities (newHeader, acesChromaticities());
     addAdoptedNeutral (newHeader, acesChromaticities().white);
 
     _data->rgbaFile = new RgbaOutputFile (name.c_str(),
-                      newHeader,
-                      rgbaChannels,
-                      numThreads);
+                                         newHeader,
+                                         rgbaChannels,
+                                         numThreads);
 
     _data->rgbaFile->setYCRounding (7, 6);
 }
@@ -236,7 +237,7 @@ AcesOutputFile::~AcesOutputFile ()
 }
 
 
-void
+void           
 AcesOutputFile::setFrameBuffer
     (const Rgba *base,
      size_t xStride,
@@ -246,14 +247,14 @@ AcesOutputFile::setFrameBuffer
 }
 
 
-void
+void           
 AcesOutputFile::writePixels (int numScanLines)
 {
     _data->rgbaFile->writePixels (numScanLines);
 }
 
 
-int
+int                    
 AcesOutputFile::currentScanLine () const
 {
     return _data->rgbaFile->currentScanLine();
@@ -267,49 +268,49 @@ AcesOutputFile::header () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesOutputFile::displayWindow () const
 {
     return _data->rgbaFile->displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesOutputFile::dataWindow () const
 {
     return _data->rgbaFile->dataWindow();
 }
 
 
-float
+float          
 AcesOutputFile::pixelAspectRatio () const
 {
     return _data->rgbaFile->pixelAspectRatio();
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 AcesOutputFile::screenWindowCenter () const
 {
     return _data->rgbaFile->screenWindowCenter();
 }
 
 
-float
+float          
 AcesOutputFile::screenWindowWidth () const
 {
     return _data->rgbaFile->screenWindowWidth();
 }
 
 
-LineOrder
+LineOrder              
 AcesOutputFile::lineOrder () const
 {
     return _data->rgbaFile->lineOrder();
 }
 
 
-Compression
+Compression            
 AcesOutputFile::compression () const
 {
     return _data->rgbaFile->compression();
@@ -323,7 +324,7 @@ AcesOutputFile::channels () const
 }
 
 
-void
+void           
 AcesOutputFile::updatePreviewImage (const PreviewRgba pixels[])
 {
     _data->rgbaFile->updatePreviewImage (pixels);
@@ -379,28 +380,28 @@ AcesInputFile::Data::initColorConversion ()
     Chromaticities fileChr;
 
     if (hasChromaticities (header))
-    fileChr = chromaticities (header);
+       fileChr = chromaticities (header);
 
     V2f fileNeutral = fileChr.white;
 
     if (hasAdoptedNeutral (header))
-    fileNeutral = adoptedNeutral (header);
+       fileNeutral = adoptedNeutral (header);
 
     const Chromaticities acesChr = acesChromaticities();
 
     V2f acesNeutral = acesChr.white;
 
     if (fileChr.red == acesChr.red &&
-    fileChr.green == acesChr.green &&
-    fileChr.blue == acesChr.blue &&
-    fileChr.white == acesChr.white &&
-    fileNeutral == acesNeutral)
+       fileChr.green == acesChr.green &&
+       fileChr.blue == acesChr.blue &&
+       fileChr.white == acesChr.white &&
+       fileNeutral == acesNeutral)
     {
-    //
-    // The file already contains ACES data,
-    // color conversion is not necessary.
+       //
+       // The file already contains ACES data,
+       // color conversion is not necessary.
 
-    return;
+       return;
     }
 
     mustConvertColor = true;
@@ -419,16 +420,16 @@ AcesInputFile::Data::initColorConversion ()
     //
 
     static const M44f bradfordCPM
-        (0.895100, -0.750200,  0.038900,  0.000000,
-         0.266400,  1.713500, -0.068500,  0.000000,
-        -0.161400,  0.036700,  1.029600,  0.000000,
-         0.000000,  0.000000,  0.000000,  1.000000);
+           (0.895100, -0.750200,  0.038900,  0.000000,
+            0.266400,  1.713500, -0.068500,  0.000000,
+           -0.161400,  0.036700,  1.029600,  0.000000,
+            0.000000,  0.000000,  0.000000,  1.000000);
 
     const static M44f inverseBradfordCPM
-        (0.986993,  0.432305, -0.008529,  0.000000,
-        -0.147054,  0.518360,  0.040043,  0.000000,
-         0.159963,  0.049291,  0.968487,  0.000000,
-         0.000000,  0.000000,  0.000000,  1.000000);
+           (0.986993,  0.432305, -0.008529,  0.000000,
+           -0.147054,  0.518360,  0.040043,  0.000000,
+            0.159963,  0.049291,  0.968487,  0.000000,
+            0.000000,  0.000000,  0.000000,  1.000000);
 
     //
     // Convert the white points of the two RGB spaces to XYZ
@@ -447,16 +448,16 @@ AcesInputFile::Data::initColorConversion ()
     //
 
     V3f ratio ((acesNeutralXYZ * bradfordCPM) /
-           (fileNeutralXYZ * bradfordCPM));
+              (fileNeutralXYZ * bradfordCPM));
 
     M44f ratioMat (ratio[0], 0,        0,        0,
-           0,        ratio[1], 0,        0,
-           0,        0,        ratio[2], 0,
-           0,        0,        0,        1);
+                  0,        ratio[1], 0,        0,
+                  0,        0,        ratio[2], 0,
+                  0,        0,        0,        1);
 
     M44f bradfordTrans = bradfordCPM *
                          ratioMat *
-             inverseBradfordCPM;
+                        inverseBradfordCPM;
 
     //
     // Build a combined file-RGB-to-ACES-RGB conversion matrix
@@ -488,7 +489,7 @@ AcesInputFile::~AcesInputFile ()
 }
 
 
-void
+void           
 AcesInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
 {
     _data->rgbaFile->setFrameBuffer (base, xStride, yStride);
@@ -498,7 +499,7 @@ AcesInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
 }
 
 
-void
+void           
 AcesInputFile::readPixels (int scanLine1, int scanLine2)
 {
     //
@@ -514,32 +515,32 @@ AcesInputFile::readPixels (int scanLine1, int scanLine2)
     //
 
     if (!_data->mustConvertColor)
-    return;
+       return;
 
     int minY = min (scanLine1, scanLine2);
     int maxY = max (scanLine1, scanLine2);
 
     for (int y = minY; y <= maxY; ++y)
     {
-    Rgba *base = _data->fbBase +
-             _data->fbXStride * _data->minX +
-             _data->fbYStride * y;
+       Rgba *base = _data->fbBase +
+                    _data->fbXStride * _data->minX +
+                    _data->fbYStride * y;
 
-    for (int x = _data->minX; x <= _data->maxX; ++x)
-    {
-        V3f aces = V3f (base->r, base->g, base->b) * _data->fileToAces;
+       for (int x = _data->minX; x <= _data->maxX; ++x)
+       {
+           V3f aces = V3f (base->r, base->g, base->b) * _data->fileToAces;
 
-        base->r = aces[0];
-        base->g = aces[1];
-        base->b = aces[2];
+           base->r = aces[0];
+           base->g = aces[1];
+           base->b = aces[2];
 
-        base += _data->fbXStride;
-    }
+           base += _data->fbXStride;
+       }
     }
 }
 
 
-void
+void           
 AcesInputFile::readPixels (int scanLine)
 {
     readPixels (scanLine, scanLine);
@@ -553,14 +554,14 @@ AcesInputFile::header () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesInputFile::displayWindow () const
 {
     return _data->rgbaFile->displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 AcesInputFile::dataWindow () const
 {
     return _data->rgbaFile->dataWindow();
@@ -574,7 +575,7 @@ AcesInputFile::pixelAspectRatio () const
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 AcesInputFile::screenWindowCenter () const
 {
     return _data->rgbaFile->screenWindowCenter();
@@ -609,7 +610,7 @@ AcesInputFile::channels () const
 }
 
 
-const char *
+const char *  
 AcesInputFile::fileName () const
 {
     return _data->rgbaFile->fileName();
@@ -629,4 +630,4 @@ AcesInputFile::version () const
     return _data->rgbaFile->version();
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 36f9522..f8e9323 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2007, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 //
 //     ACES image file I/O.
-//
+//     
 //     This header file declares two classes that directly support
 //     image file input and output according to the Academy Image
 //     Interchange Framework.
-//
+//     
 //     The Academy Image Interchange file format is a subset of OpenEXR:
-//
+//     
 //         - Images are stored as scanlines.  Tiles are not allowed.
-//
+//     
 //         - Images contain three color channels, either
 //                 R, G, B (red, green, blue) or
 //                 Y, RY, BY (luminance, sub-sampled chroma)
-//
+//     
 //         - Images may optionally contain an alpha channel.
-//
+//     
 //         - Only three compression types are allowed:
 //                 - NO_COMPRESSION (file is not compressed)
 //                 - PIZ_COMPRESSION (lossless)
 //                 - B44A_COMPRESSION (lossy)
-//
+//     
 //         - The "chromaticities" header attribute must specify
 //           the ACES RGB primaries and white point.
-//
+//     
 //     class AcesOutputFile writes an OpenEXR file, enforcing the
 //     restrictions listed above.  Pixel data supplied by application
 //     software must already be in the ACES RGB space.
-//
+//     
 //     class AcesInputFile reads an OpenEXR file.  Pixel data delivered
 //     to application software is guaranteed to be in the ACES RGB space.
 //     If the RGB space of the file is not the same as the ACES space,
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfRgba.h>
+#include "ImfHeader.h"
+#include "ImfRgba.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
-#include <ImfThreading.h>
-#include <string>
+#include "ImfThreading.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-namespace Imf {
+#include <string>
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class RgbaOutputFile;
-class RgbaInputFile;
-struct PreviewRgba;
-struct Chromaticities;
 
 //
 // ACES red, green, blue and white-point chromaticities.
@@ -111,9 +110,10 @@ class AcesOutputFile
     // Constructor -- header is constructed by the caller
     //---------------------------------------------------
 
+    IMF_EXPORT
     AcesOutputFile (const std::string &name,
-            const Header &header,
-            RgbaChannels rgbaChannels = WRITE_RGBA,
+                   const Header &header,
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
                     int numThreads = globalThreadCount());
 
 
@@ -123,9 +123,10 @@ class AcesOutputFile
     // automatically close the file.
     //----------------------------------------------------
 
-    AcesOutputFile (OStream &os,
-            const Header &header,
-            RgbaChannels rgbaChannels = WRITE_RGBA,
+    IMF_EXPORT
+    AcesOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                   const Header &header,
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
                     int numThreads = globalThreadCount());
 
 
@@ -134,15 +135,16 @@ class AcesOutputFile
     // call arguments (empty dataWindow means "same as displayWindow")
     //----------------------------------------------------------------
 
+    IMF_EXPORT
     AcesOutputFile (const std::string &name,
-            const Imath::Box2i &displayWindow,
-            const Imath::Box2i &dataWindow = Imath::Box2i(),
-            RgbaChannels rgbaChannels = WRITE_RGBA,
-            float pixelAspectRatio = 1,
-            const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
-            float screenWindowWidth = 1,
-            LineOrder lineOrder = INCREASING_Y,
-            Compression compression = PIZ_COMPRESSION,
+                   const IMATH_NAMESPACE::Box2i &displayWindow,
+                   const IMATH_NAMESPACE::Box2i &dataWindow = IMATH_NAMESPACE::Box2i(),
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
+                   float pixelAspectRatio = 1,
+                   const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
+                   float screenWindowWidth = 1,
+                   LineOrder lineOrder = INCREASING_Y,
+                   Compression compression = PIZ_COMPRESSION,
                     int numThreads = globalThreadCount());
 
 
@@ -152,15 +154,16 @@ class AcesOutputFile
     // Box2i (V2i (0, 0), V2i (width - 1, height -1))
     //-----------------------------------------------
 
+    IMF_EXPORT
     AcesOutputFile (const std::string &name,
-            int width,
-            int height,
-            RgbaChannels rgbaChannels = WRITE_RGBA,
-            float pixelAspectRatio = 1,
-            const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
-            float screenWindowWidth = 1,
-            LineOrder lineOrder = INCREASING_Y,
-            Compression compression = PIZ_COMPRESSION,
+                   int width,
+                   int height,
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
+                   float pixelAspectRatio = 1,
+                   const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
+                   float screenWindowWidth = 1,
+                   LineOrder lineOrder = INCREASING_Y,
+                   Compression compression = PIZ_COMPRESSION,
                     int numThreads = globalThreadCount());
 
 
@@ -168,6 +171,7 @@ class AcesOutputFile
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~AcesOutputFile ();
 
 
@@ -179,9 +183,10 @@ class AcesOutputFile
     //
     //------------------------------------------------
 
+    IMF_EXPORT
     void                       setFrameBuffer (const Rgba *base,
-                        size_t xStride,
-                        size_t yStride);
+                                               size_t xStride,
+                                               size_t yStride);
 
 
     //-------------------------------------------------
@@ -197,14 +202,23 @@ class AcesOutputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &             header () const;
-    const Imath::Box2i &       displayWindow () const;
-    const Imath::Box2i &       dataWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     displayWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     dataWindow () const;
+    IMF_EXPORT
     float                      pixelAspectRatio () const;
-    const Imath::V2f           screenWindowCenter () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::V2f         screenWindowCenter () const;
+    IMF_EXPORT
     float                      screenWindowWidth () const;
+    IMF_EXPORT
     LineOrder                  lineOrder () const;
+    IMF_EXPORT
     Compression                        compression () const;
+    IMF_EXPORT
     RgbaChannels               channels () const;
 
 
@@ -212,6 +226,7 @@ class AcesOutputFile
     // Update the preview image (see Imf::OutputFile::updatePreviewImage())
     // --------------------------------------------------------------------
 
+    IMF_EXPORT
     void                       updatePreviewImage (const PreviewRgba[]);
 
 
@@ -239,8 +254,9 @@ class AcesInputFile
     // destructor will automatically close the file.
     //-------------------------------------------------------
 
+    IMF_EXPORT
     AcesInputFile (const std::string &name,
-           int numThreads = globalThreadCount());
+                  int numThreads = globalThreadCount());
 
 
     //-----------------------------------------------------------
@@ -250,14 +266,16 @@ class AcesInputFile
     // close the file.
     //-----------------------------------------------------------
 
-    AcesInputFile (IStream &is,
-           int numThreads = globalThreadCount());
+    IMF_EXPORT
+    AcesInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                  int numThreads = globalThreadCount());
 
 
     //-----------
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~AcesInputFile ();
 
 
@@ -269,9 +287,10 @@ class AcesInputFile
     //
     //-----------------------------------------------------
 
+    IMF_EXPORT
     void                       setFrameBuffer (Rgba *base,
-                        size_t xStride,
-                        size_t yStride);
+                                               size_t xStride,
+                                               size_t yStride);
 
 
     //--------------------------------------------
@@ -279,7 +298,9 @@ class AcesInputFile
     // Pixels returned will contain ACES RGB data.
     //--------------------------------------------
 
+    IMF_EXPORT
     void                       readPixels (int scanLine1, int scanLine2);
+    IMF_EXPORT
     void                       readPixels (int scanLine);
 
 
@@ -287,16 +308,27 @@ class AcesInputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &             header () const;
-    const Imath::Box2i &       displayWindow () const;
-    const Imath::Box2i &       dataWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     displayWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     dataWindow () const;
+    IMF_EXPORT
     float                      pixelAspectRatio () const;
-    const Imath::V2f           screenWindowCenter () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::V2f         screenWindowCenter () const;
+    IMF_EXPORT
     float                      screenWindowWidth () const;
+    IMF_EXPORT
     LineOrder                  lineOrder () const;
+    IMF_EXPORT
     Compression                        compression () const;
+    IMF_EXPORT
     RgbaChannels               channels () const;
+    IMF_EXPORT
     const char *                fileName () const;
+    IMF_EXPORT
     bool                       isComplete () const;
 
 
@@ -304,6 +336,7 @@ class AcesInputFile
     // Access to the file format version
     //----------------------------------
 
+    IMF_EXPORT
     int                                version () const;
 
   private:
@@ -317,6 +350,9 @@ class AcesInputFile
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
 
 #endif
index c86f871..6a80d8f 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -37,6 +37,8 @@
 #ifndef INCLUDED_IMF_ARRAY_H
 #define INCLUDED_IMF_ARRAY_H
 
+#include "ImfForward.h"
+
 //-------------------------------------------------------------------------
 //
 // class Array
 //         C ()                {std::cout << "C::C  (" << this << ")\n";};
 //         virtual ~C ()       {std::cout << "C::~C (" << this << ")\n";};
 //     };
-//
+// 
 //     int
 //     main ()
 //     {
 //         Array <C> a(3);
-//
+// 
 //         C &b = a[1];
 //         const C &c = a[1];
 //         C *d = a + 2;
 //         const C *e = a;
-//
+// 
 //         return 0;
 //     }
 //
 //-------------------------------------------------------------------------
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T>
 class Array
@@ -81,8 +82,8 @@ class Array
     // Constructors and destructors
     //-----------------------------
 
-     Array ()                          {_data = 0;}
-     Array (long size)                 {_data = new T[size];}
+     Array ()                          {_data = 0; _size = 0;}
+     Array (long size)                 {_data = new T[size]; _size = size;}
     ~Array ()                          {delete [] _data;}
 
 
@@ -110,11 +111,19 @@ class Array
     void resizeEraseUnsafe (long size);
 
 
+    //-------------------------------
+    // Return the size of this array.
+    //-------------------------------
+
+    long size() const   {return _size;}
+
+
   private:
 
     Array (const Array &);             // Copying and assignment
     Array & operator = (const Array &);        // are not implemented
 
+    long _size;
     T * _data;
 };
 
@@ -157,11 +166,20 @@ class Array2D
     void resizeEraseUnsafe (long sizeX, long sizeY);
 
 
+    //-------------------------------
+    // Return the size of this array.
+    //-------------------------------
+
+    long height() const  {return _sizeX;}
+    long width() const   {return _sizeY;}
+
+
   private:
 
     Array2D (const Array2D &);                 // Copying and assignment
     Array2D & operator = (const Array2D &);    // are not implemented
 
+    long        _sizeX;
     long       _sizeY;
     T *                _data;
 };
@@ -177,6 +195,7 @@ Array<T>::resizeErase (long size)
 {
     T *tmp = new T[size];
     delete [] _data;
+    _size = size;
     _data = tmp;
 }
 
@@ -187,14 +206,16 @@ Array<T>::resizeEraseUnsafe (long size)
 {
     delete [] _data;
     _data = 0;
+    _size = 0;
     _data = new T[size];
+    _size = size;
 }
 
 
 template <class T>
 inline
 Array2D<T>::Array2D ():
-    _sizeY (0), _data (0)
+    _sizeX(0), _sizeY (0), _data (0)
 {
     // emtpy
 }
@@ -203,7 +224,7 @@ Array2D<T>::Array2D ():
 template <class T>
 inline
 Array2D<T>::Array2D (long sizeX, long sizeY):
-    _sizeY (sizeY), _data (new T[sizeX * sizeY])
+    _sizeX (sizeX), _sizeY (sizeY), _data (new T[sizeX * sizeY])
 {
     // emtpy
 }
@@ -218,7 +239,7 @@ Array2D<T>::~Array2D ()
 
 
 template <class T>
-inline T *
+inline T *     
 Array2D<T>::operator [] (long x)
 {
     return _data + x * _sizeY;
@@ -239,6 +260,7 @@ Array2D<T>::resizeErase (long sizeX, long sizeY)
 {
     T *tmp = new T[sizeX * sizeY];
     delete [] _data;
+    _sizeX = sizeX;
     _sizeY = sizeY;
     _data = tmp;
 }
@@ -250,12 +272,14 @@ Array2D<T>::resizeEraseUnsafe (long sizeX, long sizeY)
 {
     delete [] _data;
     _data = 0;
+    _sizeX = 0;
     _sizeY = 0;
     _data = new T[sizeX * sizeY];
+    _sizeX = sizeX;
     _sizeY = sizeY;
 }
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
index 0d6644e..7ac146e 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <string.h>
 #include <map>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER 
 
-using IlmThread::Mutex;
-using IlmThread::Lock;
+
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
 
 
 Attribute::Attribute () {}
@@ -66,7 +68,7 @@ struct NameCompare: std::binary_function <const char *, const char *, bool>
     bool
     operator () (const char *x, const char *y) const
     {
-    return strcmp (x, y) < 0;
+       return strcmp (x, y) < 0;
     }
 };
 
@@ -86,22 +88,28 @@ class LockedTypeMap: public TypeMap
 LockedTypeMap &
 typeMap ()
 {
+    // c++11 requires thread-safe static variable initialization
+#if __cplusplus >= 201103L
+    static LockedTypeMap tMap;
+    return tMap;
+#else
     static Mutex criticalSection;
     Lock lock (criticalSection);
 
     static LockedTypeMap* typeMap = 0;
 
     if (typeMap == 0)
-    typeMap = new LockedTypeMap ();
+       typeMap = new LockedTypeMap ();
 
     return *typeMap;
+#endif
 }
 
 
 } // namespace
 
 
-bool
+bool           
 Attribute::knownType (const char typeName[])
 {
     LockedTypeMap& tMap = typeMap();
@@ -111,17 +119,17 @@ Attribute::knownType (const char typeName[])
 }
 
 
-void
+void   
 Attribute::registerAttributeType (const char typeName[],
-                      Attribute *(*newAttribute)())
+                                 Attribute *(*newAttribute)())
 {
     LockedTypeMap& tMap = typeMap();
     Lock lock (tMap.mutex);
 
     if (tMap.find (typeName) != tMap.end())
-    THROW (Iex::ArgExc, "Cannot register image file attribute "
-                "type \"" << typeName << "\". "
-                "The type has already been registered.");
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot register image file attribute "
+                           "type \"" << typeName << "\". "
+                           "The type has already been registered.");
 
     tMap.insert (TypeMap::value_type (typeName, newAttribute));
 }
@@ -146,11 +154,11 @@ Attribute::newAttribute (const char typeName[])
     TypeMap::const_iterator i = tMap.find (typeName);
 
     if (i == tMap.end())
-    THROW (Iex::ArgExc, "Cannot create image file attribute of "
-                "unknown type \"" << typeName << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot create image file attribute of "
+                           "unknown type \"" << typeName << "\".");
 
     return (i->second)();
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 025609c..b39ce78 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include "IexBaseExc.h"
-#include <ImfIO.h>
-#include <ImfXdr.h>
-
+#include "ImfIO.h"
+#include "ImfXdr.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class Attribute
@@ -59,7 +61,9 @@ class Attribute
     // Constructor and destructor
     //---------------------------
 
+    IMF_EXPORT
     Attribute ();
+    IMF_EXPORT
     virtual ~Attribute ();
 
 
@@ -81,12 +85,12 @@ class Attribute
     // Type-specific attribute I/O and copying
     //----------------------------------------
 
-    virtual void               writeValueTo (OStream &os,
-                          int version) const = 0;
+    virtual void               writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                                             int version) const = 0;
 
-    virtual void               readValueFrom (IStream &is,
-                           int size,
-                           int version) = 0;
+    virtual void               readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                              int size,
+                                              int version) = 0;
 
     virtual void               copyValueFrom (const Attribute &other) = 0;
 
@@ -95,6 +99,7 @@ class Attribute
     // Attribute factory
     //------------------
 
+    IMF_EXPORT
     static Attribute *         newAttribute (const char typeName[]);
 
 
@@ -102,6 +107,7 @@ class Attribute
     // Test if a given attribute type has already been registered
     //-----------------------------------------------------------
 
+    IMF_EXPORT
     static bool                        knownType (const char typeName[]);
 
 
@@ -112,8 +118,9 @@ class Attribute
     // knows how to make objects of this type.
     //--------------------------------------------------
 
+    IMF_EXPORT
     static void                registerAttributeType (const char typeName[],
-                           Attribute *(*newAttribute)());
+                                              Attribute *(*newAttribute)());
 
     //------------------------------------------------------
     // Un-register an attribute type so that newAttribute()
@@ -121,6 +128,7 @@ class Attribute
     // debugging only).
     //------------------------------------------------------
 
+    IMF_EXPORT
     static void                unRegisterAttributeType (const char typeName[]);
 };
 
@@ -128,7 +136,7 @@ class Attribute
 //-------------------------------------------------
 // Class template for attributes of a specific type
 //-------------------------------------------------
-
+    
 template <class T>
 class TypedAttribute: public Attribute
 {
@@ -157,7 +165,7 @@ class TypedAttribute: public Attribute
     //--------------------------------
 
     virtual const char *               typeName () const;
-
+    
 
     //---------------------------------------------------------
     // Static version of typeName()
@@ -165,7 +173,7 @@ class TypedAttribute: public Attribute
     //---------------------------------------------------------
 
     static const char *                        staticTypeName ();
-
+    
 
     //---------------------
     // Make a new attribute
@@ -186,12 +194,12 @@ class TypedAttribute: public Attribute
     // Depending on type T, these functions may have to be specialized.
     //-----------------------------------------------------------------
 
-    virtual void               writeValueTo (OStream &os,
-                          int version) const;
+    virtual void               writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                                             int version) const;
 
-    virtual void               readValueFrom (IStream &is,
-                           int size,
-                           int version);
+    virtual void               readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                              int size,
+                                              int version);
 
     virtual void               copyValueFrom (const Attribute &other);
 
@@ -233,11 +241,9 @@ class TypedAttribute: public Attribute
     T                                  _value;
 };
 
-
 //------------------------------------
 // Implementation of TypedAttribute<T>
 //------------------------------------
-
 template <class T>
 TypedAttribute<T>::TypedAttribute ():
     Attribute (),
@@ -248,7 +254,7 @@ TypedAttribute<T>::TypedAttribute ():
 
 
 template <class T>
-TypedAttribute<T>::TypedAttribute (const T &value):
+TypedAttribute<T>::TypedAttribute (const T & value):
     Attribute (),
     _value (value)
 {
@@ -289,7 +295,7 @@ TypedAttribute<T>::value () const
 
 
 template <class T>
-const char *
+const char *   
 TypedAttribute<T>::typeName () const
 {
     return staticTypeName();
@@ -315,23 +321,26 @@ TypedAttribute<T>::copy () const
 
 
 template <class T>
-void
-TypedAttribute<T>::writeValueTo (OStream &os, int) const
+void           
+TypedAttribute<T>::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                                    int version) const
 {
-    Xdr::write <StreamIO> (os, _value);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _value);
 }
 
 
 template <class T>
-void
-TypedAttribute<T>::readValueFrom (IStream &is, int, int)
+void           
+TypedAttribute<T>::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                     int size,
+                                     int version)
 {
-    Xdr::read <StreamIO> (is, _value);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _value);
 }
 
 
 template <class T>
-void
+void           
 TypedAttribute<T>::copyValueFrom (const Attribute &other)
 {
     _value = cast(other)._value;
@@ -343,10 +352,10 @@ TypedAttribute<T> *
 TypedAttribute<T>::cast (Attribute *attribute)
 {
     TypedAttribute<T> *t =
-    dynamic_cast <TypedAttribute<T> *> (attribute);
+       dynamic_cast <TypedAttribute<T> *> (attribute);
 
     if (t == 0)
-    throw Iex::TypeExc ("Unexpected attribute type.");
+       throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return t;
 }
@@ -357,10 +366,10 @@ const TypedAttribute<T> *
 TypedAttribute<T>::cast (const Attribute *attribute)
 {
     const TypedAttribute<T> *t =
-    dynamic_cast <const TypedAttribute<T> *> (attribute);
+       dynamic_cast <const TypedAttribute<T> *> (attribute);
 
     if (t == 0)
-    throw Iex::TypeExc ("Unexpected attribute type.");
+       throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return t;
 }
@@ -398,30 +407,7 @@ TypedAttribute<T>::unRegisterAttributeType ()
 }
 
 
-} // namespace Imf
-
-#if defined(OPENEXR_DLL) && defined(_MSC_VER)
-    // Tell MS VC++ to disable "non dll-interface class used as base
-    // for dll-interface class" and "no suitable definition provided
-    // for explicit template"
-    #pragma warning (disable : 4275 4661)
-
-    #if defined (ILMIMF_EXPORTS)
-    #define IMF_EXPIMP_TEMPLATE
-    #else
-    #define IMF_EXPIMP_TEMPLATE extern
-    #endif
-
-    IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<float>;
-    IMF_EXPIMP_TEMPLATE template class Imf::TypedAttribute<double>;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-    #pragma warning(default : 4251)
-    #undef EXTERN_TEMPLATE
-#endif
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfAttribute.cpp>
-#endif
 
 #endif
index 37320aa..c1ecaff 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include "OpenEXRConfig.h"
-
-#if !defined (HAVE_LARGE_STACK)
+#include "ImfNamespace.h"
 #include <string.h>
-#endif
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 #if !defined (HAVE_LARGE_STACK)
@@ -61,15 +58,15 @@ namespace Imf {
     {
       public:
 
-     AutoArray (): _data (new T [size]) { memset(_data, 0, size*sizeof(T)); }
-    ~AutoArray () {delete [] _data;}
-
-    operator T * ()                    {return _data;}
-    operator const T * () const        {return _data;}
+        AutoArray (): _data (new T [size]) { memset(_data, 0, size*sizeof(T)); }
+       ~AutoArray () {delete [] _data;}
 
+       operator T * ()                 {return _data;}
+       operator const T * () const     {return _data;}
+      
       private:
 
-    T *_data;
+       T *_data;
     };
 
 
@@ -81,17 +78,18 @@ namespace Imf {
     {
       public:
 
-    operator T * ()                    {return _data;}
-    operator const T * () const        {return _data;}
-
+       operator T * ()                 {return _data;}
+       operator const T * () const     {return _data;}
+      
       private:
 
-    T _data[size];
+       T _data[size];
     };
 
 
 #endif
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
index 1a2be80..f13e143 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -63,7 +63,7 @@
 //               |
 //               | 0
 //               |
-//               v
+//               v 
 //              4 -------->  5 -------->  6 -------->  7
 //               |     4            8           12
 //               |
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfB44Compressor.h>
-#include <ImfHeader.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfB44Compressor.h"
+#include "ImfHeader.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfCheckedArithmetic.h"
 #include <ImathFun.h>
 #include <ImathBox.h>
 #include <Iex.h>
 #include <string.h>
 #include <assert.h>
 #include <algorithm>
+#include "ImfNamespace.h"
+
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::divp;
-using Imath::modp;
-using Imath::Box2i;
-using Imath::V2i;
+
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 using std::min;
 
 namespace {
@@ -124,7 +127,7 @@ namespace {
 //
 // Lookup tables for
 //     y = exp (x / 8)
-// and
+// and 
 //     x = 8 * log (y)
 //
 
@@ -135,7 +138,7 @@ inline void
 convertFromLinear (unsigned short s[16])
 {
     for (int i = 0; i < 16; ++i)
-    s[i] = expTable[s[i]];
+       s[i] = expTable[s[i]];
 }
 
 
@@ -143,7 +146,7 @@ inline void
 convertToLinear (unsigned short s[16])
 {
     for (int i = 0; i < 16; ++i)
-    s[i] = logTable[s[i]];
+       s[i] = logTable[s[i]];
 }
 
 
@@ -225,14 +228,14 @@ pack (const unsigned short s[16],
 
     for (int i = 0; i < 16; ++i)
     {
-    if ((s[i] & 0x7c00) == 0x7c00)
-        t[i] = 0x8000;
-    else if (s[i] & 0x8000)
-        t[i] = ~s[i];
-    else
-        t[i] = s[i] | 0x8000;
+       if ((s[i] & 0x7c00) == 0x7c00)
+           t[i] = 0x8000;
+       else if (s[i] & 0x8000)
+           t[i] = ~s[i];
+       else
+           t[i] = s[i] | 0x8000;
     }
-
+    
     //
     // Find the maximum, tMax, of t[0] ... t[15].
     //
@@ -240,8 +243,8 @@ pack (const unsigned short s[16],
     unsigned short tMax = 0;
 
     for (int i = 0; i < 16; ++i)
-    if (tMax < t[i])
-        tMax = t[i];
+       if (tMax < t[i])
+           tMax = t[i];
 
     //
     // Compute a set of running differences, r[0] ... r[14]:
@@ -261,79 +264,79 @@ pack (const unsigned short s[16],
 
     do
     {
-    shift += 1;
+        shift += 1;
 
-    //
-    // Compute absolute differences, d[0] ... d[15],
-    // between tMax and t[0] ... t[15].
-    //
-    // Shift and round the absolute differences.
-    //
+        //
+        // Compute absolute differences, d[0] ... d[15],
+        // between tMax and t[0] ... t[15].
+        //
+        // Shift and round the absolute differences.
+        //
 
-    for (int i = 0; i < 16; ++i)
-        d[i] = shiftAndRound (tMax - t[i], shift);
+        for (int i = 0; i < 16; ++i)
+            d[i] = shiftAndRound (tMax - t[i], shift);
 
-    //
-    // Convert d[0] .. d[15] into running differences
-    //
+        //
+        // Convert d[0] .. d[15] into running differences
+        //
 
-    r[ 0] = d[ 0] - d[ 4] + bias;
-    r[ 1] = d[ 4] - d[ 8] + bias;
-    r[ 2] = d[ 8] - d[12] + bias;
+        r[ 0] = d[ 0] - d[ 4] + bias;
+        r[ 1] = d[ 4] - d[ 8] + bias;
+        r[ 2] = d[ 8] - d[12] + bias;
 
-    r[ 3] = d[ 0] - d[ 1] + bias;
-    r[ 4] = d[ 4] - d[ 5] + bias;
-    r[ 5] = d[ 8] - d[ 9] + bias;
-    r[ 6] = d[12] - d[13] + bias;
+        r[ 3] = d[ 0] - d[ 1] + bias;
+        r[ 4] = d[ 4] - d[ 5] + bias;
+        r[ 5] = d[ 8] - d[ 9] + bias;
+        r[ 6] = d[12] - d[13] + bias;
 
-    r[ 7] = d[ 1] - d[ 2] + bias;
-    r[ 8] = d[ 5] - d[ 6] + bias;
-    r[ 9] = d[ 9] - d[10] + bias;
-    r[10] = d[13] - d[14] + bias;
+        r[ 7] = d[ 1] - d[ 2] + bias;
+        r[ 8] = d[ 5] - d[ 6] + bias;
+        r[ 9] = d[ 9] - d[10] + bias;
+        r[10] = d[13] - d[14] + bias;
 
-    r[11] = d[ 2] - d[ 3] + bias;
-    r[12] = d[ 6] - d[ 7] + bias;
-    r[13] = d[10] - d[11] + bias;
-    r[14] = d[14] - d[15] + bias;
+        r[11] = d[ 2] - d[ 3] + bias;
+        r[12] = d[ 6] - d[ 7] + bias;
+        r[13] = d[10] - d[11] + bias;
+        r[14] = d[14] - d[15] + bias;
 
-    rMin = r[0];
-    rMax = r[0];
+        rMin = r[0];
+        rMax = r[0];
 
-    for (int i = 1; i < 15; ++i)
-    {
-        if (rMin > r[i])
-        rMin = r[i];
+        for (int i = 1; i < 15; ++i)
+        {
+            if (rMin > r[i])
+                rMin = r[i];
 
-        if (rMax < r[i])
-        rMax = r[i];
-    }
+            if (rMax < r[i])
+                rMax = r[i];
+        }
     }
     while (rMin < 0 || rMax > 0x3f);
 
     if (rMin == bias && rMax == bias && optFlatFields)
     {
-    //
-    // Special case - all pixels have the same value.
-    // We encode this in 3 instead of 14 bytes by
-    // storing the value 0xfc in the third output byte,
-    // which cannot occur in the 14-byte encoding.
-    //
+        //
+        // Special case - all pixels have the same value.
+        // We encode this in 3 instead of 14 bytes by
+        // storing the value 0xfc in the third output byte,
+        // which cannot occur in the 14-byte encoding.
+        //
 
-    b[0] = (t[0] >> 8);
-    b[1] =  t[0];
-    b[2] = 0xfc;
+        b[0] = (t[0] >> 8);
+        b[1] = (unsigned char) t[0];
+        b[2] = 0xfc;
 
-    return 3;
+        return 3;
     }
 
     if (exactMax)
     {
-    //
-    // Adjust t[0] so that the pixel whose value is equal
-    // to tMax gets represented as accurately as possible.
-    //
+        //
+        // Adjust t[0] so that the pixel whose value is equal
+        // to tMax gets represented as accurately as possible.
+        //
 
-    t[0] = tMax - (d[0] << shift);
+        t[0] = tMax - (d[0] << shift);
     }
 
     //
@@ -341,7 +344,7 @@ pack (const unsigned short s[16],
     //
 
     b[ 0] = (t[0] >> 8);
-    b[ 1] =  t[0];
+    b[ 1] = (unsigned char) t[0];
 
     b[ 2] = (unsigned char) ((shift << 2) | (r[ 0] >> 4));
     b[ 3] = (unsigned char) ((r[ 0] << 4) | (r[ 1] >> 2));
@@ -372,7 +375,7 @@ unpack14 (const unsigned char b[14], unsigned short s[16])
     //
 
     #if defined (DEBUG)
-    assert (b[2] != 0xfc);
+       assert (b[2] != 0xfc);
     #endif
 
     s[ 0] = (b[0] << 8) | b[1];
@@ -383,17 +386,17 @@ unpack14 (const unsigned char b[14], unsigned short s[16])
     s[ 4] = s[ 0] + ((((b[ 2] << 4) | (b[ 3] >> 4)) & 0x3f) << shift) - bias;
     s[ 8] = s[ 4] + ((((b[ 3] << 2) | (b[ 4] >> 6)) & 0x3f) << shift) - bias;
     s[12] = s[ 8] +   ((b[ 4]                       & 0x3f) << shift) - bias;
-
+    
     s[ 1] = s[ 0] +   ((b[ 5] >> 2)                         << shift) - bias;
     s[ 5] = s[ 4] + ((((b[ 5] << 4) | (b[ 6] >> 4)) & 0x3f) << shift) - bias;
     s[ 9] = s[ 8] + ((((b[ 6] << 2) | (b[ 7] >> 6)) & 0x3f) << shift) - bias;
     s[13] = s[12] +   ((b[ 7]                       & 0x3f) << shift) - bias;
-
+    
     s[ 2] = s[ 1] +   ((b[ 8] >> 2)                         << shift) - bias;
     s[ 6] = s[ 5] + ((((b[ 8] << 4) | (b[ 9] >> 4)) & 0x3f) << shift) - bias;
     s[10] = s[ 9] + ((((b[ 9] << 2) | (b[10] >> 6)) & 0x3f) << shift) - bias;
     s[14] = s[13] +   ((b[10]                       & 0x3f) << shift) - bias;
-
+    
     s[ 3] = s[ 2] +   ((b[11] >> 2)                         << shift) - bias;
     s[ 7] = s[ 6] + ((((b[11] << 4) | (b[12] >> 4)) & 0x3f) << shift) - bias;
     s[11] = s[10] + ((((b[12] << 2) | (b[13] >> 6)) & 0x3f) << shift) - bias;
@@ -401,10 +404,10 @@ unpack14 (const unsigned char b[14], unsigned short s[16])
 
     for (int i = 0; i < 16; ++i)
     {
-    if (s[i] & 0x8000)
-        s[i] &= 0x7fff;
-    else
-        s[i] = ~s[i];
+       if (s[i] & 0x8000)
+           s[i] &= 0x7fff;
+       else
+           s[i] = ~s[i];
     }
 }
 
@@ -418,34 +421,34 @@ unpack3 (const unsigned char b[3], unsigned short s[16])
     //
 
     #if defined (DEBUG)
-    assert (b[2] == 0xfc);
+       assert (b[2] == 0xfc);
     #endif
 
     s[0] = (b[0] << 8) | b[1];
 
     if (s[0] & 0x8000)
-    s[0] &= 0x7fff;
+       s[0] &= 0x7fff;
     else
-    s[0] = ~s[0];
+       s[0] = ~s[0];
 
     for (int i = 1; i < 16; ++i)
-    s[i] = s[0];
+       s[i] = s[0];
 }
 
 
 void
 notEnoughData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
-             "(input data are shorter than expected).");
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
+                        "(input data are shorter than expected).");
 }
 
 
 void
 tooMuchData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
-             "(input data are longer than expected).");
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
+                        "(input data are longer than expected).");
 }
 
 } // namespace
@@ -496,14 +499,14 @@ B44Compressor::B44Compressor
     int numHalfChans = 0;
 
     for (ChannelList::ConstIterator c = channels.begin();
-     c != channels.end();
-     ++c)
+        c != channels.end();
+        ++c)
     {
-    assert (pixelTypeSize (c.channel().type) % pixelTypeSize (HALF) == 0);
-    ++_numChans;
+       assert (pixelTypeSize (c.channel().type) % pixelTypeSize (HALF) == 0);
+       ++_numChans;
 
-    if (c.channel().type == HALF)
-        ++numHalfChans;
+       if (c.channel().type == HALF)
+           ++numHalfChans;
     }
 
     //
@@ -520,14 +523,14 @@ B44Compressor::B44Compressor
     int i = 0;
 
     for (ChannelList::ConstIterator c = channels.begin();
-     c != channels.end();
-     ++c, ++i)
+        c != channels.end();
+        ++c, ++i)
     {
-    _channelData[i].ys = c.channel().ySampling;
-    _channelData[i].type = c.channel().type;
-    _channelData[i].pLinear = c.channel().pLinear;
-    _channelData[i].size =
-        pixelTypeSize (c.channel().type) / pixelTypeSize (HALF);
+       _channelData[i].ys = c.channel().ySampling;
+       _channelData[i].type = c.channel().type;
+       _channelData[i].pLinear = c.channel().pLinear;
+       _channelData[i].size =
+           pixelTypeSize (c.channel().type) / pixelTypeSize (HALF);
     }
 
     const Box2i &dataWindow = hdr.dataWindow();
@@ -544,7 +547,7 @@ B44Compressor::B44Compressor
     assert (sizeof (unsigned short) == pixelTypeSize (HALF));
 
     if (_numChans == numHalfChans)
-    _format = NATIVE;
+       _format = NATIVE;
 }
 
 
@@ -572,23 +575,23 @@ B44Compressor::format () const
 
 int
 B44Compressor::compress (const char *inPtr,
-             int inSize,
-             int minY,
-             const char *&outPtr)
+                        int inSize,
+                        int minY,
+                        const char *&outPtr)
 {
     return compress (inPtr,
-             inSize,
-             Box2i (V2i (_minX, minY),
-                V2i (_maxX, minY + numScanLines() - 1)),
-             outPtr);
+                    inSize,
+                    Box2i (V2i (_minX, minY),
+                           V2i (_maxX, minY + numScanLines() - 1)),
+                    outPtr);
 }
 
 
 int
 B44Compressor::compressTile (const char *inPtr,
-                 int inSize,
-                 Imath::Box2i range,
-                 const char *&outPtr)
+                            int inSize,
+                            IMATH_NAMESPACE::Box2i range,
+                            const char *&outPtr)
 {
     return compress (inPtr, inSize, range, outPtr);
 }
@@ -596,23 +599,23 @@ B44Compressor::compressTile (const char *inPtr,
 
 int
 B44Compressor::uncompress (const char *inPtr,
-               int inSize,
-               int minY,
-               const char *&outPtr)
+                          int inSize,
+                          int minY,
+                          const char *&outPtr)
 {
     return uncompress (inPtr,
-               inSize,
-               Box2i (V2i (_minX, minY),
-                  V2i (_maxX, minY + numScanLines() - 1)),
-               outPtr);
+                      inSize,
+                      Box2i (V2i (_minX, minY),
+                             V2i (_maxX, minY + numScanLines() - 1)),
+                      outPtr);
 }
 
 
 int
 B44Compressor::uncompressTile (const char *inPtr,
-                   int inSize,
-                   Imath::Box2i range,
-                   const char *&outPtr)
+                              int inSize,
+                              IMATH_NAMESPACE::Box2i range,
+                              const char *&outPtr)
 {
     return uncompress (inPtr, inSize, range, outPtr);
 }
@@ -620,9 +623,9 @@ B44Compressor::uncompressTile (const char *inPtr,
 
 int
 B44Compressor::compress (const char *inPtr,
-             int inSize,
-             Imath::Box2i range,
-             const char *&outPtr)
+                        int inSize,
+                        IMATH_NAMESPACE::Box2i range,
+                        const char *&outPtr)
 {
     //
     // Compress a block of pixel data:  First copy the input pixels
@@ -637,11 +640,11 @@ B44Compressor::compress (const char *inPtr,
 
     if (inSize == 0)
     {
-    //
-    // Special case - empty input buffer.
-    //
+       //
+       // Special case - empty input buffer.
+       //
 
-    return 0;
+       return 0;
     }
 
     //
@@ -654,88 +657,88 @@ B44Compressor::compress (const char *inPtr,
     int maxX = min (range.max.x, _maxX);
     int minY = range.min.y;
     int maxY = min (range.max.y, _maxY);
-
+    
     unsigned short *tmpBufferEnd = _tmpBuffer;
     int i = 0;
 
     for (ChannelList::ConstIterator c = _channels.begin();
-     c != _channels.end();
-     ++c, ++i)
+        c != _channels.end();
+        ++c, ++i)
     {
-    ChannelData &cd = _channelData[i];
+       ChannelData &cd = _channelData[i];
 
-    cd.start = tmpBufferEnd;
-    cd.end = cd.start;
+       cd.start = tmpBufferEnd;
+       cd.end = cd.start;
 
-    cd.nx = numSamples (c.channel().xSampling, minX, maxX);
-    cd.ny = numSamples (c.channel().ySampling, minY, maxY);
+       cd.nx = numSamples (c.channel().xSampling, minX, maxX);
+       cd.ny = numSamples (c.channel().ySampling, minY, maxY);
 
-    tmpBufferEnd += cd.nx * cd.ny * cd.size;
+       tmpBufferEnd += cd.nx * cd.ny * cd.size;
     }
 
     if (_format == XDR)
     {
-    //
-    // The data in the input buffer are in the machine-independent
-    // Xdr format.  Copy the HALF channels into _tmpBuffer and
-    // convert them back into native format for compression.
-    // Copy UINT and FLOAT channels verbatim into _tmpBuffer.
-    //
-
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        if (cd.type == HALF)
-        {
-            for (int x = cd.nx; x > 0; --x)
-            {
-            Xdr::read <CharPtrIO> (inPtr, *cd.end);
-            ++cd.end;
-            }
-        }
-        else
-        {
-            int n = cd.nx * cd.size;
-            memcpy (cd.end, inPtr, n * sizeof (unsigned short));
-            inPtr += n * sizeof (unsigned short);
-            cd.end += n;
-        }
-        }
-    }
+       //
+       // The data in the input buffer are in the machine-independent
+       // Xdr format.  Copy the HALF channels into _tmpBuffer and
+       // convert them back into native format for compression.
+       // Copy UINT and FLOAT channels verbatim into _tmpBuffer.
+       //
+
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               if (cd.type == HALF)
+               {
+                   for (int x = cd.nx; x > 0; --x)
+                   {
+                       Xdr::read <CharPtrIO> (inPtr, *cd.end);
+                       ++cd.end;
+                   }
+               }
+               else
+               {
+                   int n = cd.nx * cd.size;
+                   memcpy (cd.end, inPtr, n * sizeof (unsigned short));
+                   inPtr += n * sizeof (unsigned short);
+                   cd.end += n;
+               }
+           }
+       }
     }
     else
     {
-    //
-    // The input buffer contains only HALF channels, and they
-    // are in native, machine-dependent format.  Copy the pixels
-    // into _tmpBuffer.
-    //
-
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        #if defined (DEBUG)
-            assert (cd.type == HALF);
-        #endif
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        int n = cd.nx * cd.size;
-        memcpy (cd.end, inPtr, n * sizeof (unsigned short));
-        inPtr  += n * sizeof (unsigned short);
-        cd.end += n;
-        }
-    }
+       //
+       // The input buffer contains only HALF channels, and they
+       // are in native, machine-dependent format.  Copy the pixels
+       // into _tmpBuffer.
+       //
+
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               #if defined (DEBUG)
+                   assert (cd.type == HALF);
+               #endif
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               int n = cd.nx * cd.size;
+               memcpy (cd.end, inPtr, n * sizeof (unsigned short));
+               inPtr  += n * sizeof (unsigned short);
+               cd.end += n;
+           }
+       }
     }
 
     //
@@ -746,10 +749,10 @@ B44Compressor::compress (const char *inPtr,
 
     #if defined (DEBUG)
 
-    for (int i = 1; i < _numChans; ++i)
-        assert (_channelData[i-1].end == _channelData[i].start);
+       for (int i = 1; i < _numChans; ++i)
+           assert (_channelData[i-1].end == _channelData[i].start);
 
-    assert (_channelData[_numChans-1].end == tmpBufferEnd);
+       assert (_channelData[_numChans-1].end == tmpBufferEnd);
 
     #endif
 
@@ -766,94 +769,94 @@ B44Compressor::compress (const char *inPtr,
 
     for (int i = 0; i < _numChans; ++i)
     {
-    ChannelData &cd = _channelData[i];
-
-    if (cd.type != HALF)
-    {
-        //
-        // UINT or FLOAT channel.
-        //
-
-        int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short);
-        memcpy (outEnd, cd.start, n);
-        outEnd += n;
-
-        continue;
-    }
-
-    //
-    // HALF channel
-    //
-
-    for (int y = 0; y < cd.ny; y += 4)
-    {
-        //
-        // Copy the next 4x4 pixel block into array s.
-        // If the width, cd.nx, or the height, cd.ny, of
-        // the pixel data in _tmpBuffer is not divisible
-        // by 4, then pad the data by repeating the
-        // rightmost column and the bottom row.
-        //
-
-        unsigned short *row0 = cd.start + y * cd.nx;
-        unsigned short *row1 = row0 + cd.nx;
-        unsigned short *row2 = row1 + cd.nx;
-        unsigned short *row3 = row2 + cd.nx;
-
-        if (y + 3 >= cd.ny)
-        {
-        if (y + 1 >= cd.ny)
-            row1 = row0;
-
-        if (y + 2 >= cd.ny)
-            row2 = row1;
-
-        row3 = row2;
-        }
-
-        for (int x = 0; x < cd.nx; x += 4)
-        {
-        unsigned short s[16];
-
-        if (x + 3 >= cd.nx)
-        {
-            int n = cd.nx - x;
-
-            for (int i = 0; i < 4; ++i)
-            {
-            int j = min (i, n - 1);
-
-            s[i +  0] = row0[j];
-            s[i +  4] = row1[j];
-            s[i +  8] = row2[j];
-            s[i + 12] = row3[j];
-            }
-        }
-        else
-        {
-            memcpy (&s[ 0], row0, 4 * sizeof (unsigned short));
-            memcpy (&s[ 4], row1, 4 * sizeof (unsigned short));
-            memcpy (&s[ 8], row2, 4 * sizeof (unsigned short));
-            memcpy (&s[12], row3, 4 * sizeof (unsigned short));
-        }
-
-        row0 += 4;
-        row1 += 4;
-        row2 += 4;
-        row3 += 4;
-
-        //
-        // Compress the contents of array s and append the
-        // results to the output buffer.
-        //
-
-        if (cd.pLinear)
-            convertFromLinear (s);
-
-        outEnd += pack (s, (unsigned char *) outEnd,
-                _optFlatFields, !cd.pLinear);
-        }
-    }
+       ChannelData &cd = _channelData[i];
+       
+       if (cd.type != HALF)
+       {
+           //
+           // UINT or FLOAT channel.
+           //
+
+           int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short);
+           memcpy (outEnd, cd.start, n);
+           outEnd += n;
+
+           continue;
+       }
+       
+       //
+       // HALF channel
+       //
+
+       for (int y = 0; y < cd.ny; y += 4)
+       {
+           //
+           // Copy the next 4x4 pixel block into array s.
+           // If the width, cd.nx, or the height, cd.ny, of
+           // the pixel data in _tmpBuffer is not divisible
+           // by 4, then pad the data by repeating the
+           // rightmost column and the bottom row.
+           // 
+
+           unsigned short *row0 = cd.start + y * cd.nx;
+           unsigned short *row1 = row0 + cd.nx;
+           unsigned short *row2 = row1 + cd.nx;
+           unsigned short *row3 = row2 + cd.nx;
+
+           if (y + 3 >= cd.ny)
+           {
+               if (y + 1 >= cd.ny)
+                   row1 = row0;
+
+               if (y + 2 >= cd.ny)
+                   row2 = row1;
+
+               row3 = row2;
+           }
+
+           for (int x = 0; x < cd.nx; x += 4)
+           {
+               unsigned short s[16];
+
+               if (x + 3 >= cd.nx)
+               {
+                   int n = cd.nx - x;
+
+                   for (int i = 0; i < 4; ++i)
+                   {
+                       int j = min (i, n - 1);
+
+                       s[i +  0] = row0[j];
+                       s[i +  4] = row1[j];
+                       s[i +  8] = row2[j];
+                       s[i + 12] = row3[j];
+                   }
+               }
+               else
+               {
+                   memcpy (&s[ 0], row0, 4 * sizeof (unsigned short));
+                   memcpy (&s[ 4], row1, 4 * sizeof (unsigned short));
+                   memcpy (&s[ 8], row2, 4 * sizeof (unsigned short));
+                   memcpy (&s[12], row3, 4 * sizeof (unsigned short));
+               }
+
+               row0 += 4;
+               row1 += 4;
+               row2 += 4;
+               row3 += 4;
+
+               //
+               // Compress the contents of array s and append the
+               // results to the output buffer.
+               //
+
+               if (cd.pLinear)
+                   convertFromLinear (s);
+
+               outEnd += pack (s, (unsigned char *) outEnd,
+                               _optFlatFields, !cd.pLinear);
+           }
+       }
     }
 
     return outEnd - _outBuffer;
@@ -862,9 +865,9 @@ B44Compressor::compress (const char *inPtr,
 
 int
 B44Compressor::uncompress (const char *inPtr,
-               int inSize,
-               Imath::Box2i range,
-               const char *&outPtr)
+                          int inSize,
+                          IMATH_NAMESPACE::Box2i range,
+                          const char *&outPtr)
 {
     //
     // This function is the reverse of the compress() function,
@@ -880,190 +883,190 @@ B44Compressor::uncompress (const char *inPtr,
 
     if (inSize == 0)
     {
-    return 0;
+       return 0;
     }
 
     int minX = range.min.x;
     int maxX = min (range.max.x, _maxX);
     int minY = range.min.y;
     int maxY = min (range.max.y, _maxY);
-
+    
     unsigned short *tmpBufferEnd = _tmpBuffer;
     int i = 0;
 
     for (ChannelList::ConstIterator c = _channels.begin();
-     c != _channels.end();
-     ++c, ++i)
+        c != _channels.end();
+        ++c, ++i)
     {
-    ChannelData &cd = _channelData[i];
+       ChannelData &cd = _channelData[i];
 
-    cd.start = tmpBufferEnd;
-    cd.end = cd.start;
+       cd.start = tmpBufferEnd;
+       cd.end = cd.start;
 
-    cd.nx = numSamples (c.channel().xSampling, minX, maxX);
-    cd.ny = numSamples (c.channel().ySampling, minY, maxY);
+       cd.nx = numSamples (c.channel().xSampling, minX, maxX);
+       cd.ny = numSamples (c.channel().ySampling, minY, maxY);
 
-    tmpBufferEnd += cd.nx * cd.ny * cd.size;
+       tmpBufferEnd += cd.nx * cd.ny * cd.size;
     }
 
     for (int i = 0; i < _numChans; ++i)
     {
-    ChannelData &cd = _channelData[i];
-
-    if (cd.type != HALF)
-    {
-        //
-        // UINT or FLOAT channel.
-        //
-
-        int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short);
-
-        if (inSize < n)
-        notEnoughData();
-
-        memcpy (cd.start, inPtr, n);
-        inPtr += n;
-        inSize -= n;
-
-        continue;
-    }
-
-    //
-    // HALF channel
-    //
-
-    for (int y = 0; y < cd.ny; y += 4)
-    {
-        unsigned short *row0 = cd.start + y * cd.nx;
-        unsigned short *row1 = row0 + cd.nx;
-        unsigned short *row2 = row1 + cd.nx;
-        unsigned short *row3 = row2 + cd.nx;
-
-        for (int x = 0; x < cd.nx; x += 4)
-        {
-        unsigned short s[16];
-
-        if (inSize < 3)
-            notEnoughData();
-
-        if (((const unsigned char *)inPtr)[2] == 0xfc)
-        {
-            unpack3 ((const unsigned char *)inPtr, s);
-            inPtr += 3;
-            inSize -= 3;
-        }
-        else
-        {
-            if (inSize < 14)
-            notEnoughData();
-
-            unpack14 ((const unsigned char *)inPtr, s);
-            inPtr += 14;
-            inSize -= 14;
-        }
-
-        if (cd.pLinear)
-            convertToLinear (s);
-
-        int n = (x + 3 < cd.nx)?
-                4 * sizeof (unsigned short) :
-                (cd.nx - x) * sizeof (unsigned short);
-
-        if (y + 3 < cd.ny)
-        {
-            memcpy (row0, &s[ 0], n);
-            memcpy (row1, &s[ 4], n);
-            memcpy (row2, &s[ 8], n);
-            memcpy (row3, &s[12], n);
-        }
-        else
-        {
-            memcpy (row0, &s[ 0], n);
-
-            if (y + 1 < cd.ny)
-            memcpy (row1, &s[ 4], n);
-
-            if (y + 2 < cd.ny)
-            memcpy (row2, &s[ 8], n);
-        }
-
-        row0 += 4;
-        row1 += 4;
-        row2 += 4;
-        row3 += 4;
-        }
-    }
+       ChannelData &cd = _channelData[i];
+
+       if (cd.type != HALF)
+       {
+           //
+           // UINT or FLOAT channel.
+           //
+
+           int n = cd.nx * cd.ny * cd.size * sizeof (unsigned short);
+
+           if (inSize < n)
+               notEnoughData();
+
+           memcpy (cd.start, inPtr, n);
+           inPtr += n;
+           inSize -= n;
+
+           continue;
+       }
+
+       //
+       // HALF channel
+       //
+
+       for (int y = 0; y < cd.ny; y += 4)
+       {
+           unsigned short *row0 = cd.start + y * cd.nx;
+           unsigned short *row1 = row0 + cd.nx;
+           unsigned short *row2 = row1 + cd.nx;
+           unsigned short *row3 = row2 + cd.nx;
+
+           for (int x = 0; x < cd.nx; x += 4)
+           {
+               unsigned short s[16]; 
+
+               if (inSize < 3)
+                   notEnoughData();
+
+               if (((const unsigned char *)inPtr)[2] == 0xfc)
+               {
+                   unpack3 ((const unsigned char *)inPtr, s);
+                   inPtr += 3;
+                   inSize -= 3;
+               }
+               else
+               {
+                   if (inSize < 14)
+                       notEnoughData();
+
+                   unpack14 ((const unsigned char *)inPtr, s);
+                   inPtr += 14;
+                   inSize -= 14;
+               }
+
+               if (cd.pLinear)
+                   convertToLinear (s);
+
+               int n = (x + 3 < cd.nx)?
+                           4 * sizeof (unsigned short) :
+                           (cd.nx - x) * sizeof (unsigned short);
+
+               if (y + 3 < cd.ny)
+               {
+                   memcpy (row0, &s[ 0], n);
+                   memcpy (row1, &s[ 4], n);
+                   memcpy (row2, &s[ 8], n);
+                   memcpy (row3, &s[12], n);
+               }
+               else
+               {
+                   memcpy (row0, &s[ 0], n);
+
+                   if (y + 1 < cd.ny)
+                       memcpy (row1, &s[ 4], n);
+
+                   if (y + 2 < cd.ny)
+                       memcpy (row2, &s[ 8], n);
+               }
+
+               row0 += 4;
+               row1 += 4;
+               row2 += 4;
+               row3 += 4;
+           }
+       }
     }
 
     char *outEnd = _outBuffer;
 
     if (_format == XDR)
     {
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        if (cd.type == HALF)
-        {
-            for (int x = cd.nx; x > 0; --x)
-            {
-            Xdr::write <CharPtrIO> (outEnd, *cd.end);
-            ++cd.end;
-            }
-        }
-        else
-        {
-            int n = cd.nx * cd.size;
-            memcpy (outEnd, cd.end, n * sizeof (unsigned short));
-            outEnd += n * sizeof (unsigned short);
-            cd.end += n;
-        }
-        }
-    }
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               if (cd.type == HALF)
+               {
+                   for (int x = cd.nx; x > 0; --x)
+                   {
+                       Xdr::write <CharPtrIO> (outEnd, *cd.end);
+                       ++cd.end;
+                   }
+               }
+               else
+               {
+                   int n = cd.nx * cd.size;
+                   memcpy (outEnd, cd.end, n * sizeof (unsigned short));
+                   outEnd += n * sizeof (unsigned short);
+                   cd.end += n;
+               }
+           }
+       }
     }
     else
     {
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        #if defined (DEBUG)
-            assert (cd.type == HALF);
-        #endif
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        int n = cd.nx * cd.size;
-        memcpy (outEnd, cd.end, n * sizeof (unsigned short));
-        outEnd += n * sizeof (unsigned short);
-        cd.end += n;
-        }
-    }
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               #if defined (DEBUG)
+                   assert (cd.type == HALF);
+               #endif
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               int n = cd.nx * cd.size;
+               memcpy (outEnd, cd.end, n * sizeof (unsigned short));
+               outEnd += n * sizeof (unsigned short);
+               cd.end += n;
+           }
+       }
     }
 
     #if defined (DEBUG)
 
-    for (int i = 1; i < _numChans; ++i)
-        assert (_channelData[i-1].end == _channelData[i].start);
+       for (int i = 1; i < _numChans; ++i)
+           assert (_channelData[i-1].end == _channelData[i].start);
 
-    assert (_channelData[_numChans-1].end == tmpBufferEnd);
+       assert (_channelData[_numChans-1].end == tmpBufferEnd);
 
     #endif
 
     if (inSize > 0)
-    tooMuchData();
+       tooMuchData();
 
     outPtr = _outBuffer;
     return outEnd - _outBuffer;
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 809eebe..c84eaac 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
-
-namespace Imf {
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-class ChannelList;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class B44Compressor: public Compressor
 {
   public:
 
+    IMF_EXPORT
     B44Compressor (const Header &hdr,
                    size_t maxScanLineSize,
-           size_t numScanLines,
-           bool optFlatFields);
+                  size_t numScanLines,
+                  bool optFlatFields);
 
+    IMF_EXPORT
     virtual ~B44Compressor ();
 
+    IMF_EXPORT
     virtual int                numScanLines () const;
 
+    IMF_EXPORT
     virtual Format     format () const;
 
+    IMF_EXPORT
     virtual int                compress (const char *inPtr,
-                  int inSize,
-                  int minY,
-                  const char *&outPtr);
-
+                                 int inSize,
+                                 int minY,
+                                 const char *&outPtr);                  
+                  
+    IMF_EXPORT
     virtual int                compressTile (const char *inPtr,
-                      int inSize,
-                      Imath::Box2i range,
-                      const char *&outPtr);
+                                     int inSize,
+                                     IMATH_NAMESPACE::Box2i range,
+                                     const char *&outPtr);
 
+    IMF_EXPORT
     virtual int                uncompress (const char *inPtr,
-                    int inSize,
-                    int minY,
-                    const char *&outPtr);
-
+                                   int inSize,
+                                   int minY,
+                                   const char *&outPtr);
+                    
+    IMF_EXPORT
     virtual int                uncompressTile (const char *inPtr,
-                    int inSize,
-                    Imath::Box2i range,
-                    const char *&outPtr);
+                                       int inSize,
+                                       IMATH_NAMESPACE::Box2i range,
+                                       const char *&outPtr);
   private:
 
     struct ChannelData;
-
+    
     int                        compress (const char *inPtr,
-                  int inSize,
-                  Imath::Box2i range,
-                  const char *&outPtr);
-
+                                 int inSize,
+                                 IMATH_NAMESPACE::Box2i range,
+                                 const char *&outPtr);
     int                        uncompress (const char *inPtr,
-                    int inSize,
-                    Imath::Box2i range,
-                    const char *&outPtr);
+                                   int inSize,
+                                   IMATH_NAMESPACE::Box2i range,
+                                   const char *&outPtr);
 
     int                        _maxScanLineSize;
     bool               _optFlatFields;
@@ -112,6 +121,6 @@ class B44Compressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index fa839ee..6d44d0c 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -44,8 +44,9 @@
 #include <ImfBoxAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -57,7 +58,7 @@ Box2iAttribute::staticTypeName ()
 
 template <>
 void
-Box2iAttribute::writeValueTo (OStream &os, int) const
+Box2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.min.x);
     Xdr::write <StreamIO> (os, _value.min.y);
@@ -68,7 +69,7 @@ Box2iAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-Box2iAttribute::readValueFrom (IStream &is, int, int)
+Box2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.min.x);
     Xdr::read <StreamIO> (is, _value.min.y);
@@ -87,7 +88,7 @@ Box2fAttribute::staticTypeName ()
 
 template <>
 void
-Box2fAttribute::writeValueTo (OStream &os, int) const
+Box2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.min.x);
     Xdr::write <StreamIO> (os, _value.min.y);
@@ -98,7 +99,7 @@ Box2fAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-Box2fAttribute::readValueFrom (IStream &is, int, int)
+Box2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.min.x);
     Xdr::read <StreamIO> (is, _value.min.y);
@@ -107,4 +108,4 @@ Box2fAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index ca0f140..7bf2585 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfAttribute.h"
 #include "ImathBox.h"
+#include "ImfNamespace.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<IMATH_NAMESPACE::Box2i> Box2iAttribute;
 
-typedef TypedAttribute<Imath::Box2i> Box2iAttribute;
-template <> const char *Box2iAttribute::staticTypeName ();
-template <> void Box2iAttribute::writeValueTo (OStream &, int) const;
-template <> void Box2iAttribute::readValueFrom (IStream &, int, int);
+template <>
+IMF_EXPORT
+const char *Box2iAttribute::staticTypeName ();
+template <>
+IMF_EXPORT
+void Box2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                   int) const;
+template <>
+IMF_EXPORT
+void Box2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                    int, int);
 
 
-typedef TypedAttribute<Imath::Box2f> Box2fAttribute;
-template <> const char *Box2fAttribute::staticTypeName ();
-template <> void Box2fAttribute::writeValueTo (OStream &, int) const;
-template <> void Box2fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::Box2f> Box2fAttribute;
+template <>
+IMF_EXPORT
+const char *Box2fAttribute::staticTypeName ();
+template <>
+IMF_EXPORT
+void Box2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                   int) const;
+template <>
+IMF_EXPORT
+void Box2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                    int, int);
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfBoxAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 7312358..48363b4 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfChannelList.h>
 #include <ImfLut.h>
 #include "half.h"
+#include "ImfNamespace.h"
+#include "ImathForward.h"
+
 #include <string.h>
 
-using Imath::Box2i;
-using Imath::Box2f;
-using Imath::V2i;
-using Imath::V2f;
-using Imath::V3i;
-using Imath::V3f;
-using Imath::M33f;
-using Imath::M44f;
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::Box2f;
+using IMATH_NAMESPACE::V2i;
+using IMATH_NAMESPACE::V2f;
+using IMATH_NAMESPACE::V3i;
+using IMATH_NAMESPACE::V3f;
+using IMATH_NAMESPACE::M33f;
+using IMATH_NAMESPACE::M44f;
 
 
 namespace {
@@ -80,95 +84,95 @@ setErrorMessage (const std::exception &e)
 }
 
 
-inline Imf::Header *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::Header *
 header (ImfHeader *hdr)
 {
-    return (Imf::Header *)(hdr);
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::Header *)(hdr);
 }
 
 
-inline const Imf::Header *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::Header *
 header (const ImfHeader *hdr)
 {
-    return (const Imf::Header *)(hdr);
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::Header *)(hdr);
 }
 
 
-inline Imf::RgbaOutputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *
 outfile (ImfOutputFile *out)
 {
-    return (Imf::RgbaOutputFile *) out;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *) out;
 }
 
 
-inline const Imf::RgbaOutputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *
 outfile (const ImfOutputFile *out)
 {
-    return (const Imf::RgbaOutputFile *) out;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile *) out;
 }
 
 
-inline Imf::TiledRgbaOutputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *
 outfile (ImfTiledOutputFile *out)
 {
-    return (Imf::TiledRgbaOutputFile *) out;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *) out;
 }
 
 
-inline const Imf::TiledRgbaOutputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *
 outfile (const ImfTiledOutputFile *out)
 {
-    return (const Imf::TiledRgbaOutputFile *) out;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile *) out;
 }
 
 
-inline Imf::RgbaInputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *
 infile (ImfInputFile *in)
 {
-    return (Imf::RgbaInputFile *) in;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *) in;
 }
 
 
-inline const Imf::RgbaInputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *
 infile (const ImfInputFile *in)
 {
-    return (const Imf::RgbaInputFile *) in;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile *) in;
 }
 
 
-inline Imf::TiledRgbaInputFile *
+inline OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *
 infile (ImfTiledInputFile *in)
 {
-    return (Imf::TiledRgbaInputFile *) in;
+    return (OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *) in;
 }
 
 
-inline const Imf::TiledRgbaInputFile *
+inline const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *
 infile (const ImfTiledInputFile *in)
 {
-    return (const Imf::TiledRgbaInputFile *) in;
+    return (const OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile *) in;
 }
 
 
 } // namespace
 
 
-void
+void   
 ImfFloatToHalf (float f, ImfHalf *h)
 {
     *h = half(f).bits();
 }
 
 
-void
+void   
 ImfFloatToHalfArray (int n, const float f[/*n*/], ImfHalf h[/*n*/])
 {
     for (int i = 0; i < n; ++i)
-    h[i] = half(f[i]).bits();
+       h[i] = half(f[i]).bits();
 }
 
 
-float
+float  
 ImfHalfToFloat (ImfHalf h)
 {
     return float (*((half *)&h));
@@ -179,7 +183,7 @@ void
 ImfHalfToFloatArray (int n, const ImfHalf h[/*n*/], float f[/*n*/])
 {
     for (int i = 0; i < n; ++i)
-    f[i] = float (*((half *)(h + i)));
+       f[i] = float (*((half *)(h + i)));
 }
 
 
@@ -188,17 +192,17 @@ ImfNewHeader (void)
 {
     try
     {
-    return (ImfHeader *) new Imf::Header;
+       return (ImfHeader *) new OPENEXR_IMF_INTERNAL_NAMESPACE::Header;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-void
+void   
 ImfDeleteHeader (ImfHeader *hdr)
 {
     delete header (hdr);
@@ -210,29 +214,29 @@ ImfCopyHeader (const ImfHeader *hdr)
 {
     try
     {
-    return (ImfHeader *) new Imf::Header (*header (hdr));
+       return (ImfHeader *) new OPENEXR_IMF_INTERNAL_NAMESPACE::Header (*header (hdr));
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-void
+void   
 ImfHeaderSetDisplayWindow (ImfHeader *hdr,
-               int xMin, int yMin,
-               int xMax, int yMax)
+                          int xMin, int yMin,
+                          int xMax, int yMax)
 {
     header(hdr)->displayWindow() = Box2i (V2i (xMin, yMin), V2i (xMax, yMax));
 }
 
 
-void
+void   
 ImfHeaderDisplayWindow (const ImfHeader *hdr,
-            int *xMin, int *yMin,
-            int *xMax, int *yMax)
+                       int *xMin, int *yMin,
+                       int *xMax, int *yMax)
 {
     const Box2i dw = header(hdr)->displayWindow();
     *xMin = dw.min.x;
@@ -244,17 +248,17 @@ ImfHeaderDisplayWindow (const ImfHeader *hdr,
 
 void
 ImfHeaderSetDataWindow (ImfHeader *hdr,
-            int xMin, int yMin,
-            int xMax, int yMax)
+                       int xMin, int yMin,
+                       int xMax, int yMax)
 {
     header(hdr)->dataWindow() = Box2i (V2i (xMin, yMin), V2i (xMax, yMax));
 }
 
 
-void
+void   
 ImfHeaderDataWindow (const ImfHeader *hdr,
-             int *xMin, int *yMin,
-             int *xMax, int *yMax)
+                    int *xMin, int *yMin,
+                    int *xMax, int *yMax)
 {
     const Box2i dw = header(hdr)->dataWindow();
     *xMin = dw.min.x;
@@ -264,165 +268,165 @@ ImfHeaderDataWindow (const ImfHeader *hdr,
 }
 
 
-void
+void   
 ImfHeaderSetPixelAspectRatio (ImfHeader *hdr, float pixelAspectRatio)
 {
     header(hdr)->pixelAspectRatio() = pixelAspectRatio;
 }
 
 
-float
+float  
 ImfHeaderPixelAspectRatio (const ImfHeader *hdr)
 {
     return header(hdr)->pixelAspectRatio();
 }
 
 
-void
+void   
 ImfHeaderSetScreenWindowCenter (ImfHeader *hdr, float x, float y)
 {
     header(hdr)->screenWindowCenter() = V2f (x, y);
 }
 
 
-void
+void   
 ImfHeaderScreenWindowCenter (const ImfHeader *hdr, float *x, float *y)
 {
     const V2i &swc = header(hdr)->screenWindowCenter();
-    *x = swc.x;
-    *y = swc.y;
+    *x = (float) swc.x;
+    *y = (float) swc.y;
 }
 
 
-void
+void   
 ImfHeaderSetScreenWindowWidth (ImfHeader *hdr, float width)
 {
     header(hdr)->screenWindowWidth() = width;
 }
 
 
-float
+float  
 ImfHeaderScreenWindowWidth (const ImfHeader *hdr)
 {
     return header(hdr)->screenWindowWidth();
 }
 
 
-void
+void   
 ImfHeaderSetLineOrder (ImfHeader *hdr, int lineOrder)
 {
-    header(hdr)->lineOrder() = Imf::LineOrder (lineOrder);
+    header(hdr)->lineOrder() = OPENEXR_IMF_INTERNAL_NAMESPACE::LineOrder (lineOrder);
 }
 
 
-int
+int    
 ImfHeaderLineOrder (const ImfHeader *hdr)
 {
     return header(hdr)->lineOrder();
 }
 
-
-void
+                           
+void   
 ImfHeaderSetCompression (ImfHeader *hdr, int compression)
 {
-    header(hdr)->compression() = Imf::Compression (compression);
+    header(hdr)->compression() = OPENEXR_IMF_INTERNAL_NAMESPACE::Compression (compression);
 }
 
 
-int
+int    
 ImfHeaderCompression (const ImfHeader *hdr)
 {
     return header(hdr)->compression();
 }
 
 
-int
+int    
 ImfHeaderSetIntAttribute (ImfHeader *hdr, const char name[], int value)
 {
     try
     {
-    if (header(hdr)->find(name) == header(hdr)->end())
-    {
-        header(hdr)->insert (name, Imf::IntAttribute (value));
-    }
-    else
-    {
-        header(hdr)->typedAttribute<Imf::IntAttribute>(name).value() =
-        value;
-    }
+       if (header(hdr)->find(name) == header(hdr)->end())
+       {
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::IntAttribute (value));
+       }
+       else
+       {
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::IntAttribute>(name).value() =
+               value;
+       }
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int    
 ImfHeaderIntAttribute (const ImfHeader *hdr, const char name[], int *value)
 {
     try
     {
-    *value = header(hdr)->typedAttribute<Imf::IntAttribute>(name).value();
-    return 1;
+       *value = header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::IntAttribute>(name).value();
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int    
 ImfHeaderSetFloatAttribute (ImfHeader *hdr, const char name[], float value)
 {
     try
     {
-    if (header(hdr)->find(name) == header(hdr)->end())
-    {
-        header(hdr)->insert (name, Imf::FloatAttribute (value));
-    }
-    else
-    {
-        header(hdr)->typedAttribute<Imf::FloatAttribute>(name).value() =
-        value;
-    }
+       if (header(hdr)->find(name) == header(hdr)->end())
+       {
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::FloatAttribute (value));
+       }
+       else
+       {
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::FloatAttribute>(name).value() =
+               value;
+       }
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int    
 ImfHeaderSetDoubleAttribute (ImfHeader *hdr, const char name[], double value)
 {
     try
     {
-    if (header(hdr)->find(name) == header(hdr)->end())
-    {
-        header(hdr)->insert (name, Imf::DoubleAttribute (value));
-    }
-    else
-    {
-        header(hdr)->typedAttribute<Imf::DoubleAttribute>(name).value() =
-        value;
-    }
+       if (header(hdr)->find(name) == header(hdr)->end())
+       {
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::DoubleAttribute (value));
+       }
+       else
+       {
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::DoubleAttribute>(name).value() =
+               value;
+       }
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -432,569 +436,569 @@ ImfHeaderFloatAttribute (const ImfHeader *hdr, const char name[], float *value)
 {
     try
     {
-    *value = header(hdr)->typedAttribute<Imf::FloatAttribute>(name).value();
-    return 1;
+       *value = header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::FloatAttribute>(name).value();
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderDoubleAttribute (const ImfHeader *hdr,
-              const char name[],
-              double *value)
+                         const char name[],
+                         double *value)
 {
     try
     {
-    *value = header(hdr)->
-        typedAttribute<Imf::DoubleAttribute>(name).value();
+       *value = header(hdr)->
+           typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::DoubleAttribute>(name).value();
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetStringAttribute (ImfHeader *hdr,
-                 const char name[],
-                 const char value[])
+                            const char name[],
+                            const char value[])
 {
     try
     {
-    if (header(hdr)->find(name) == header(hdr)->end())
-    {
-        header(hdr)->insert (name, Imf::StringAttribute (value));
-    }
-    else
-    {
-        header(hdr)->typedAttribute<Imf::StringAttribute>(name).value() =
-        value;
-    }
+       if (header(hdr)->find(name) == header(hdr)->end())
+       {
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::StringAttribute (value));
+       }
+       else
+       {
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::StringAttribute>(name).value() =
+               value;
+       }
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderStringAttribute (const ImfHeader *hdr,
-              const char name[],
-              const char **value)
+                         const char name[],
+                         const char **value)
 {
     try
     {
-    *value = header(hdr)->
-        typedAttribute<Imf::StringAttribute>(name).value().c_str();
+       *value = header(hdr)->
+           typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::StringAttribute>(name).value().c_str();
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetBox2iAttribute (ImfHeader *hdr,
-                const char name[],
-                int xMin, int yMin,
-                int xMax, int yMax)
+                           const char name[],
+                           int xMin, int yMin,
+                           int xMax, int yMax)
 {
     try
     {
-    Box2i box (V2i (xMin, yMin), V2i (xMax, yMax));
+       Box2i box (V2i (xMin, yMin), V2i (xMax, yMax));
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-    {
-        header(hdr)->insert (name, Imf::Box2iAttribute (box));
-    }
-    else
-    {
-        header(hdr)->typedAttribute<Imf::Box2iAttribute>(name).value() =
-        box;
-    }
+       if (header(hdr)->find(name) == header(hdr)->end())
+       {
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::Box2iAttribute (box));
+       }
+       else
+       {
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2iAttribute>(name).value() =
+               box;
+       }
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderBox2iAttribute (const ImfHeader *hdr,
-             const char name[],
-             int *xMin, int *yMin,
-             int *xMax, int *yMax)
+                        const char name[],
+                        int *xMin, int *yMin,
+                        int *xMax, int *yMax)
 {
     try
     {
-    const Box2i &box =
-        header(hdr)->typedAttribute<Imf::Box2iAttribute>(name).value();
+       const Box2i &box =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2iAttribute>(name).value();
 
-    *xMin = box.min.x;
-    *yMin = box.min.y;
-    *xMax = box.max.x;
-    *yMax = box.max.y;
+       *xMin = box.min.x;
+       *yMin = box.min.y;
+       *xMax = box.max.x;
+       *yMax = box.max.y;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetBox2fAttribute (ImfHeader *hdr,
-                const char name[],
-                float xMin, float yMin,
-                float xMax, float yMax)
+                           const char name[],
+                           float xMin, float yMin,
+                           float xMax, float yMax)
 {
     try
     {
-    Box2f box (V2f (xMin, yMin), V2f (xMax, yMax));
+       Box2f box (V2f (xMin, yMin), V2f (xMax, yMax));
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-    {
-        header(hdr)->insert (name, Imf::Box2fAttribute (box));
-    }
-    else
-    {
-        header(hdr)->typedAttribute<Imf::Box2fAttribute>(name).value() =
-        box;
-    }
+       if (header(hdr)->find(name) == header(hdr)->end())
+       {
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::Box2fAttribute (box));
+       }
+       else
+       {
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2fAttribute>(name).value() =
+               box;
+       }
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderBox2fAttribute (const ImfHeader *hdr,
-             const char name[],
-             float *xMin, float *yMin,
-             float *xMax, float *yMax)
+                        const char name[],
+                        float *xMin, float *yMin,
+                        float *xMax, float *yMax)
 {
     try
     {
-    const Box2f &box =
-        header(hdr)->typedAttribute<Imf::Box2fAttribute>(name).value();
+       const Box2f &box =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Box2fAttribute>(name).value();
 
-    *xMin = box.min.x;
-    *yMin = box.min.y;
-    *xMax = box.max.x;
-    *yMax = box.max.y;
+       *xMin = box.min.x;
+       *yMin = box.min.y;
+       *xMax = box.max.x;
+       *yMax = box.max.y;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetV2iAttribute (ImfHeader *hdr,
-              const char name[],
-              int x, int y)
+                         const char name[],
+                         int x, int y)
 {
     try
     {
-    V2i v (x, y);
+       V2i v (x, y);
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-        header(hdr)->insert (name, Imf::V2iAttribute (v));
-    else
-        header(hdr)->typedAttribute<Imf::V2iAttribute>(name).value() = v;
+       if (header(hdr)->find(name) == header(hdr)->end())
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V2iAttribute (v));
+       else
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2iAttribute>(name).value() = v;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderV2iAttribute (const ImfHeader *hdr,
-               const char name[],
-               int *x, int *y)
+                      const char name[],
+                      int *x, int *y)
 {
     try
     {
-    const V2i &v =
-        header(hdr)->typedAttribute<Imf::V2iAttribute>(name).value();
+       const V2i &v =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2iAttribute>(name).value();
 
-    *x = v.x;
-    *y = v.y;
+       *x = v.x;
+       *y = v.y;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int    
 ImfHeaderSetV2fAttribute (ImfHeader *hdr,
-              const char name[],
-              float x, float y)
+                         const char name[],
+                         float x, float y)
 {
     try
     {
-    V2f v (x, y);
+       V2f v (x, y);
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-        header(hdr)->insert (name, Imf::V2fAttribute (v));
-    else
-        header(hdr)->typedAttribute<Imf::V2fAttribute>(name).value() = v;
+       if (header(hdr)->find(name) == header(hdr)->end())
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V2fAttribute (v));
+       else
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2fAttribute>(name).value() = v;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderV2fAttribute (const ImfHeader *hdr,
-               const char name[],
-               float *x, float *y)
+                      const char name[],
+                      float *x, float *y)
 {
     try
     {
-    const V2f &v =
-        header(hdr)->typedAttribute<Imf::V2fAttribute>(name).value();
+       const V2f &v =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V2fAttribute>(name).value();
 
-    *x = v.x;
-    *y = v.y;
+       *x = v.x;
+       *y = v.y;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetV3iAttribute (ImfHeader *hdr,
-              const char name[],
-              int x, int y, int z)
+                         const char name[],
+                         int x, int y, int z)
 {
     try
     {
-    V3i v (x, y, z);
+       V3i v (x, y, z);
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-        header(hdr)->insert (name, Imf::V3iAttribute (v));
-    else
-        header(hdr)->typedAttribute<Imf::V3iAttribute>(name).value() = v;
+       if (header(hdr)->find(name) == header(hdr)->end())
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V3iAttribute (v));
+       else
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3iAttribute>(name).value() = v;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderV3iAttribute (const ImfHeader *hdr,
-               const char name[],
-               int *x, int *y, int *z)
+                      const char name[],
+                      int *x, int *y, int *z)
 {
     try
     {
-    const V3i &v =
-        header(hdr)->typedAttribute<Imf::V3iAttribute>(name).value();
+       const V3i &v =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3iAttribute>(name).value();
 
-    *x = v.x;
-    *y = v.y;
-    *z = v.z;
+       *x = v.x;
+       *y = v.y;
+       *z = v.z;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetV3fAttribute (ImfHeader *hdr,
-              const char name[],
-              float x, float y, float z)
+                         const char name[],
+                         float x, float y, float z)
 {
     try
     {
-    V3f v (x, y, z);
+       V3f v (x, y, z);
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-        header(hdr)->insert (name, Imf::V3fAttribute (v));
-    else
-        header(hdr)->typedAttribute<Imf::V3fAttribute>(name).value() = v;
+       if (header(hdr)->find(name) == header(hdr)->end())
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::V3fAttribute (v));
+       else
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3fAttribute>(name).value() = v;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderV3fAttribute (const ImfHeader *hdr,
-               const char name[],
-               float *x, float *y, float *z)
+                      const char name[],
+                      float *x, float *y, float *z)
 {
     try
     {
-    const V3f &v =
-        header(hdr)->typedAttribute<Imf::V3fAttribute>(name).value();
+       const V3f &v =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::V3fAttribute>(name).value();
 
-    *x = v.x;
-    *y = v.y;
-    *z = v.z;
+       *x = v.x;
+       *y = v.y;
+       *z = v.z;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetM33fAttribute (ImfHeader *hdr,
-               const char name[],
-               const float m[3][3])
+                          const char name[],
+                          const float m[3][3])
 {
     try
     {
-    M33f m3 (m);
+       M33f m3 (m);
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-        header(hdr)->insert (name, Imf::M33fAttribute (m3));
-    else
-        header(hdr)->typedAttribute<Imf::M33fAttribute>(name).value() = m3;
+       if (header(hdr)->find(name) == header(hdr)->end())
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::M33fAttribute (m3));
+       else
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M33fAttribute>(name).value() = m3;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderM33fAttribute (const ImfHeader *hdr,
-            const char name[],
-            float m[3][3])
+                       const char name[],
+                       float m[3][3])
 {
     try
     {
-    const M33f &m3 =
-        header(hdr)->typedAttribute<Imf::M33fAttribute>(name).value();
+       const M33f &m3 =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M33fAttribute>(name).value();
 
-    m[0][0] = m3[0][0];
-    m[0][1] = m3[0][1];
-    m[0][2] = m3[0][2];
+       m[0][0] = m3[0][0];
+       m[0][1] = m3[0][1];
+       m[0][2] = m3[0][2];
 
-    m[1][0] = m3[1][0];
-    m[1][1] = m3[1][1];
-    m[1][2] = m3[1][2];
+       m[1][0] = m3[1][0];
+       m[1][1] = m3[1][1];
+       m[1][2] = m3[1][2];
 
-    m[2][0] = m3[2][0];
-    m[2][1] = m3[2][1];
-    m[2][2] = m3[2][2];
+       m[2][0] = m3[2][0];
+       m[2][1] = m3[2][1];
+       m[2][2] = m3[2][2];
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderSetM44fAttribute (ImfHeader *hdr,
-               const char name[],
-               const float m[4][4])
+                          const char name[],
+                          const float m[4][4])
 {
     try
     {
-    M44f m4 (m);
+       M44f m4 (m);
 
-    if (header(hdr)->find(name) == header(hdr)->end())
-        header(hdr)->insert (name, Imf::M44fAttribute (m4));
-    else
-        header(hdr)->typedAttribute<Imf::M44fAttribute>(name).value() = m4;
+       if (header(hdr)->find(name) == header(hdr)->end())
+           header(hdr)->insert (name, OPENEXR_IMF_INTERNAL_NAMESPACE::M44fAttribute (m4));
+       else
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M44fAttribute>(name).value() = m4;
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfHeaderM44fAttribute (const ImfHeader *hdr,
-            const char name[],
-            float m[4][4])
+                       const char name[],
+                       float m[4][4])
 {
     try
     {
-    const M44f &m4 =
-        header(hdr)->typedAttribute<Imf::M44fAttribute>(name).value();
+       const M44f &m4 =
+           header(hdr)->typedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::M44fAttribute>(name).value();
 
-    m[0][0] = m4[0][0];
-    m[0][1] = m4[0][1];
-    m[0][2] = m4[0][2];
-    m[0][3] = m4[0][3];
+       m[0][0] = m4[0][0];
+       m[0][1] = m4[0][1];
+       m[0][2] = m4[0][2];
+       m[0][3] = m4[0][3];
 
-    m[1][0] = m4[1][0];
-    m[1][1] = m4[1][1];
-    m[1][2] = m4[1][2];
-    m[1][3] = m4[1][3];
+       m[1][0] = m4[1][0];
+       m[1][1] = m4[1][1];
+       m[1][2] = m4[1][2];
+       m[1][3] = m4[1][3];
 
-    m[2][0] = m4[2][0];
-    m[2][1] = m4[2][1];
-    m[2][2] = m4[2][2];
-    m[2][3] = m4[2][3];
+       m[2][0] = m4[2][0];
+       m[2][1] = m4[2][1];
+       m[2][2] = m4[2][2];
+       m[2][3] = m4[2][3];
 
-    m[3][0] = m4[3][0];
-    m[3][1] = m4[3][1];
-    m[3][2] = m4[3][2];
-    m[3][3] = m4[3][3];
+       m[3][0] = m4[3][0];
+       m[3][1] = m4[3][1];
+       m[3][2] = m4[3][2];
+       m[3][3] = m4[3][3];
 
-    return 1;
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-ImfOutputFile *
+ImfOutputFile *        
 ImfOpenOutputFile (const char name[], const ImfHeader *hdr, int channels)
 {
     try
     {
-    return (ImfOutputFile *) new Imf::RgbaOutputFile
-        (name, *header(hdr), Imf::RgbaChannels (channels));
+       return (ImfOutputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaOutputFile
+           (name, *header(hdr), OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels));
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfCloseOutputFile (ImfOutputFile *out)
 {
     try
     {
-    delete outfile (out);
-    return 1;
+       delete outfile (out);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfOutputSetFrameBuffer (ImfOutputFile *out,
-             const ImfRgba *base,
-             size_t xStride,
-             size_t yStride)
+                        const ImfRgba *base,
+                        size_t xStride,
+                        size_t yStride)
 {
     try
     {
-    outfile(out)->setFrameBuffer ((Imf::Rgba *)base, xStride, yStride);
-    return 1;
+       outfile(out)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *)base, xStride, yStride);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfOutputWritePixels (ImfOutputFile *out, int numScanLines)
 {
     try
     {
-    outfile(out)->writePixels (numScanLines);
-    return 1;
+       outfile(out)->writePixels (numScanLines);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1020,98 +1024,98 @@ ImfOutputChannels (const ImfOutputFile *out)
 }
 
 
-ImfTiledOutputFile *
+ImfTiledOutputFile *   
 ImfOpenTiledOutputFile (const char name[],
-            const ImfHeader *hdr,
-            int channels,
-            int xSize, int ySize,
-            int mode, int rmode)
+                       const ImfHeader *hdr,
+                       int channels,
+                       int xSize, int ySize,
+                       int mode, int rmode)
 {
     try
     {
-    return (ImfTiledOutputFile *) new Imf::TiledRgbaOutputFile
-            (name, *header(hdr),
-             Imf::RgbaChannels (channels),
-             xSize, ySize,
-             Imf::LevelMode (mode),
-             Imf::LevelRoundingMode (rmode));
+       return (ImfTiledOutputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaOutputFile
+                   (name, *header(hdr),
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels),
+                    xSize, ySize,
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::LevelMode (mode),
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::LevelRoundingMode (rmode));
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfCloseTiledOutputFile (ImfTiledOutputFile *out)
 {
     try
     {
-    delete outfile (out);
-    return 1;
+       delete outfile (out);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfTiledOutputSetFrameBuffer (ImfTiledOutputFile *out,
-                  const ImfRgba *base,
-                  size_t xStride,
-                  size_t yStride)
+                             const ImfRgba *base,
+                             size_t xStride,
+                             size_t yStride)
 {
     try
     {
-    outfile(out)->setFrameBuffer ((Imf::Rgba *)base, xStride, yStride);
-    return 1;
+       outfile(out)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *)base, xStride, yStride);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfTiledOutputWriteTile (ImfTiledOutputFile *out,
-             int dx, int dy,
-             int lx, int ly)
+                        int dx, int dy,
+                        int lx, int ly)
 {
     try
     {
-    outfile(out)->writeTile (dx, dy, lx, ly);
-    return 1;
+       outfile(out)->writeTile (dx, dy, lx, ly);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfTiledOutputWriteTiles (ImfTiledOutputFile *out,
-              int dxMin, int dxMax,
+                         int dxMin, int dxMax,
                           int dyMin, int dyMax,
-              int lx, int ly)
+                         int lx, int ly)
 {
     try
     {
-    outfile(out)->writeTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
-    return 1;
+       outfile(out)->writeTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1158,17 +1162,17 @@ ImfTiledOutputLevelRoundingMode (const ImfTiledOutputFile *out)
 }
 
 
-ImfInputFile *
+ImfInputFile * 
 ImfOpenInputFile (const char name[])
 {
     try
     {
-    return (ImfInputFile *) new Imf::RgbaInputFile (name);
+       return (ImfInputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaInputFile (name);
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1178,32 +1182,32 @@ ImfCloseInputFile (ImfInputFile *in)
 {
     try
     {
-    delete infile (in);
-    return 1;
+       delete infile (in);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfInputSetFrameBuffer (ImfInputFile *in,
-            ImfRgba *base,
-            size_t xStride,
-            size_t yStride)
+                       ImfRgba *base,
+                       size_t xStride,
+                       size_t yStride)
 {
     try
     {
-    infile(in)->setFrameBuffer ((Imf::Rgba *) base, xStride, yStride);
-    return 1;
+       infile(in)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *) base, xStride, yStride);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1213,13 +1217,13 @@ ImfInputReadPixels (ImfInputFile *in, int scanLine1, int scanLine2)
 {
     try
     {
-    infile(in)->readPixels (scanLine1, scanLine2);
-    return 1;
+       infile(in)->readPixels (scanLine1, scanLine2);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1245,17 +1249,17 @@ ImfInputFileName (const ImfInputFile *in)
 }
 
 
-ImfTiledInputFile *
+ImfTiledInputFile *    
 ImfOpenTiledInputFile (const char name[])
 {
     try
     {
-    return (ImfTiledInputFile *) new Imf::TiledRgbaInputFile (name);
+       return (ImfTiledInputFile *) new OPENEXR_IMF_INTERNAL_NAMESPACE::TiledRgbaInputFile (name);
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1265,69 +1269,69 @@ ImfCloseTiledInputFile (ImfTiledInputFile *in)
 {
     try
     {
-    delete infile (in);
-    return 1;
+       delete infile (in);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
-int
+int            
 ImfTiledInputSetFrameBuffer (ImfTiledInputFile *in,
-                 ImfRgba *base,
-                 size_t xStride,
-                 size_t yStride)
+                            ImfRgba *base,
+                            size_t xStride,
+                            size_t yStride)
 {
     try
     {
-    infile(in)->setFrameBuffer ((Imf::Rgba *) base, xStride, yStride);
-    return 1;
+       infile(in)->setFrameBuffer ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *) base, xStride, yStride);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfTiledInputReadTile (ImfTiledInputFile *in,
-               int dx, int dy,
-               int lx, int ly)
+                      int dx, int dy,
+                      int lx, int ly)
 {
     try
     {
-    infile(in)->readTile (dx, dy, lx, ly);
-    return 1;
+       infile(in)->readTile (dx, dy, lx, ly);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
 
 int
 ImfTiledInputReadTiles (ImfTiledInputFile *in,
-                int dxMin, int dxMax,
+                       int dxMin, int dxMax,
                         int dyMin, int dyMax,
-                int lx, int ly)
+                       int lx, int ly)
 {
     try
     {
-    infile(in)->readTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
-    return 1;
+       infile(in)->readTiles (dxMin, dxMax, dyMin, dyMax, lx, ly);
+       return 1;
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1386,13 +1390,13 @@ ImfNewRound12logLut (int channels)
 {
     try
     {
-    return (ImfLut *) new Imf::RgbaLut
-        (Imf::round12log, Imf::RgbaChannels (channels));
+       return (ImfLut *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut
+           (OPENEXR_IMF_INTERNAL_NAMESPACE::round12log, OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels));
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1402,13 +1406,13 @@ ImfNewRoundNBitLut (unsigned int n, int channels)
 {
     try
     {
-    return (ImfLut *) new Imf::RgbaLut
-        (Imf::roundNBit (n), Imf::RgbaChannels (channels));
+       return (ImfLut *) new OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut
+           (OPENEXR_IMF_INTERNAL_NAMESPACE::roundNBit (n), OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaChannels (channels));
     }
     catch (const std::exception &e)
     {
-    setErrorMessage (e);
-    return 0;
+       setErrorMessage (e);
+       return 0;
     }
 }
 
@@ -1416,18 +1420,18 @@ ImfNewRoundNBitLut (unsigned int n, int channels)
 void
 ImfDeleteLut (ImfLut *lut)
 {
-    delete (Imf::RgbaLut *) lut;
+    delete (OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut *) lut;
 }
 
 
 void
 ImfApplyLut (ImfLut *lut, ImfRgba *data, int nData, int stride)
 {
-    ((Imf::RgbaLut *)lut)->apply ((Imf::Rgba *)data, nData, stride);
+    ((OPENEXR_IMF_INTERNAL_NAMESPACE::RgbaLut *)lut)->apply ((OPENEXR_IMF_INTERNAL_NAMESPACE::Rgba *)data, nData, stride);
 }
 
 
-const char *
+const char *   
 ImfErrorMessage ()
 {
     return errorMessage;
index 7921069..db58247 100644 (file)
@@ -16,7 +16,7 @@ in the documentation and/or other materials provided with the
 distribution.
 *       Neither the name of Industrial Light & Magic nor the names of
 its contributors may be used to endorse or promote products derived
-from this software without specific prior written permission.
+from this software without specific prior written permission. 
 
 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
@@ -35,6 +35,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #ifndef INCLUDED_IMF_C_RGBA_FILE_H
 #define INCLUDED_IMF_C_RGBA_FILE_H
 
+#include "ImfExport.h"
 
 #include <stdlib.h>
 
@@ -48,18 +49,22 @@ extern "C" {
 
 typedef unsigned short ImfHalf;
 
+IMF_EXPORT 
 void   ImfFloatToHalf (float f,
-            ImfHalf *h);
+                       ImfHalf *h);
 
+IMF_EXPORT 
 void   ImfFloatToHalfArray (int n,
-                const float f[/*n*/],
-                ImfHalf h[/*n*/]);
+                           const float f[/*n*/],
+                           ImfHalf h[/*n*/]);
 
+IMF_EXPORT 
 float  ImfHalfToFloat (ImfHalf h);
 
+IMF_EXPORT 
 void   ImfHalfToFloatArray (int n,
-                const ImfHalf h[/*n*/],
-                float f[/*n*/]);
+                           const ImfHalf h[/*n*/],
+                           float f[/*n*/]);
 
 /*
 ** RGBA pixel; memory layout must be the same as struct Imf::Rgba.
@@ -93,7 +98,7 @@ typedef struct ImfRgba ImfRgba;
 
 #define IMF_INCREASING_Y       0
 #define IMF_DECREASING_Y       1
-#define IMF_RAMDOM_Y           2
+#define IMF_RANDOM_Y           2
 
 
 /*
@@ -151,153 +156,194 @@ typedef struct ImfRgba ImfRgba;
 struct ImfHeader;
 typedef struct ImfHeader ImfHeader;
 
+IMF_EXPORT 
 ImfHeader *    ImfNewHeader (void);
 
+IMF_EXPORT 
 void           ImfDeleteHeader (ImfHeader *hdr);
 
+IMF_EXPORT 
 ImfHeader *    ImfCopyHeader (const ImfHeader *hdr);
 
+IMF_EXPORT 
 void           ImfHeaderSetDisplayWindow (ImfHeader *hdr,
-                       int xMin, int yMin,
-                       int xMax, int yMax);
+                                          int xMin, int yMin,
+                                          int xMax, int yMax);
 
+IMF_EXPORT 
 void           ImfHeaderDisplayWindow (const ImfHeader *hdr,
-                    int *xMin, int *yMin,
-                    int *xMax, int *yMax);
+                                       int *xMin, int *yMin,
+                                       int *xMax, int *yMax);
 
+IMF_EXPORT 
 void           ImfHeaderSetDataWindow (ImfHeader *hdr,
-                    int xMin, int yMin,
-                    int xMax, int yMax);
+                                       int xMin, int yMin,
+                                       int xMax, int yMax);
 
+IMF_EXPORT 
 void           ImfHeaderDataWindow (const ImfHeader *hdr,
-                     int *xMin, int *yMin,
-                     int *xMax, int *yMax);
+                                    int *xMin, int *yMin,
+                                    int *xMax, int *yMax);
 
+IMF_EXPORT 
 void           ImfHeaderSetPixelAspectRatio (ImfHeader *hdr,
-                          float pixelAspectRatio);
+                                             float pixelAspectRatio);
 
+IMF_EXPORT 
 float          ImfHeaderPixelAspectRatio (const ImfHeader *hdr);
 
+IMF_EXPORT 
 void           ImfHeaderSetScreenWindowCenter (ImfHeader *hdr,
-                        float x, float y);
+                                               float x, float y);
 
+IMF_EXPORT 
 void           ImfHeaderScreenWindowCenter (const ImfHeader *hdr,
-                         float *x, float *y);
+                                            float *x, float *y);
 
+IMF_EXPORT 
 void           ImfHeaderSetScreenWindowWidth (ImfHeader *hdr,
-                           float width);
+                                              float width);
 
+IMF_EXPORT 
 float          ImfHeaderScreenWindowWidth (const ImfHeader *hdr);
 
+IMF_EXPORT 
 void           ImfHeaderSetLineOrder (ImfHeader *hdr,
-                       int lineOrder);
+                                      int lineOrder);
 
+IMF_EXPORT 
 int            ImfHeaderLineOrder (const ImfHeader *hdr);
-
+                           
+IMF_EXPORT 
 void           ImfHeaderSetCompression (ImfHeader *hdr,
-                     int compression);
+                                        int compression);
 
+IMF_EXPORT 
 int            ImfHeaderCompression (const ImfHeader *hdr);
 
+IMF_EXPORT 
 int            ImfHeaderSetIntAttribute (ImfHeader *hdr,
-                      const char name[],
-                      int value);
+                                         const char name[],
+                                         int value);
 
+IMF_EXPORT 
 int            ImfHeaderIntAttribute (const ImfHeader *hdr,
-                       const char name[],
-                       int *value);
+                                      const char name[],
+                                      int *value);
 
+IMF_EXPORT 
 int            ImfHeaderSetFloatAttribute (ImfHeader *hdr,
-                        const char name[],
-                        float value);
+                                           const char name[],
+                                           float value);
 
+IMF_EXPORT 
 int            ImfHeaderSetDoubleAttribute (ImfHeader *hdr,
-                         const char name[],
-                         double value);
+                                            const char name[],
+                                            double value);
 
+IMF_EXPORT 
 int            ImfHeaderFloatAttribute (const ImfHeader *hdr,
-                         const char name[],
-                         float *value);
+                                        const char name[],
+                                        float *value);
 
+IMF_EXPORT 
 int            ImfHeaderDoubleAttribute (const ImfHeader *hdr,
-                          const char name[],
-                          double *value);
+                                         const char name[],
+                                         double *value);
 
+IMF_EXPORT 
 int            ImfHeaderSetStringAttribute (ImfHeader *hdr,
-                         const char name[],
-                         const char value[]);
+                                            const char name[],
+                                            const char value[]);
 
+IMF_EXPORT 
 int            ImfHeaderStringAttribute (const ImfHeader *hdr,
-                         const char name[],
-                      const char **value);
+                                        const char name[],
+                                         const char **value);
 
+IMF_EXPORT 
 int            ImfHeaderSetBox2iAttribute (ImfHeader *hdr,
-                        const char name[],
-                        int xMin, int yMin,
-                        int xMax, int yMax);
+                                           const char name[],
+                                           int xMin, int yMin,
+                                           int xMax, int yMax);
 
+IMF_EXPORT 
 int            ImfHeaderBox2iAttribute (const ImfHeader *hdr,
-                     const char name[],
-                     int *xMin, int *yMin,
-                     int *xMax, int *yMax);
+                                        const char name[],
+                                        int *xMin, int *yMin,
+                                        int *xMax, int *yMax);
 
+IMF_EXPORT 
 int            ImfHeaderSetBox2fAttribute (ImfHeader *hdr,
-                        const char name[],
-                        float xMin, float yMin,
-                        float xMax, float yMax);
+                                           const char name[],
+                                           float xMin, float yMin,
+                                           float xMax, float yMax);
 
+IMF_EXPORT 
 int            ImfHeaderBox2fAttribute (const ImfHeader *hdr,
-                     const char name[],
-                     float *xMin, float *yMin,
-                     float *xMax, float *yMax);
+                                        const char name[],
+                                        float *xMin, float *yMin,
+                                        float *xMax, float *yMax);
 
+IMF_EXPORT 
 int            ImfHeaderSetV2iAttribute (ImfHeader *hdr,
-                         const char name[],
-                         int x, int y);
+                                        const char name[],
+                                        int x, int y);
 
+IMF_EXPORT 
 int            ImfHeaderV2iAttribute (const ImfHeader *hdr,
-                       const char name[],
-                       int *x, int *y);
+                                      const char name[],
+                                      int *x, int *y);
 
+IMF_EXPORT 
 int            ImfHeaderSetV2fAttribute (ImfHeader *hdr,
-                          const char name[],
-                          float x, float y);
+                                         const char name[],
+                                         float x, float y);
 
+IMF_EXPORT 
 int            ImfHeaderV2fAttribute (const ImfHeader *hdr,
-                       const char name[],
-                       float *x, float *y);
+                                      const char name[],
+                                      float *x, float *y);
 
+IMF_EXPORT 
 int            ImfHeaderSetV3iAttribute (ImfHeader *hdr,
-                          const char name[],
-                          int x, int y, int z);
+                                         const char name[],
+                                         int x, int y, int z);
 
+IMF_EXPORT 
 int            ImfHeaderV3iAttribute (const ImfHeader *hdr,
-                       const char name[],
-                       int *x, int *y, int *z);
+                                      const char name[],
+                                      int *x, int *y, int *z);
 
+IMF_EXPORT 
 int            ImfHeaderSetV3fAttribute (ImfHeader *hdr,
-                          const char name[],
-                          float x, float y, float z);
+                                         const char name[],
+                                         float x, float y, float z);
 
+IMF_EXPORT 
 int            ImfHeaderV3fAttribute (const ImfHeader *hdr,
-                       const char name[],
-                       float *x, float *y, float *z);
+                                      const char name[],
+                                      float *x, float *y, float *z);
 
+IMF_EXPORT 
 int            ImfHeaderSetM33fAttribute (ImfHeader *hdr,
-                       const char name[],
-                       const float m[3][3]);
+                                          const char name[],
+                                          const float m[3][3]);
 
+IMF_EXPORT 
 int            ImfHeaderM33fAttribute (const ImfHeader *hdr,
-                    const char name[],
-                    float m[3][3]);
+                                       const char name[],
+                                       float m[3][3]);
 
+IMF_EXPORT 
 int            ImfHeaderSetM44fAttribute (ImfHeader *hdr,
-                       const char name[],
-                       const float m[4][4]);
+                                          const char name[],
+                                          const float m[4][4]);
 
+IMF_EXPORT 
 int            ImfHeaderM44fAttribute (const ImfHeader *hdr,
-                    const char name[],
-                    float m[4][4]);
+                                       const char name[],
+                                       float m[4][4]);
 
 /*
 ** RGBA output file
@@ -306,24 +352,31 @@ int               ImfHeaderM44fAttribute (const ImfHeader *hdr,
 struct ImfOutputFile;
 typedef struct ImfOutputFile ImfOutputFile;
 
+IMF_EXPORT 
 ImfOutputFile *        ImfOpenOutputFile (const char name[],
-                   const ImfHeader *hdr,
-                   int channels);
+                                  const ImfHeader *hdr,
+                                  int channels);
 
+IMF_EXPORT 
 int                    ImfCloseOutputFile (ImfOutputFile *out);
 
+IMF_EXPORT 
 int                    ImfOutputSetFrameBuffer (ImfOutputFile *out,
-                         const ImfRgba *base,
-                         size_t xStride,
-                         size_t yStride);
+                                                const ImfRgba *base,
+                                                size_t xStride,
+                                                size_t yStride);
 
+IMF_EXPORT 
 int                    ImfOutputWritePixels (ImfOutputFile *out,
-                          int numScanLines);
+                                             int numScanLines);
 
+IMF_EXPORT 
 int                    ImfOutputCurrentScanLine (const ImfOutputFile *out);
 
+IMF_EXPORT 
 const ImfHeader *      ImfOutputHeader (const ImfOutputFile *out);
 
+IMF_EXPORT 
 int                    ImfOutputChannels (const ImfOutputFile *out);
 
 
@@ -334,39 +387,51 @@ int                       ImfOutputChannels (const ImfOutputFile *out);
 struct ImfTiledOutputFile;
 typedef struct ImfTiledOutputFile ImfTiledOutputFile;
 
+IMF_EXPORT 
 ImfTiledOutputFile *   ImfOpenTiledOutputFile (const char name[],
-                            const ImfHeader *hdr,
-                        int channels,
-                        int xSize, int ySize,
-                        int mode, int rmode);
+                                               const ImfHeader *hdr,
+                                               int channels,
+                                               int xSize, int ySize,
+                                               int mode, int rmode);
 
+IMF_EXPORT 
 int            ImfCloseTiledOutputFile (ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int            ImfTiledOutputSetFrameBuffer (ImfTiledOutputFile *out,
-                          const ImfRgba *base,
-                          size_t xStride,
-                          size_t yStride);
+                                             const ImfRgba *base,
+                                             size_t xStride,
+                                             size_t yStride);
 
+IMF_EXPORT 
 int            ImfTiledOutputWriteTile (ImfTiledOutputFile *out,
-                     int dx, int dy,
-                     int lx, int ly);
+                                        int dx, int dy,
+                                        int lx, int ly);
 
+IMF_EXPORT 
 int             ImfTiledOutputWriteTiles (ImfTiledOutputFile *out,
                                           int dxMin, int dxMax,
                                           int dyMin, int dyMax,
                                           int lx, int ly);
 
+IMF_EXPORT 
 const ImfHeader *      ImfTiledOutputHeader (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int            ImfTiledOutputChannels (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int            ImfTiledOutputTileXSize (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int            ImfTiledOutputTileYSize (const ImfTiledOutputFile *out);
 
+IMF_EXPORT 
 int            ImfTiledOutputLevelMode (const ImfTiledOutputFile *out);
+
+IMF_EXPORT 
 int            ImfTiledOutputLevelRoundingMode
-                        (const ImfTiledOutputFile *out);
+                                               (const ImfTiledOutputFile *out);
 
 
 /*
@@ -378,21 +443,27 @@ typedef struct ImfInputFile ImfInputFile;
 
 ImfInputFile *         ImfOpenInputFile (const char name[]);
 
+IMF_EXPORT 
 int                    ImfCloseInputFile (ImfInputFile *in);
 
+IMF_EXPORT 
 int                    ImfInputSetFrameBuffer (ImfInputFile *in,
-                        ImfRgba *base,
-                        size_t xStride,
-                        size_t yStride);
+                                               ImfRgba *base,
+                                               size_t xStride,
+                                               size_t yStride);
 
+IMF_EXPORT 
 int                    ImfInputReadPixels (ImfInputFile *in,
-                        int scanLine1,
-                        int scanLine2);
+                                           int scanLine1,
+                                           int scanLine2);
 
+IMF_EXPORT 
 const ImfHeader *      ImfInputHeader (const ImfInputFile *in);
 
+IMF_EXPORT 
 int                    ImfInputChannels (const ImfInputFile *in);
 
+IMF_EXPORT 
 const char *            ImfInputFileName (const ImfInputFile *in);
 
 
@@ -403,38 +474,50 @@ const char *            ImfInputFileName (const ImfInputFile *in);
 struct ImfTiledInputFile;
 typedef struct ImfTiledInputFile ImfTiledInputFile;
 
+IMF_EXPORT 
 ImfTiledInputFile *    ImfOpenTiledInputFile (const char name[]);
 
+IMF_EXPORT 
 int            ImfCloseTiledInputFile (ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int            ImfTiledInputSetFrameBuffer (ImfTiledInputFile *in,
-                         ImfRgba *base,
-                         size_t xStride,
-                         size_t yStride);
+                                            ImfRgba *base,
+                                            size_t xStride,
+                                            size_t yStride);
 
+IMF_EXPORT 
 int            ImfTiledInputReadTile (ImfTiledInputFile *in,
-                       int dx, int dy,
-                       int lx, int ly);
+                                      int dx, int dy,
+                                      int lx, int ly);
 
+IMF_EXPORT 
 int            ImfTiledInputReadTiles (ImfTiledInputFile *in,
                                         int dxMin, int dxMax,
                                         int dyMin, int dyMax,
                                         int lx, int ly);
 
+IMF_EXPORT 
 const ImfHeader *      ImfTiledInputHeader (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int            ImfTiledInputChannels (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 const char *           ImfTiledInputFileName (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int            ImfTiledInputTileXSize (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int            ImfTiledInputTileYSize (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int            ImfTiledInputLevelMode (const ImfTiledInputFile *in);
 
+IMF_EXPORT 
 int            ImfTiledInputLevelRoundingMode
-                           (const ImfTiledInputFile *in);
+                                              (const ImfTiledInputFile *in);
 
 /*
 ** Lookup tables
@@ -443,20 +526,25 @@ int               ImfTiledInputLevelRoundingMode
 struct ImfLut;
 typedef struct ImfLut ImfLut;
 
+IMF_EXPORT 
 ImfLut *               ImfNewRound12logLut (int channels);
 
+IMF_EXPORT 
 ImfLut *               ImfNewRoundNBitLut (unsigned int n, int channels);
 
+IMF_EXPORT 
 void                   ImfDeleteLut (ImfLut *lut);
 
+IMF_EXPORT 
 void                   ImfApplyLut (ImfLut *lut,
-                     ImfRgba *data,
-                     int nData,
-                     int stride);
+                                    ImfRgba *data,
+                                    int nData,
+                                    int stride);
 /*
 ** Most recent error message
 */
 
+IMF_EXPORT 
 const char *           ImfErrorMessage (void);
 
 
index 4a74c97..ae2ccaa 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -47,8 +47,9 @@
 
 using std::string;
 using std::set;
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Channel::Channel (PixelType t, int xs, int ys, bool pl):
@@ -61,27 +62,27 @@ Channel::Channel (PixelType t, int xs, int ys, bool pl):
 }
 
 
-bool
+bool   
 Channel::operator == (const Channel &other) const
 {
     return type == other.type &&
-       xSampling == other.xSampling &&
-       ySampling == other.ySampling &&
-       pLinear == other.pLinear;
+          xSampling == other.xSampling &&
+          ySampling == other.ySampling &&
+          pLinear == other.pLinear;
 }
 
 
-void
+void   
 ChannelList::insert (const char name[], const Channel &channel)
 {
     if (name[0] == 0)
-    THROW (Iex::ArgExc, "Image channel name cannot be an empty string.");
+       THROW (IEX_NAMESPACE::ArgExc, "Image channel name cannot be an empty string.");
 
     _map[name] = channel;
 }
 
 
-void
+void   
 ChannelList::insert (const string &name, const Channel &channel)
 {
     insert (name.c_str(), channel);
@@ -94,7 +95,7 @@ ChannelList::operator [] (const char name[])
     ChannelMap::iterator i = _map.find (name);
 
     if (i == _map.end())
-    THROW (Iex::ArgExc, "Cannot find image channel \"" << name << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot find image channel \"" << name << "\".");
 
     return i->second;
 }
@@ -106,7 +107,7 @@ ChannelList::operator [] (const char name[]) const
     ChannelMap::const_iterator i = _map.find (name);
 
     if (i == _map.end())
-    THROW (Iex::ArgExc, "Cannot find image channel \"" << name << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot find image channel \"" << name << "\".");
 
     return i->second;
 }
@@ -156,14 +157,14 @@ ChannelList::findChannel (const string &name) const
 }
 
 
-ChannelList::Iterator
+ChannelList::Iterator          
 ChannelList::begin ()
 {
     return _map.begin();
 }
 
 
-ChannelList::ConstIterator
+ChannelList::ConstIterator     
 ChannelList::begin () const
 {
     return _map.begin();
@@ -177,7 +178,7 @@ ChannelList::end ()
 }
 
 
-ChannelList::ConstIterator
+ChannelList::ConstIterator     
 ChannelList::end () const
 {
     return _map.end();
@@ -219,22 +220,22 @@ ChannelList::layers (set <string> &layerNames) const
 
     for (ConstIterator i = begin(); i != end(); ++i)
     {
-    string layerName = i.name();
-    size_t pos = layerName.rfind ('.');
-
-    if (pos != string::npos && pos != 0 && pos + 1 < layerName.size())
-    {
-        layerName.erase (pos);
-        layerNames.insert (layerName);
-    }
+       string layerName = i.name();
+       size_t pos = layerName.rfind ('.');
+
+       if (pos != string::npos && pos != 0 && pos + 1 < layerName.size())
+       {
+           layerName.erase (pos);
+           layerNames.insert (layerName);
+       }
     }
 }
 
 
 void
 ChannelList::channelsInLayer (const string &layerName,
-                  Iterator &first,
-                  Iterator &last)
+                             Iterator &first,
+                             Iterator &last)
 {
     channelsWithPrefix (layerName + '.', first, last);
 }
@@ -242,49 +243,49 @@ ChannelList::channelsInLayer (const string &layerName,
 
 void
 ChannelList::channelsInLayer (const string &layerName,
-                  ConstIterator &first,
-                  ConstIterator &last) const
+                             ConstIterator &first,
+                             ConstIterator &last) const
 {
     channelsWithPrefix (layerName + '.', first, last);
 }
 
 
-void
+void           
 ChannelList::channelsWithPrefix (const char prefix[],
-                 Iterator &first,
-                 Iterator &last)
+                                Iterator &first,
+                                Iterator &last)
 {
     first = last = _map.lower_bound (prefix);
-    int n = strlen (prefix);
+    size_t n = int(strlen (prefix));
 
     while (last != Iterator (_map.end()) &&
-       strncmp (last.name(), prefix, n) <= 0)
+          strncmp (last.name(), prefix, n) <= 0)
     {
-    ++last;
+       ++last;
     }
 }
 
 
 void
 ChannelList::channelsWithPrefix (const char prefix[],
-                 ConstIterator &first,
-                 ConstIterator &last) const
+                                ConstIterator &first,
+                                ConstIterator &last) const
 {
     first = last = _map.lower_bound (prefix);
-    int n = strlen (prefix);
+    size_t n = strlen (prefix);
 
     while (last != ConstIterator (_map.end()) &&
-       strncmp (last.name(), prefix, n) <= 0)
+          strncmp (last.name(), prefix, n) <= 0)
     {
-    ++last;
+       ++last;
     }
 }
 
 
-void
+void           
 ChannelList::channelsWithPrefix (const string &prefix,
-                 Iterator &first,
-                 Iterator &last)
+                                Iterator &first,
+                                Iterator &last)
 {
     return channelsWithPrefix (prefix.c_str(), first, last);
 }
@@ -292,14 +293,14 @@ ChannelList::channelsWithPrefix (const string &prefix,
 
 void
 ChannelList::channelsWithPrefix (const string &prefix,
-                 ConstIterator &first,
-                 ConstIterator &last) const
+                                ConstIterator &first,
+                                ConstIterator &last) const
 {
     return channelsWithPrefix (prefix.c_str(), first, last);
 }
 
 
-bool
+bool           
 ChannelList::operator == (const ChannelList &other) const
 {
     ConstIterator i = begin();
@@ -307,15 +308,15 @@ ChannelList::operator == (const ChannelList &other) const
 
     while (i != end() && j != other.end())
     {
-    if (!(i.channel() == j.channel()))
-        return false;
+       if (!(i.channel() == j.channel()))
+           return false;
 
-    ++i;
-    ++j;
+       ++i;
+       ++j;
     }
 
     return i == end() && j == other.end();
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index c29aba0..d36e7dc 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfName.h>
-#include <ImfPixelType.h>
+#include "ImfName.h"
+#include "ImfPixelType.h"
+
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <map>
 #include <set>
 #include <string>
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 struct Channel
@@ -65,7 +68,7 @@ struct Channel
 
     //--------------------------------------------
     // Subsampling: pixel (x, y) is present in the
-    // channel only if
+    // channel only if 
     //
     //  x % xSampling == 0 && y % ySampling == 0
     //
@@ -96,17 +99,19 @@ struct Channel
     //------------
     // Constructor
     //------------
-
+    
+    IMF_EXPORT
     Channel (PixelType type = HALF,
-         int xSampling = 1,
-         int ySampling = 1,
-         bool pLinear = false);
+            int xSampling = 1,
+            int ySampling = 1,
+            bool pLinear = false);
 
 
     //------------
     // Operator ==
     //------------
 
+    IMF_EXPORT
     bool               operator == (const Channel &other) const;
 };
 
@@ -119,17 +124,19 @@ class ChannelList
     // Add a channel
     //--------------
 
+    IMF_EXPORT
     void                       insert (const char name[],
-                    const Channel &channel);
+                                       const Channel &channel);
 
+    IMF_EXPORT
     void                       insert (const std::string &name,
-                    const Channel &channel);
+                                       const Channel &channel);
 
     //------------------------------------------------------------------
     // Access to existing channels:
     //
     // [n]             Returns a reference to the channel with name n.
-    //                 If no channel with name n exists, an Iex::ArgExc
+    //                 If no channel with name n exists, an IEX_NAMESPACE::ArgExc
     //                 is thrown.
     //
     // findChannel(n)  Returns a pointer to the channel with name n,
@@ -137,16 +144,24 @@ class ChannelList
     //
     //------------------------------------------------------------------
 
+    IMF_EXPORT
     Channel &                  operator [] (const char name[]);
+    IMF_EXPORT
     const Channel &            operator [] (const char name[]) const;
 
+    IMF_EXPORT
     Channel &                  operator [] (const std::string &name);
+    IMF_EXPORT
     const Channel &            operator [] (const std::string &name) const;
 
+    IMF_EXPORT
     Channel *                  findChannel (const char name[]);
+    IMF_EXPORT
     const Channel *            findChannel (const char name[]) const;
 
+    IMF_EXPORT
     Channel *                  findChannel (const std::string &name);
+    IMF_EXPORT
     const Channel *            findChannel (const std::string &name) const;
 
 
@@ -159,19 +174,27 @@ class ChannelList
     class Iterator;
     class ConstIterator;
 
+    IMF_EXPORT
     Iterator                   begin ();
+    IMF_EXPORT
     ConstIterator              begin () const;
 
+    IMF_EXPORT
     Iterator                   end ();
+    IMF_EXPORT
     ConstIterator              end () const;
 
+    IMF_EXPORT
     Iterator                   find (const char name[]);
+    IMF_EXPORT
     ConstIterator              find (const char name[]) const;
 
+    IMF_EXPORT
     Iterator                   find (const std::string &name);
+    IMF_EXPORT
     ConstIterator              find (const std::string &name) const;
 
-
+    
     //-----------------------------------------------------------------
     // Support for image layers:
     //
@@ -186,7 +209,7 @@ class ChannelList
     // several different virtual light sources.  The channels in
     // this image might be called "light1.R", "light1.G", "light1.B",
     // "light2.R", "light2.G", "light2.B", etc.
-    //
+    // 
     // Note that this naming convention allows layers to be nested;
     // for example, "light1.specular.R" identifies the "R" channel
     // in the "specular" sub-layer of layer "light1".
@@ -212,15 +235,18 @@ class ChannelList
     //
     //-----------------------------------------------------------------
 
+    IMF_EXPORT
     void               layers (std::set <std::string> &layerNames) const;
 
+    IMF_EXPORT
     void               channelsInLayer (const std::string &layerName,
-                         Iterator &first,
-                     Iterator &last);
+                                        Iterator &first,
+                                        Iterator &last);
 
+    IMF_EXPORT
     void               channelsInLayer (const std::string &layerName,
-                         ConstIterator &first,
-                     ConstIterator &last) const;
+                                        ConstIterator &first,
+                                        ConstIterator &last) const;
 
 
     //-------------------------------------------------------------------
@@ -235,26 +261,31 @@ class ChannelList
     //
     //-------------------------------------------------------------------
 
+    IMF_EXPORT
     void                       channelsWithPrefix (const char prefix[],
-                            Iterator &first,
-                            Iterator &last);
+                                                   Iterator &first,
+                                                   Iterator &last);
 
+    IMF_EXPORT
     void                       channelsWithPrefix (const char prefix[],
-                            ConstIterator &first,
-                            ConstIterator &last) const;
+                                                   ConstIterator &first,
+                                                   ConstIterator &last) const;
 
+    IMF_EXPORT
     void                       channelsWithPrefix (const std::string &prefix,
-                            Iterator &first,
-                            Iterator &last);
+                                                   Iterator &first,
+                                                   Iterator &last);
 
+    IMF_EXPORT
     void                       channelsWithPrefix (const std::string &prefix,
-                            ConstIterator &first,
-                            ConstIterator &last) const;
+                                                   ConstIterator &first,
+                                                   ConstIterator &last) const;
 
     //------------
     // Operator ==
     //------------
 
+    IMF_EXPORT
     bool                       operator == (const ChannelList &other) const;
 
   private:
@@ -271,13 +302,19 @@ class ChannelList::Iterator
 {
   public:
 
+    IMF_EXPORT
     Iterator ();
+    IMF_EXPORT
     Iterator (const ChannelList::ChannelMap::iterator &i);
 
+    IMF_EXPORT
     Iterator &                 operator ++ ();
+    IMF_EXPORT
     Iterator                   operator ++ (int);
 
+    IMF_EXPORT
     const char *               name () const;
+    IMF_EXPORT
     Channel &                  channel () const;
 
   private:
@@ -292,14 +329,21 @@ class ChannelList::ConstIterator
 {
   public:
 
+    IMF_EXPORT
     ConstIterator ();
+    IMF_EXPORT
     ConstIterator (const ChannelList::ChannelMap::const_iterator &i);
+    IMF_EXPORT
     ConstIterator (const ChannelList::Iterator &other);
 
+    IMF_EXPORT
     ConstIterator &            operator ++ ();
+    IMF_EXPORT
     ConstIterator              operator ++ (int);
 
+    IMF_EXPORT
     const char *               name () const;
+    IMF_EXPORT
     const Channel &            channel () const;
 
   private:
@@ -330,7 +374,7 @@ ChannelList::Iterator::Iterator (const ChannelList::ChannelMap::iterator &i):
 }
 
 
-inline ChannelList::Iterator &
+inline ChannelList::Iterator &         
 ChannelList::Iterator::operator ++ ()
 {
     ++_i;
@@ -338,7 +382,7 @@ ChannelList::Iterator::operator ++ ()
 }
 
 
-inline ChannelList::Iterator
+inline ChannelList::Iterator   
 ChannelList::Iterator::operator ++ (int)
 {
     Iterator tmp = *this;
@@ -354,7 +398,7 @@ ChannelList::Iterator::name () const
 }
 
 
-inline Channel &
+inline Channel &       
 ChannelList::Iterator::channel () const
 {
     return _i->second;
@@ -390,7 +434,7 @@ ChannelList::ConstIterator::operator ++ ()
 }
 
 
-inline ChannelList::ConstIterator
+inline ChannelList::ConstIterator              
 ChannelList::ConstIterator::operator ++ (int)
 {
     ConstIterator tmp = *this;
@@ -405,7 +449,7 @@ ChannelList::ConstIterator::name () const
     return *_i->first;
 }
 
-inline const Channel &
+inline const Channel & 
 ChannelList::ConstIterator::channel () const
 {
     return _i->second;
@@ -414,7 +458,7 @@ ChannelList::ConstIterator::channel () const
 
 inline bool
 operator == (const ChannelList::ConstIterator &x,
-         const ChannelList::ConstIterator &y)
+            const ChannelList::ConstIterator &y)
 {
     return x._i == y._i;
 }
@@ -422,12 +466,12 @@ operator == (const ChannelList::ConstIterator &x,
 
 inline bool
 operator != (const ChannelList::ConstIterator &x,
-         const ChannelList::ConstIterator &y)
+            const ChannelList::ConstIterator &y)
 {
     return !(x == y);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index f4ab3e3..5549493 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include <ImfChannelListAttribute.h>
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 namespace {
 
 template <size_t N>
 void checkIsNullTerminated (const char (&str)[N], const char *what)
 {
-    for (int i = 0; i < N; ++i) {
+    for (size_t i = 0; i < N; ++i) {
         if (str[i] == '\0')
             return;
    }
     std::stringstream s;
-    s << "Invalid " << what << ": it is more than " << (N - 1)
+    s << "Invalid " << what << ": it is more than " << (N - 1) 
       << " characters long.";
-    throw Iex::InputExc(s);
+    throw IEX_NAMESPACE::InputExc(s);
 }
 
 } // namespace
 
+
 template <>
 const char *
 ChannelListAttribute::staticTypeName ()
@@ -69,30 +69,31 @@ ChannelListAttribute::staticTypeName ()
     return "chlist";
 }
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 void
-ChannelListAttribute::writeValueTo (OStream &os, int) const
+ChannelListAttribute::writeValueTo (OStream &os, int version) const
 {
     for (ChannelList::ConstIterator i = _value.begin();
-     i != _value.end();
-     ++i)
+        i != _value.end();
+        ++i)
     {
-    //
-    // Write name
-    //
+       //
+       // Write name
+       //
 
-    Xdr::write <StreamIO> (os, i.name());
+       Xdr::write <StreamIO> (os, i.name());
 
-    //
-    // Write Channel struct
-    //
+       //
+       // Write Channel struct
+       //
 
-    Xdr::write <StreamIO> (os, int (i.channel().type));
-    Xdr::write <StreamIO> (os, i.channel().pLinear);
-    Xdr::pad   <StreamIO> (os, 3);
-    Xdr::write <StreamIO> (os, i.channel().xSampling);
-    Xdr::write <StreamIO> (os, i.channel().ySampling);
+       Xdr::write <StreamIO> (os, int (i.channel().type));
+       Xdr::write <StreamIO> (os, i.channel().pLinear);
+       Xdr::pad   <StreamIO> (os, 3);
+       Xdr::write <StreamIO> (os, i.channel().xSampling);
+       Xdr::write <StreamIO> (os, i.channel().ySampling);
     }
 
     //
@@ -105,41 +106,45 @@ ChannelListAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-ChannelListAttribute::readValueFrom (IStream &is, int, int)
+ChannelListAttribute::readValueFrom (IStream &is,
+                                     int size,
+                                     int version)
 {
     while (true)
     {
-    //
-    // Read name; zero length name means end of channel list
-    //
+       //
+       // Read name; zero length name means end of channel list
+       //
 
-    char name[Name::SIZE];
-    Xdr::read <StreamIO> (is, Name::MAX_LENGTH, name);
+       char name[Name::SIZE];
+       Xdr::read <StreamIO> (is,Name::MAX_LENGTH,name);
 
-    if (name[0] == 0)
-        break;
+       if (name[0] == 0)
+           break;
 
-    checkIsNullTerminated (name, "channel name");
+       checkIsNullTerminated (name, "channel name");
 
-    //
-    // Read Channel struct
-    //
+       //
+       // Read Channel struct
+       //
 
-    int type;
-    bool pLinear;
-    int xSampling;
-    int ySampling;
+       int type;
+       bool pLinear;
+       int xSampling;
+       int ySampling;
 
-    Xdr::read <StreamIO> (is, type);
-    Xdr::read <StreamIO> (is, pLinear);
-    Xdr::skip <StreamIO> (is, 3);
-    Xdr::read <StreamIO> (is, xSampling);
-    Xdr::read <StreamIO> (is, ySampling);
+       Xdr::read <StreamIO> (is, type);
+       Xdr::read <StreamIO> (is, pLinear);
+       Xdr::skip <StreamIO> (is, 3);
+       Xdr::read <StreamIO> (is, xSampling);
+       Xdr::read <StreamIO> (is, ySampling);
 
-    _value.insert
-        (name, Channel (PixelType (type), xSampling, ySampling, pLinear));
+       _value.insert (name, Channel (PixelType (type),
+                                     xSampling,
+                                     ySampling,
+                                     pLinear));
     }
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index d45832b..60d8907 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfChannelList.h>
+#include "ImfAttribute.h"
+#include "ImfChannelList.h"
+#include "ImfExport.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::ChannelList> ChannelListAttribute;
 
-typedef TypedAttribute<ChannelList> ChannelListAttribute;
-template <> const char *ChannelListAttribute::staticTypeName ();
-template <> void ChannelListAttribute::writeValueTo (OStream &, int) const;
-template <> void ChannelListAttribute::readValueFrom (IStream &, int, int);
+template <>
+IMF_EXPORT
+const char *ChannelListAttribute::staticTypeName ();
 
+template <>
+IMF_EXPORT
+void ChannelListAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                         int) const;
 
-} // namespace Imf
+template <>
+IMF_EXPORT
+void ChannelListAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                          int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfChannelListAttribute.cpp>
-#endif
 
 #endif
 
index c0a81ee..6a7fc15 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2009, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include <limits>
-#include <IexMathExc.h>
+#include "IexMathExc.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <bool b> struct StaticAssertionFailed;
 template <> struct StaticAssertionFailed <true> {};
 
 #define IMF_STATIC_ASSERT(x) \
-    do {StaticAssertionFailed <x> staticAssertionFailed;} while (false)
+    do {StaticAssertionFailed <x> staticAssertionFailed; ((void) staticAssertionFailed);} while (false)
 
 
 template <class T>
@@ -66,7 +67,7 @@ uiMult (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (a > 0 && b > std::numeric_limits<T>::max() / a)
-        throw Iex::OverflowExc ("Integer multiplication overflow.");
+        throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow.");
 
     return a * b;
 }
@@ -84,7 +85,7 @@ uiDiv (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (b == 0)
-        throw Iex::DivzeroExc ("Integer division by zero.");
+        throw IEX_NAMESPACE::DivzeroExc ("Integer division by zero.");
 
     return a / b;
 }
@@ -102,7 +103,7 @@ uiAdd (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (a > std::numeric_limits<T>::max() - b)
-        throw Iex::OverflowExc ("Integer addition overflow.");
+        throw IEX_NAMESPACE::OverflowExc ("Integer addition overflow.");
 
     return a + b;
 }
@@ -120,7 +121,7 @@ uiSub (T a, T b)
                         std::numeric_limits<T>::is_integer);
 
     if (a < b)
-        throw Iex::UnderflowExc ("Integer subtraction underflow.");
+        throw IEX_NAMESPACE::UnderflowExc ("Integer subtraction underflow.");
 
     return a - b;
 }
@@ -138,7 +139,7 @@ checkArraySize (T n, size_t s)
     //
     //      size_t (n) * s
     //
-    // would overflow, then throw an Iex::OverflowExc exception.
+    // would overflow, then throw an IEX_NAMESPACE::OverflowExc exception.
     // Otherwise return
     //
     //      size_t (n).
@@ -150,12 +151,13 @@ checkArraySize (T n, size_t s)
     IMF_STATIC_ASSERT (sizeof (T) <= sizeof (size_t));
 
     if (size_t (n) > std::numeric_limits<size_t>::max() / s)
-        throw Iex::OverflowExc ("Integer multiplication overflow.");
+        throw IEX_NAMESPACE::OverflowExc ("Integer multiplication overflow.");
 
     return size_t (n);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
index 4368f03..f354cdf 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include <ImfChromaticities.h>
+#include "ImfNamespace.h"
+#include <string.h>
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-Chromaticities::Chromaticities (const Imath::V2f &red,
-                const Imath::V2f &green,
-                const Imath::V2f &blue,
-                const Imath::V2f &white)
+   
+Chromaticities::Chromaticities (const IMATH_NAMESPACE::V2f &red,
+                               const IMATH_NAMESPACE::V2f &green,
+                               const IMATH_NAMESPACE::V2f &blue,
+                               const IMATH_NAMESPACE::V2f &white)
 :
     red (red),
     green (green),
@@ -58,14 +60,28 @@ Chromaticities::Chromaticities (const Imath::V2f &red,
     // empty
 }
 
+    
+bool
+Chromaticities::operator == (const Chromaticities & c) const
+{
+    return red == c.red && green == c.green && blue == c.blue;
+}
 
-Imath::M44f
+    
+bool
+Chromaticities::operator != (const Chromaticities & c) const
+{
+    return red != c.red || green != c.green || blue != c.blue;
+}
+    
+    
+IMATH_NAMESPACE::M44f
 RGBtoXYZ (const Chromaticities chroma, float Y)
 {
     //
     // For an explanation of how the color conversion matrix is derived,
     // see Roy Hall, "Illumination and Color in Computer Generated Imagery",
-    // Springer-Verlag, 1989, chapter 3, "Perceptual Response"; and
+    // Springer-Verlag, 1989, chapter 3, "Perceptual Response"; and 
     // Charles A. Poynton, "A Technical Introduction to Digital Video",
     // John Wiley & Sons, 1996, chapter 7, "Color science for video".
     //
@@ -82,32 +98,32 @@ RGBtoXYZ (const Chromaticities chroma, float Y)
     //
 
     float d = chroma.red.x   * (chroma.blue.y  - chroma.green.y) +
-          chroma.blue.x  * (chroma.green.y - chroma.red.y) +
-          chroma.green.x * (chroma.red.y   - chroma.blue.y);
+             chroma.blue.x  * (chroma.green.y - chroma.red.y) +
+             chroma.green.x * (chroma.red.y   - chroma.blue.y);
 
     float Sr = (X * (chroma.blue.y - chroma.green.y) -
-            chroma.green.x * (Y * (chroma.blue.y - 1) +
-        chroma.blue.y  * (X + Z)) +
-        chroma.blue.x  * (Y * (chroma.green.y - 1) +
-        chroma.green.y * (X + Z))) / d;
+               chroma.green.x * (Y * (chroma.blue.y - 1) +
+               chroma.blue.y  * (X + Z)) +
+               chroma.blue.x  * (Y * (chroma.green.y - 1) +
+               chroma.green.y * (X + Z))) / d;
 
     float Sg = (X * (chroma.red.y - chroma.blue.y) +
-        chroma.red.x   * (Y * (chroma.blue.y - 1) +
-        chroma.blue.y  * (X + Z)) -
-        chroma.blue.x  * (Y * (chroma.red.y - 1) +
-        chroma.red.y   * (X + Z))) / d;
+               chroma.red.x   * (Y * (chroma.blue.y - 1) +
+               chroma.blue.y  * (X + Z)) -
+               chroma.blue.x  * (Y * (chroma.red.y - 1) +
+               chroma.red.y   * (X + Z))) / d;
 
     float Sb = (X * (chroma.green.y - chroma.red.y) -
-        chroma.red.x   * (Y * (chroma.green.y - 1) +
-        chroma.green.y * (X + Z)) +
-        chroma.green.x * (Y * (chroma.red.y - 1) +
-        chroma.red.y   * (X + Z))) / d;
+               chroma.red.x   * (Y * (chroma.green.y - 1) +
+               chroma.green.y * (X + Z)) +
+               chroma.green.x * (Y * (chroma.red.y - 1) +
+               chroma.red.y   * (X + Z))) / d;
 
     //
     // Assemble the matrix
     //
 
-    Imath::M44f M;
+    IMATH_NAMESPACE::M44f M;
 
     M[0][0] = Sr * chroma.red.x;
     M[0][1] = Sr * chroma.red.y;
@@ -125,11 +141,11 @@ RGBtoXYZ (const Chromaticities chroma, float Y)
 }
 
 
-Imath::M44f
+IMATH_NAMESPACE::M44f
 XYZtoRGB (const Chromaticities chroma, float Y)
 {
     return RGBtoXYZ (chroma, Y).inverse();
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 28614c0..96b0928 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "ImathVec.h"
 #include "ImathMatrix.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
+   
 struct Chromaticities
 {
     //-----------------------------------------------
@@ -56,20 +59,31 @@ struct Chromaticities
     // (1,0,0), (0,1,0), (0,0,1) and (1,1,1).
     //-----------------------------------------------
 
-    Imath::V2f red;
-    Imath::V2f green;
-    Imath::V2f blue;
-    Imath::V2f white;
+    IMATH_NAMESPACE::V2f       red;
+    IMATH_NAMESPACE::V2f       green;
+    IMATH_NAMESPACE::V2f       blue;
+    IMATH_NAMESPACE::V2f       white;
 
     //--------------------------------------------
     // Default constructor produces chromaticities
     // according to Rec. ITU-R BT.709-3
     //--------------------------------------------
 
-    Chromaticities (const Imath::V2f &red   = Imath::V2f (0.6400f, 0.3300f),
-            const Imath::V2f &green = Imath::V2f (0.3000f, 0.6000f),
-            const Imath::V2f &blue  = Imath::V2f (0.1500f, 0.0600f),
-            const Imath::V2f &white = Imath::V2f (0.3127f, 0.3290f));
+    IMF_EXPORT
+    Chromaticities (const IMATH_NAMESPACE::V2f &red   = IMATH_NAMESPACE::V2f (0.6400f, 0.3300f),
+                   const IMATH_NAMESPACE::V2f &green = IMATH_NAMESPACE::V2f (0.3000f, 0.6000f),
+                   const IMATH_NAMESPACE::V2f &blue  = IMATH_NAMESPACE::V2f (0.1500f, 0.0600f),
+                   const IMATH_NAMESPACE::V2f &white = IMATH_NAMESPACE::V2f (0.3127f, 0.3290f));
+    
+    
+    //---------
+    // Equality
+    //---------
+    
+    IMF_EXPORT
+    bool               operator == (const Chromaticities &v) const;    
+    IMF_EXPORT
+    bool               operator != (const Chromaticities &v) const;
 };
 
 
@@ -82,39 +96,39 @@ struct Chromaticities
 //     triple (1,1,1), or "white", RGBtoXYZ(c,Y) computes a matrix, M, so
 //     that multiplying an RGB value, v, with M produces an equivalent
 //     XYZ value, w.  (w == v * M)
-//
+// 
 //     If we define that
-//
+// 
 //        (Xr, Yr, Zr) == (1, 0, 0) * M
 //        (Xg, Yg, Zg) == (0, 1, 0) * M
 //        (Xb, Yb, Zb) == (0, 0, 1) * M
 //        (Xw, Yw, Zw) == (1, 1, 1) * M,
-//
+// 
 //     then the following statements are true:
-//
+// 
 //        Xr / (Xr + Yr + Zr) == c.red.x
 //        Yr / (Xr + Yr + Zr) == c.red.y
-//
+// 
 //        Xg / (Xg + Yg + Zg) == c.red.x
 //        Yg / (Xg + Yg + Zg) == c.red.y
-//
+// 
 //        Xb / (Xb + Yb + Zb) == c.red.x
 //        Yb / (Xb + Yb + Zb) == c.red.y
-//
+// 
 //        Xw / (Xw + Yw + Zw) == c.red.x
 //        Yw / (Xw + Yw + Zw) == c.red.y
-//
+// 
 //        Yw == Y.
-//
+// 
 // XYZ to RGB:
-//
+// 
 //     YYZtoRGB(c,Y) returns RGBtoXYZ(c,Y).inverse().
-//
+// 
 
-Imath::M44f    RGBtoXYZ (const Chromaticities chroma, float Y);
-Imath::M44f    XYZtoRGB (const Chromaticities chroma, float Y);
+IMF_EXPORT IMATH_NAMESPACE::M44f    RGBtoXYZ (const Chromaticities chroma, float Y);
+IMF_EXPORT IMATH_NAMESPACE::M44f    XYZtoRGB (const Chromaticities chroma, float Y);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index ba8fb33..4d7b985 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,8 +42,9 @@
 #include <ImfChromaticitiesAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ ChromaticitiesAttribute::staticTypeName ()
 
 template <>
 void
-ChromaticitiesAttribute::writeValueTo (OStream &os, int) const
+ChromaticitiesAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.red.x);
     Xdr::write <StreamIO> (os, _value.red.y);
@@ -70,7 +71,7 @@ ChromaticitiesAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-ChromaticitiesAttribute::readValueFrom (IStream &is, int, int)
+ChromaticitiesAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.red.x);
     Xdr::read <StreamIO> (is, _value.red.y);
@@ -83,4 +84,4 @@ ChromaticitiesAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index ed2f478..6c0c35a 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfChromaticities.h>
+#include "ImfAttribute.h"
+#include "ImfChromaticities.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<Chromaticities> ChromaticitiesAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Chromaticities> ChromaticitiesAttribute;
 
 template <>
+IMF_EXPORT
 const char *ChromaticitiesAttribute::staticTypeName ();
 
 template <>
-void ChromaticitiesAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void ChromaticitiesAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                            int) const;
 
 template <>
-void ChromaticitiesAttribute::readValueFrom (IStream &, int, int);
+IMF_EXPORT
+void ChromaticitiesAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                             int,
+                                             int);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfChromaticitiesAttribute.cpp>
-#endif
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfCompositeDeepScanLine.cpp b/3rdparty/openexr/IlmImf/ImfCompositeDeepScanLine.cpp
new file mode 100644 (file)
index 0000000..7e0dac0
--- /dev/null
@@ -0,0 +1,591 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "ImfCompositeDeepScanLine.h"
+#include "ImfDeepScanLineInputPart.h"
+#include "ImfDeepScanLineInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfFrameBuffer.h"
+#include "ImfDeepFrameBuffer.h"
+#include "ImfDeepCompositing.h"
+#include "ImfPixelType.h"
+#include "IlmThreadPool.h"
+
+#include <Iex.h>
+#include <vector>
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using std::vector;
+using std::string;
+using IMATH_NAMESPACE::Box2i;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+
+
+struct CompositeDeepScanLine::Data{
+    public :
+    vector<DeepScanLineInputFile *>     _file;   // array of files    
+    vector<DeepScanLineInputPart *>     _part;   // array of parts 
+    FrameBuffer            _outputFrameBuffer;   // output frame buffer provided
+    bool                               _zback;   // true if we are using zback (otherwise channel 1 = channel 0)
+    vector< vector<float> >      _channeldata;   // pixel values, read from the input, one array per channel
+    vector< int >               _sampleCounts;   // total per-pixel sample counts,   
+    Box2i                         _dataWindow;   // data window of combined inputs
+    DeepCompositing *                   _comp;   // user-provided compositor
+    vector<string>                  _channels;   // names of channels that will be composited
+    vector<int>                    _bufferMap;   // entry _outputFrameBuffer[n].name() == _channels[ _bufferMap[n] ].name()
+    
+    void check_valid(const Header & header);     // check newly added part/file is OK; on first good call, set _zback/_dataWindow
+
+    //
+    // set up the given deep frame buffer to contain the required channels
+    // resize counts and pointers to the width of _dataWindow
+    // zero-out all counts, since the datawindow may be smaller than/not include this part
+    //
+
+    void handleDeepFrameBuffer (DeepFrameBuffer & buf,
+                                vector<unsigned int> & counts,        //per-pixel counts
+                                vector< vector<float *> > & pointers, //per-channel-per-pixel pointers to data
+                                const Header & header,
+                                int start,
+                                int end);
+
+    Data();
+};
+
+CompositeDeepScanLine::Data::Data() : _zback(false) , _comp(NULL) {}
+
+CompositeDeepScanLine::CompositeDeepScanLine() : _Data(new Data) {}
+
+CompositeDeepScanLine::~CompositeDeepScanLine()
+{
+   delete _Data;
+}
+
+void
+CompositeDeepScanLine::addSource(DeepScanLineInputPart* part)
+{
+  _Data->check_valid(part->header());
+  _Data->_part.push_back(part);
+}
+
+void
+CompositeDeepScanLine::addSource(DeepScanLineInputFile* file)
+{
+    _Data->check_valid(file->header());
+    _Data->_file.push_back(file);
+}
+
+int 
+CompositeDeepScanLine::sources() const
+{
+   return int(_Data->_part.size())+int(_Data->_file.size());
+}
+
+void
+CompositeDeepScanLine::Data::check_valid(const Header & header)
+{
+
+    bool has_z=false;
+    bool has_alpha=false;
+    // check good channel names
+    for( ChannelList::ConstIterator i=header.channels().begin();i!=header.channels().end();++i)
+    {
+        std::string n(i.name()); 
+        if(n=="ZBack")
+        {
+            _zback=true;
+        }
+        else if(n=="Z")
+        {
+            has_z=true;
+        }
+        else if(n=="A")
+        {
+            has_alpha=true;
+        }
+    }
+    
+    if(!has_z)
+    {
+        throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine is missing a Z channel");
+    }
+    
+    if(!has_alpha)
+    {
+        throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine is missing an alpha channel");
+    }
+    
+    
+    if(_part.size()==0 && _file.size()==0)
+    {
+       // first in - update and return
+
+       _dataWindow = header.dataWindow();
+       
+       return;
+    }
+    
+    
+    const Header * const match_header = _part.size()>0 ? &_part[0]->header() : &_file[0]->header();
+    
+    // check the sizes match
+    if(match_header->displayWindow() != header.displayWindow())
+    {
+        throw IEX_NAMESPACE::ArgExc("Deep data provided to CompositeDeepScanLine has a different displayWindow to previously provided data");
+    }
+    
+    _dataWindow.extendBy(header.dataWindow());
+    
+}
+void 
+CompositeDeepScanLine::Data::handleDeepFrameBuffer (DeepFrameBuffer& buf,
+                                                    std::vector< unsigned int > & counts,
+                                                    vector< std::vector< float* > > & pointers,
+                                                    const Header& header,
+                                                    int start,
+                                                    int end)
+{
+    int width=_dataWindow.size().x+1;
+    size_t pixelcount = width * (end-start+1);
+    pointers.resize(_channels.size());
+    counts.resize(pixelcount);
+    buf.insertSampleCountSlice (Slice (OPENEXR_IMF_INTERNAL_NAMESPACE::UINT,
+                                (char *) (&counts[0]-_dataWindow.min.x-start*width),
+                                sizeof(unsigned int),
+                                sizeof(unsigned int)*width));
+
+    pointers[0].resize(pixelcount);
+    buf.insert ("Z", DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                (char *)(&pointers[0][0]-_dataWindow.min.x-start*width),
+                                sizeof(float *),
+                                sizeof(float *)*width,
+                                sizeof(float) ));
+
+    if(_zback)
+    {
+        pointers[1].resize(pixelcount);
+        buf.insert ("ZBack", DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                        (char *)(&pointers[1][0]-_dataWindow.min.x-start*width),
+                                        sizeof(float *),
+                                        sizeof(float *)*width,
+                                        sizeof(float) ));
+    }
+
+    pointers[2].resize(pixelcount);
+    buf.insert ("A", DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                (char *)(&pointers[2][0]-_dataWindow.min.x-start*width),
+                                sizeof(float *),
+                                sizeof(float *)*width,
+                                sizeof(float) ));
+
+
+    size_t i =0;
+    for(FrameBuffer::ConstIterator qt  = _outputFrameBuffer.begin();
+                                   qt != _outputFrameBuffer.end();
+                                   qt++)
+    {
+        int channel_in_source = _bufferMap[i];
+        if(channel_in_source>2)
+        {
+            // not dealt with yet (0,1,2 previously inserted)
+            pointers[channel_in_source].resize(pixelcount);
+            buf.insert (qt.name(),
+                        DeepSlice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                                   (char *)(&pointers[channel_in_source][0]-_dataWindow.min.x-start*width),
+                                   sizeof(float *),
+                                   sizeof(float *)*width,
+                                   sizeof(float) ));
+        }
+
+        i++;
+    }
+
+}
+
+void
+CompositeDeepScanLine::setCompositing(DeepCompositing* c)
+{
+  _Data->_comp=c;
+}
+
+const IMATH_NAMESPACE::Box2i& CompositeDeepScanLine::dataWindow() const
+{
+  return  _Data->_dataWindow;
+}
+
+
+void
+CompositeDeepScanLine::setFrameBuffer(const FrameBuffer& fr)
+{
+    
+    //
+    // count channels; build map between channels in frame buffer
+    // and channels in internal buffers
+    //
+    
+    _Data->_channels.resize(3);
+    _Data->_channels[0]="Z";
+    _Data->_channels[1]=_Data->_zback ? "ZBack" : "Z";
+    _Data->_channels[2]="A";
+    _Data->_bufferMap.resize(0);
+    
+    for(FrameBuffer::ConstIterator q=fr.begin();q!=fr.end();q++)
+    {
+        string name(q.name());
+        if(name=="ZBack")
+        {
+            _Data->_bufferMap.push_back(1);
+        }else if(name=="Z")
+        {
+            _Data->_bufferMap.push_back(0);
+        }else if(name=="A")
+        {
+            _Data->_bufferMap.push_back(2);
+        }else{
+            _Data->_bufferMap.push_back(_Data->_channels.size());
+            _Data->_channels.push_back(name);
+        }
+    }
+    
+  _Data->_outputFrameBuffer=fr;
+}
+
+namespace 
+{
+    
+class LineCompositeTask : public Task
+{
+  public:
+
+    LineCompositeTask ( TaskGroup* group ,
+                        CompositeDeepScanLine::Data * data,
+                    int y,
+                    int start,
+                    vector<const char*>* names,
+                    vector<vector< vector<float *> > >* pointers,
+                    vector<unsigned int>* total_sizes,
+                    vector<unsigned int>* num_sources
+                  ) : Task(group) ,
+                     _Data(data),
+                     _y(y),
+                     _start(start),
+                     _names(names),
+                     _pointers(pointers),
+                     _total_sizes(total_sizes),
+                     _num_sources(num_sources)
+                     {}
+
+    virtual ~LineCompositeTask () {}
+
+    virtual void                execute ();
+    CompositeDeepScanLine::Data*         _Data;
+    int                                  _y;
+    int                                  _start;
+    vector<const char *>*                _names;
+    vector<vector< vector<float *> > >*  _pointers;
+    vector<unsigned int>*                _total_sizes;
+    vector<unsigned int>*                _num_sources;
+
+};
+
+
+void
+composite_line(int y,
+               int start,
+               CompositeDeepScanLine::Data * _Data,
+               vector<const char *> & names,
+               const vector<vector< vector<float *> > >  & pointers,
+               const vector<unsigned int> & total_sizes,
+               const vector<unsigned int> & num_sources
+              )
+{
+    vector<float> output_pixel(names.size());    //the pixel we'll output to
+    vector<const float *> inputs(names.size());
+    DeepCompositing d; // fallback compositing engine
+    DeepCompositing * comp= _Data->_comp ? _Data->_comp : &d;
+
+    int pixel = (y-start)*(_Data->_dataWindow.max.x+1-_Data->_dataWindow.min.x);
+    
+     for(int x=_Data->_dataWindow.min.x;x<=_Data->_dataWindow.max.x;x++)
+     {
+           // set inputs[] to point to the first sample of the first part of each channel
+           // if there's a zback, set all channel independently...
+
+          if(_Data->_zback)
+          {
+
+              for(size_t channel=0;channel<names.size();channel++)
+              {
+                 inputs[channel]=pointers[0][channel][pixel];
+              }
+
+          }else{
+
+              // otherwise, set 0 and 1 to point to Z
+
+
+              inputs[0]=pointers[0][0][pixel];
+              inputs[1]=pointers[0][0][pixel];
+              for(size_t channel=2;channel<names.size();channel++)
+              {
+                  inputs[channel]=pointers[0][channel][pixel];
+              }
+
+          }
+          comp->composite_pixel(&output_pixel[0],
+                                &inputs[0],
+                                &names[0],
+                                names.size(),
+                                total_sizes[pixel],
+                                num_sources[pixel]
+                               );
+
+
+           size_t channel_number=0;
+
+
+           //
+           // write out composited value into internal frame buffer
+           //
+           for(FrameBuffer::Iterator it = _Data->_outputFrameBuffer.begin();it !=_Data->_outputFrameBuffer.end();it++)
+           {
+
+               float value = output_pixel[ _Data->_bufferMap[channel_number] ]; // value to write
+
+
+                // cast to half float if necessary
+               if(it.slice().type==OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
+               {
+                   * (float *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = value;
+               }
+               else if(it.slice().type==HALF)
+               {
+                   * (half *)(it.slice().base + y*it.slice().yStride + x*it.slice().xStride) = half(value);
+               }
+
+               channel_number++;
+
+           }
+
+           pixel++;
+
+       }// next pixel on row
+}
+
+void LineCompositeTask::execute()
+{
+  composite_line(_y,_start,_Data,*_names,*_pointers,*_total_sizes,*_num_sources);
+}
+
+
+}
+
+void
+CompositeDeepScanLine::readPixels(int start, int end)
+{
+   size_t parts = _Data->_file.size() + _Data->_part.size(); // total of files+parts
+   
+   vector<DeepFrameBuffer> framebuffers(parts);
+   vector< vector<unsigned int> > counts(parts);
+   
+   //
+   // for each part, a pointer to an array of channels
+   //
+   vector<vector< vector<float *> > > pointers(parts);
+   vector<const Header *> headers(parts);
+   
+   {
+     size_t i;
+     for(i=0;i<_Data->_file.size();i++)
+     {
+         headers[i] = &_Data->_file[i]->header();
+     }
+     
+     for(size_t j=0;j<_Data->_part.size();j++)
+     {
+        headers[i+j] = &_Data->_part[j]->header();
+     }
+   }
+   
+   
+   for(size_t i=0;i<parts;i++)
+   {
+     _Data->handleDeepFrameBuffer(framebuffers[i],counts[i],pointers[i],*headers[i],start,end);
+   }
+   
+   //
+   // set frame buffers and read scanlines from all parts
+   // TODO what happens if SCANLINE not in data window?
+   //
+   
+   {
+       size_t i=0;
+       for(i=0;i<_Data->_file.size();i++)
+       {
+            _Data->_file[i]->setFrameBuffer(framebuffers[i]);
+            _Data->_file[i]->readPixelSampleCounts(start,end);
+       }
+       for(size_t j=0;j<_Data->_part.size();j++)
+       {
+           _Data->_part[j]->setFrameBuffer(framebuffers[i+j]);
+           _Data->_part[j]->readPixelSampleCounts(start,end); 
+       }
+   }   
+   
+   
+   //
+   //  total width
+   //
+   
+   size_t total_width = _Data->_dataWindow.size().x+1;
+   size_t total_pixels = total_width*(end-start+1);
+   vector<unsigned int> total_sizes(total_pixels);
+   vector<unsigned int> num_sources(total_pixels); //number of parts with non-zero sample count
+   
+   size_t overall_sample_count=0; // sum of all samples in all images between start and end
+   
+   
+   //
+   // accumulate pixel counts
+   //
+   for(size_t ptr=0;ptr<total_pixels;ptr++)
+   {
+       total_sizes[ptr]=0;
+       num_sources[ptr]=0;
+       for(size_t j=0;j<parts;j++)
+       {
+          total_sizes[ptr]+=counts[j][ptr];
+          if(counts[j][ptr]>0) num_sources[ptr]++;
+       }
+       overall_sample_count+=total_sizes[ptr];
+       
+       
+       
+   }
+   
+  
+  
+   
+   //
+   // allocate arrays for pixel data
+   // samples array accessed as in pixels[channel][sample]
+   //
+   
+   vector<vector<float> > samples( _Data->_channels.size() );
+   
+   for(size_t channel=0;channel<_Data->_channels.size();channel++)
+   {
+       if( channel!=1 || _Data->_zback)
+       {            
+           samples[channel].resize(overall_sample_count);
+       }
+   }
+   
+   for(size_t channel=0;channel<samples.size();channel++)
+   {
+       
+       if( channel!=1 || _Data->_zback)
+       {
+           
+           samples[channel].resize(overall_sample_count);
+       
+       
+          //
+          // allocate pointers for channel data
+          //
+          
+          size_t offset=0;
+       
+          for(size_t pixel=0;pixel<total_pixels;pixel++)
+          {
+              for(size_t part=0 ; part<parts && offset<overall_sample_count ; part++ )
+              {
+                      pointers[part][channel][pixel]=&samples[channel][offset];           
+                      offset+=counts[part][pixel];
+              }
+          }
+       
+       }
+   }
+   
+   //
+   // read data
+   //
+   
+   for(size_t i=0;i<_Data->_file.size();i++)
+   {
+       _Data->_file[i]->readPixels(start,end);
+   }
+   for(size_t j=0;j<_Data->_part.size();j++)
+   {
+       _Data->_part[j]->readPixels(start,end); 
+   }
+   
+   
+   
+   
+   //
+   // composite pixels and write back to framebuffer
+  //
+   
+   
+   // turn vector of strings into array of char *
+   // and make sure 'ZBack' channel is correct
+   vector<const char *> names(_Data->_channels.size());
+   for(size_t i=0;i<names.size();i++)
+   {
+       names[i]=_Data->_channels[i].c_str();
+   }
+   
+   if(!_Data->_zback) names[1]=names[0]; // no zback channel, so make it point to z
+
+   
+   
+   TaskGroup g;
+   for(int y=start;y<=end;y++)
+   {
+       ThreadPool::addGlobalTask(new LineCompositeTask(&g,_Data,y,start,&names,&pointers,&total_sizes,&num_sources));
+   }//next row
+}  
+
+const FrameBuffer& 
+CompositeDeepScanLine::frameBuffer() const
+{
+  return _Data->_outputFrameBuffer;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfCompositeDeepScanLine.h b/3rdparty/openexr/IlmImf/ImfCompositeDeepScanLine.h
new file mode 100644 (file)
index 0000000..13c3fbe
--- /dev/null
@@ -0,0 +1,152 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_COMPOSITEDEEPSCANLINE_H
+#define INCLUDED_IMF_COMPOSITEDEEPSCANLINE_H
+
+//-----------------------------------------------------------------------------
+//
+//     Class to composite deep samples into a frame buffer
+//      Initialise with a deep input part or deep inputfile
+//      (also supports multiple files and parts, and will 
+//       composite them together, as long as their sizes and channelmaps agree)
+//       
+//      Then call setFrameBuffer, and readPixels, exactly as for reading 
+//      regular scanline images.
+//
+//      Restrictions - source file(s) must contain at least Z and alpha channels
+//                   - if multiple files/parts are provided, sizes must match
+//                   - all requested channels will be composited as premultiplied
+//                   - only half and float channels can be requested
+//
+//      This object should not be considered threadsafe
+//  
+//      The default compositing engine will give spurious results with overlapping
+//      volumetric samples - you may derive from DeepCompositing class, override the 
+//      sort_pixel() and composite_pixel() functions, and pass an instance to 
+//      setCompositing(). 
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include <ImathBox.h>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class CompositeDeepScanLine
+{
+    public:
+        IMF_EXPORT
+        CompositeDeepScanLine();
+        IMF_EXPORT
+        virtual ~CompositeDeepScanLine();
+        
+        /// set the source data as a part
+        ///@note all parts must remain valid until after last interaction with DeepComp
+        IMF_EXPORT
+        void addSource(DeepScanLineInputPart * part);
+        
+        /// set the source data as a file
+        ///@note all file must remain valid until after last interaction with DeepComp
+        IMF_EXPORT
+        void addSource(DeepScanLineInputFile * file);
+        
+        
+        /////////////////////////////////////////
+        //
+        // set the frame buffer for output values
+        // the buffers specified must be large enough
+        // to handle the dataWindow() 
+        //
+        /////////////////////////////////////////
+        IMF_EXPORT
+        void setFrameBuffer(const FrameBuffer & fr);
+        
+        
+        
+        /////////////////////////////////////////
+        //
+        // retrieve frameBuffer
+        //
+        ////////////////////////////////////////
+        IMF_EXPORT
+        const FrameBuffer & frameBuffer() const;
+        
+        
+        //////////////////////////////////////////////////
+        //
+        // read scanlines start to end from the source(s)
+        // storing the result in the frame buffer provided
+        //
+        //////////////////////////////////////////////////
+        
+        IMF_EXPORT
+        void readPixels(int start,int end);
+        
+        IMF_EXPORT
+        int sources() const; // return number of sources
+        
+        /////////////////////////////////////////////////
+        //
+        // retrieve the datawindow
+        // If multiple parts are specified, this will
+        // be the union of the dataWindow of all parts
+        //
+        ////////////////////////////////////////////////
+        
+        IMF_EXPORT
+        const IMATH_NAMESPACE::Box2i & dataWindow() const;
+        
+        //
+        // override default sorting/compositing operation
+        // (otherwise an instance of the base class will be used)
+        //
+        
+        IMF_EXPORT
+        void setCompositing(DeepCompositing *);
+        
+      struct Data; 
+    private :  
+      struct Data *_Data;
+      
+      CompositeDeepScanLine(const CompositeDeepScanLine &); // not implemented
+      const CompositeDeepScanLine & operator=(const CompositeDeepScanLine &);  // not implemented
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
index ed1e4ff..c066d34 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,9 +42,9 @@
 //     enum Compression
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 enum Compression
 {
@@ -61,15 +61,24 @@ enum Compression
     PXR24_COMPRESSION = 5,     // lossy 24-bit float compression
 
     B44_COMPRESSION = 6,       // lossy 4-by-4 pixel block compression,
-                    // fixed compression rate
+                               // fixed compression rate
 
     B44A_COMPRESSION = 7,      // lossy 4-by-4 pixel block compression,
-                    // flat fields are compressed more
+                               // flat fields are compressed more
+
+    DWAA_COMPRESSION = 8,       // lossy DCT based compression, in blocks
+                                // of 32 scanlines. More efficient for partial
+                                // buffer access.
+
+    DWAB_COMPRESSION = 9,       // lossy DCT based compression, in blocks
+                                // of 256 scanlines. More efficient space
+                                // wise and faster to decode full frames
+                                // than DWAA_COMPRESSION.
 
     NUM_COMPRESSION_METHODS    // number of different compression methods
 };
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
index c198613..a32c689 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressionAttribute.h>
+#include "ImfCompressionAttribute.h"
+
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 
 template <>
@@ -56,7 +58,7 @@ CompressionAttribute::staticTypeName ()
 
 template <>
 void
-CompressionAttribute::writeValueTo (OStream &os, int) const
+CompressionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     unsigned char tmp = _value;
     Xdr::write <StreamIO> (os, tmp);
@@ -65,7 +67,7 @@ CompressionAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-CompressionAttribute::readValueFrom (IStream &is, int, int)
+CompressionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned char tmp;
     Xdr::read <StreamIO> (is, tmp);
@@ -73,4 +75,4 @@ CompressionAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index be83f2c..eea95dd 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfCompression.h>
+#include "ImfAttribute.h"
+#include "ImfCompression.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Compression> CompressionAttribute;
+template <> IMF_EXPORT const char *CompressionAttribute::staticTypeName ();
+template <> IMF_EXPORT void CompressionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                                     int) const;
+template <> IMF_EXPORT void CompressionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                                      int,
+                                                      int);
 
-typedef TypedAttribute<Compression> CompressionAttribute;
-template <> const char *CompressionAttribute::staticTypeName ();
-template <> void CompressionAttribute::writeValueTo (OStream &, int) const;
-template <> void CompressionAttribute::readValueFrom (IStream &, int, int);
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfCompressionAttribute.cpp>
-#endif
 
 #endif
index fc5beaf..1905a4d 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
-#include <ImfRleCompressor.h>
-#include <ImfZipCompressor.h>
-#include <ImfPizCompressor.h>
-#include <ImfPxr24Compressor.h>
-#include <ImfB44Compressor.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfCompressor.h"
+#include "ImfRleCompressor.h"
+#include "ImfZipCompressor.h"
+#include "ImfPizCompressor.h"
+#include "ImfPxr24Compressor.h"
+#include "ImfB44Compressor.h"
+#include "ImfDwaCompressor.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::Box2i;
+using IMATH_NAMESPACE::Box2i;
 
 
 Compressor::Compressor (const Header &hdr): _header (hdr) {}
@@ -68,25 +70,25 @@ Compressor::format () const
 
 int
 Compressor::compressTile (const char *inPtr,
-              int inSize,
-              Box2i range,
-              const char *&outPtr)
+                         int inSize,
+                         Box2i range,
+                         const char *&outPtr)
 {
     return compress (inPtr, inSize, range.min.y, outPtr);
 }
 
-
+             
 int
 Compressor::uncompressTile (const char *inPtr,
-                int inSize,
-                Box2i range,
-                const char *&outPtr)
+                           int inSize,
+                           Box2i range,
+                           const char *&outPtr)
 {
     return uncompress (inPtr, inSize, range.min.y, outPtr);
 }
 
 
-bool
+bool   
 isValidCompression (Compression c)
 {
     switch (c)
@@ -99,15 +101,30 @@ isValidCompression (Compression c)
       case PXR24_COMPRESSION:
       case B44_COMPRESSION:
       case B44A_COMPRESSION:
+      case DWAA_COMPRESSION:
+      case DWAB_COMPRESSION:
 
-    return true;
+       return true;
 
       default:
 
-    return false;
+       return false;
     }
 }
 
+bool isValidDeepCompression(Compression c)
+{
+  switch(c)
+  {
+      case NO_COMPRESSION:
+      case RLE_COMPRESSION:
+      case ZIPS_COMPRESSION:
+          return true;
+      default :
+          return false;
+  }
+}
+
 
 Compressor *
 newCompressor (Compression c, size_t maxScanLineSize, const Header &hdr)
@@ -116,77 +133,94 @@ newCompressor (Compression c, size_t maxScanLineSize, const Header &hdr)
     {
       case RLE_COMPRESSION:
 
-    return new RleCompressor (hdr, maxScanLineSize);
+       return new RleCompressor (hdr, maxScanLineSize);
 
       case ZIPS_COMPRESSION:
 
-    return new ZipCompressor (hdr, maxScanLineSize, 1);
+       return new ZipCompressor (hdr, maxScanLineSize, 1);
 
       case ZIP_COMPRESSION:
 
-    return new ZipCompressor (hdr, maxScanLineSize, 16);
+       return new ZipCompressor (hdr, maxScanLineSize, 16);
 
       case PIZ_COMPRESSION:
 
-    return new PizCompressor (hdr, maxScanLineSize, 32);
+       return new PizCompressor (hdr, maxScanLineSize, 32);
 
       case PXR24_COMPRESSION:
 
-    return new Pxr24Compressor (hdr, maxScanLineSize, 16);
+       return new Pxr24Compressor (hdr, maxScanLineSize, 16);
 
       case B44_COMPRESSION:
 
-    return new B44Compressor (hdr, maxScanLineSize, 32, false);
+       return new B44Compressor (hdr, maxScanLineSize, 32, false);
 
       case B44A_COMPRESSION:
 
-    return new B44Compressor (hdr, maxScanLineSize, 32, true);
+       return new B44Compressor (hdr, maxScanLineSize, 32, true);
+
+      case DWAA_COMPRESSION:
+
+       return new DwaCompressor (hdr, maxScanLineSize, 32, 
+                               DwaCompressor::STATIC_HUFFMAN);
+
+      case DWAB_COMPRESSION:
+
+       return new DwaCompressor (hdr, maxScanLineSize, 256, 
+                               DwaCompressor::STATIC_HUFFMAN);
 
       default:
 
-    return 0;
+       return 0;
     }
 }
 
 
 Compressor *
 newTileCompressor (Compression c,
-           size_t tileLineSize,
-           size_t numTileLines,
-           const Header &hdr)
+                  size_t tileLineSize,
+                  size_t numTileLines,
+                  const Header &hdr)
 {
     switch (c)
     {
       case RLE_COMPRESSION:
 
-    return new RleCompressor (hdr, uiMult (tileLineSize, numTileLines));
+       return new RleCompressor (hdr, uiMult (tileLineSize, numTileLines));
 
       case ZIPS_COMPRESSION:
       case ZIP_COMPRESSION:
 
-    return new ZipCompressor (hdr, tileLineSize, numTileLines);
+       return new ZipCompressor (hdr, tileLineSize, numTileLines);
 
       case PIZ_COMPRESSION:
 
-    return new PizCompressor (hdr, tileLineSize, numTileLines);
+       return new PizCompressor (hdr, tileLineSize, numTileLines);
 
       case PXR24_COMPRESSION:
 
-    return new Pxr24Compressor (hdr, tileLineSize, numTileLines);
+       return new Pxr24Compressor (hdr, tileLineSize, numTileLines);
 
       case B44_COMPRESSION:
 
-    return new B44Compressor (hdr, tileLineSize, numTileLines, false);
+       return new B44Compressor (hdr, tileLineSize, numTileLines, false);
 
       case B44A_COMPRESSION:
 
-    return new B44Compressor (hdr, tileLineSize, numTileLines, true);
+       return new B44Compressor (hdr, tileLineSize, numTileLines, true);
+
+      case DWAA_COMPRESSION:
+      case DWAB_COMPRESSION:
+
+       return new DwaCompressor (hdr, tileLineSize, numTileLines, 
+                               DwaCompressor::DEFLATE);
 
       default:
 
-    return 0;
+       return 0;
     }
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
index 9987820..9586778 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompression.h>
+#include "ImfCompression.h"
 #include "ImathBox.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
+
 #include <stdlib.h>
 
-namespace Imf {
 
-class Header;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class Compressor
@@ -61,6 +64,7 @@ class Compressor
     // that will be compressed or uncompressed
     //---------------------------------------------
 
+    IMF_EXPORT
     Compressor (const Header &hdr);
 
 
@@ -68,6 +72,7 @@ class Compressor
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~Compressor ();
 
 
@@ -76,6 +81,7 @@ class Compressor
     // a single call to compress() and uncompress().
     //----------------------------------------------
 
+    IMF_EXPORT
     virtual int                numScanLines () const = 0;
 
 
@@ -88,10 +94,11 @@ class Compressor
 
     enum Format
     {
-    NATIVE,            // the machine's native format
-    XDR                // Xdr format
+        NATIVE,                // the machine's native format
+        XDR            // Xdr format
     };
 
+    IMF_EXPORT
     virtual Format     format () const;
 
 
@@ -155,15 +162,17 @@ class Compressor
     //
     //-------------------------------------------------------------------------
 
+    IMF_EXPORT
     virtual int                compress (const char *inPtr,
-                  int inSize,
-                  int minY,
-                  const char *&outPtr) = 0;
+                                 int inSize,
+                                 int minY,
+                                 const char *&outPtr) = 0;
 
+    IMF_EXPORT
     virtual int                compressTile (const char *inPtr,
-                      int inSize,
-                      Imath::Box2i range,
-                      const char *&outPtr);
+                                     int inSize,
+                                     IMATH_NAMESPACE::Box2i range,
+                                     const char *&outPtr);
 
     //-------------------------------------------------------------------------
     // Uncompress an array of bytes that has been compressed by compress():
@@ -181,15 +190,17 @@ class Compressor
     //
     //-------------------------------------------------------------------------
 
+    IMF_EXPORT
     virtual int                uncompress (const char *inPtr,
-                    int inSize,
-                    int minY,
-                    const char *&outPtr) = 0;
+                                   int inSize,
+                                   int minY,
+                                   const char *&outPtr) = 0;
 
+    IMF_EXPORT
     virtual int                uncompressTile (const char *inPtr,
-                    int inSize,
-                    Imath::Box2i range,
-                    const char *&outPtr);
+                                       int inSize,
+                                       IMATH_NAMESPACE::Box2i range,
+                                       const char *&outPtr);
 
   private:
 
@@ -201,7 +212,15 @@ class Compressor
 // Test if c is a valid compression type
 //--------------------------------------
 
-bool           isValidCompression (Compression c);
+IMF_EXPORT 
+bool isValidCompression (Compression c);
+
+//--------------------------------------
+// Test if c is valid for deep data
+//--------------------------------------
+
+IMF_EXPORT
+bool            isValidDeepCompression (Compression c);
 
 
 //-----------------------------------------------------------------
@@ -212,16 +231,17 @@ bool              isValidCompression (Compression c);
 //
 //  header             Header of the input or output file whose
 //                     pixels will be compressed or uncompressed.
-//
+//                     
 //  return value       A pointer to a new Compressor object (it
 //                     is the caller's responsibility to delete
 //                     the object), or 0 (if c is NO_COMPRESSION).
 //
 //-----------------------------------------------------------------
 
+IMF_EXPORT 
 Compressor *   newCompressor (Compression c,
-                   size_t maxScanLineSize,
-                   const Header &hdr);
+                              size_t maxScanLineSize,
+                              const Header &hdr);
 
 
 //-----------------------------------------------------------------
@@ -241,12 +261,13 @@ Compressor *      newCompressor (Compression c,
 //
 //-----------------------------------------------------------------
 
+IMF_EXPORT 
 Compressor *    newTileCompressor (Compression c,
-                   size_t tileLineSize,
-                   size_t numTileLines,
-                   const Header &hdr);
+                                  size_t tileLineSize,
+                                  size_t numTileLines,
+                                  const Header &hdr);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index c94a502..cce7163 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfConvert.h>
+#include "ImfConvert.h"
+#include "ImfNamespace.h"
+
 #include <limits.h>
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
 namespace {
 
 inline bool
@@ -88,10 +92,10 @@ unsigned int
 halfToUint (half h)
 {
     if (h.isNegative() || h.isNan())
-    return 0;
+       return 0;
 
     if (h.isInfinity())
-    return UINT_MAX;
+       return UINT_MAX;
 
     return (unsigned int) h;
 }
@@ -101,39 +105,39 @@ unsigned int
 floatToUint (float f)
 {
     if (isNegative (f) || isNan (f))
-    return 0;
+       return 0;
 
     if (isInfinity (f) || f > UINT_MAX)
-    return UINT_MAX;
+       return UINT_MAX;
 
     return (unsigned int) f;
 }
 
 
-half
+half   
 uintToHalf (unsigned int ui)
 {
     if (ui >  HALF_MAX)
-    return half::posInf();
+       return half::posInf();
 
-    return half (ui);
+    return half ((float) ui);
 }
 
 
-half
+half   
 floatToHalf (float f)
 {
     if (isFinite (f))
     {
-    if (f >  HALF_MAX)
-        return half::posInf();
+       if (f >  HALF_MAX)
+           return half::posInf();
 
-    if (f < -HALF_MAX)
-        return half::negInf();
+       if (f < -HALF_MAX)
+           return half::negInf();
     }
 
     return half (f);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 00844dd..b0a7f47 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include "half.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
 //---------------------------------------------------------
 // Conversion from half or float to unsigned int:
@@ -70,8 +72,8 @@ namespace Imf {
 //
 //---------------------------------------------------------
 
-unsigned int   halfToUint (half h);
-unsigned int   floatToUint (float f);
+IMF_EXPORT unsigned int        halfToUint (half h);
+IMF_EXPORT unsigned int        floatToUint (float f);
 
 
 //---------------------------------------------------------
@@ -95,10 +97,11 @@ unsigned int        floatToUint (float f);
 //
 //---------------------------------------------------------
 
-half           uintToHalf (unsigned int ui);
-half           floatToHalf (float f);
+IMF_EXPORT half                uintToHalf (unsigned int ui);
+IMF_EXPORT half                floatToHalf (float f);
+
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepCompositing.cpp b/3rdparty/openexr/IlmImf/ImfDeepCompositing.cpp
new file mode 100644 (file)
index 0000000..76702c1
--- /dev/null
@@ -0,0 +1,110 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepCompositing.h"
+
+#include "ImfNamespace.h"
+#include <algorithm>
+#include <vector>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using std::sort;
+using std::vector;
+DeepCompositing::DeepCompositing()
+{
+}
+
+DeepCompositing::~DeepCompositing()
+{
+}
+
+void 
+DeepCompositing::composite_pixel (float outputs[],
+                                  const float* inputs[],
+                                  const char*channel_names[],
+                                  int num_channels,
+                                  int num_samples,
+                                  int sources)
+{
+    for(int i=0;i<num_channels;i++) outputs[i]=0.0;
+    // no samples? do nothing
+   if(num_samples==0)
+   {
+       return;
+   }
+   
+   vector<int> sort_order;
+   if(sources>1)
+   {
+       sort_order.resize(num_samples);
+       for(int i=0;i<num_samples;i++) sort_order[i]=i;
+       sort(&sort_order[0],inputs,channel_names,num_channels,num_samples,sources);
+   }
+   
+   
+   for(int i=0;i<num_samples;i++)
+   {
+       int s=(sources>1) ? sort_order[i] : i;
+       float alpha=outputs[2]; 
+       if(alpha>=1.0) return;
+       
+       for(int c=0;c<num_channels;c++)
+       {
+           outputs[c]+=(1.0-alpha)*inputs[c][s];
+       }
+   }   
+}
+
+struct sort_helper
+{
+    const float ** inputs;
+    bool operator() (int a,int b) 
+    {
+        if(inputs[0][a] < inputs[0][b]) return true;
+        if(inputs[0][a] > inputs[0][b]) return false;
+        if(inputs[1][a] < inputs[1][b]) return true;
+        if(inputs[1][a] > inputs[1][b]) return false;
+        return a<b;
+    }
+    sort_helper(const float ** i) : inputs(i) {}
+};
+
+void
+DeepCompositing::sort(int order[], const float* inputs[], const char* channel_names[], int num_channels, int num_samples, int sources)
+{
+  std::sort(order+0,order+num_samples,sort_helper(inputs));
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepCompositing.h b/3rdparty/openexr/IlmImf/ImfDeepCompositing.h
new file mode 100644 (file)
index 0000000..c5a6204
--- /dev/null
@@ -0,0 +1,136 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEPCOMPOSITING_H
+#define INCLUDED_IMF_DEEPCOMPOSITING_H
+
+//-----------------------------------------------------------------------------
+//
+//     Class to sort and composite deep samples into a frame buffer
+//      You may derive from this class to change the way that CompositeDeepScanLine
+//      and CompositeDeepTile combine samples together - pass an instance of your derived
+//      class to the compositing engine
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class DeepCompositing
+{
+    public:
+        IMF_EXPORT
+        DeepCompositing();
+        IMF_EXPORT
+        virtual ~DeepCompositing();
+        
+        
+        //////////////////////////////////////////////
+        ///
+        /// composite together the given channels
+        /// 
+        ///  @param outputs       - return array of pixel values - 
+        ///  @param inputs        - arrays of input sample
+        ///  @param channel_names - array of channel names for corresponding channels
+        ///  @param num_channels  - number of active channels (3 or greater)    
+        ///  @param num_samples   - number of values in all input arrays
+        ///  @param sources       - number of different sources
+        ///
+        /// each array input has num_channels entries: outputs[n] should be the composited
+        /// values in array inputs[n], whose name will be given by channel_names[n]
+        /// 
+        /// The channel ordering shall be as follows:
+        /// Position Channel
+        ///    0     Z
+        ///    1     ZBack (if no ZBack, then inputs[1]==inputs[0] and channel_names[1]==channel_names[0])
+        ///    2     A (alpha channel)
+        ///    3-n   other channels - only channels in the frame buffer will appear here
+        ///
+        /// since a Z and Alpha channel is required, and channel[1] is ZBack or another copy of Z
+        /// there will always be 3 or more channels.
+        ///
+        /// The default implementation calls sort() if and only if more than one source is active,
+        /// composites all samples together using the Over operator from front to back,
+        /// stopping as soon as a sample with alpha=1 is found
+        /// It also blanks all outputs if num_samples==0
+        ///
+        /// note - multiple threads may call composite_pixel simultaneously for different pixels
+        ///
+        ///
+        //////////////////////////////////////////////
+        IMF_EXPORT
+        virtual void composite_pixel(float outputs[],
+                                     const float * inputs[],
+                                     const char * channel_names[],
+                                     int num_channels,
+                                     int num_samples,
+                                     int sources
+                                     );
+                                     
+        
+       
+       ////////////////////////////////////////////////////////////////
+       ///
+       /// find the depth order for samples with given channel values
+       /// does not sort the values in-place. Instead it populates
+       /// array 'order' with the desired sorting order
+       ///
+       /// the default operation sorts samples from front to back according to their Z channel
+       ///
+       /// @param order         - required output order. order[n] shall be the nth closest sample
+       /// @param inputs        - arrays of input samples, one array per channel_name
+       /// @param channel_names - array of channel names for corresponding channels
+       /// @param num_channels  - number of channels (3 or greater)  
+       /// @param num_samples   - number of samples in each array
+       /// @param sources       - number of different sources the data arises from
+       ///
+       /// the channel layout is identical to composite_pixel() 
+       ///
+       ///////////////////////////////////////////////////////////////
+                                     
+       IMF_EXPORT
+       virtual void sort(int order[],
+                         const float * inputs[],
+                         const char * channel_names[],
+                         int num_channels,
+                         int num_samples,
+                         int sources);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepFrameBuffer.cpp b/3rdparty/openexr/IlmImf/ImfDeepFrameBuffer.cpp
new file mode 100644 (file)
index 0000000..1dfd453
--- /dev/null
@@ -0,0 +1,230 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepFrameBuffer.h"
+#include "Iex.h"
+
+
+using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepSlice::DeepSlice (PixelType t,
+                      char *b,
+                      size_t xst,
+                      size_t yst,
+                      size_t spst,
+                      int xsm,
+                      int ysm,
+                      double fv,
+                      bool xtc,
+                      bool ytc)
+:
+    Slice (t, b, xst, yst, xsm, ysm, fv, xtc, ytc),
+    sampleStride (spst)
+{
+    // empty
+}
+
+
+void
+DeepFrameBuffer::insert (const char name[], const DeepSlice &slice)
+{
+    if (name[0] == 0)
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Frame buffer slice name cannot be an empty string.");
+    }
+
+    _map[name] = slice;
+}
+
+
+void
+DeepFrameBuffer::insert (const string &name, const DeepSlice &slice)
+{
+    insert (name.c_str(), slice);
+}
+
+
+DeepSlice &
+DeepFrameBuffer::operator [] (const char name[])
+{
+    SliceMap::iterator i = _map.find (name);
+
+    if (i == _map.end())
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
+    }
+
+    return i->second;
+}
+
+
+const DeepSlice &
+DeepFrameBuffer::operator [] (const char name[]) const
+{
+    SliceMap::const_iterator i = _map.find (name);
+
+    if (i == _map.end())
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
+    }
+
+    return i->second;
+}
+
+
+DeepSlice &
+DeepFrameBuffer::operator [] (const string &name)
+{
+    return this->operator[] (name.c_str());
+}
+
+
+const DeepSlice &
+DeepFrameBuffer::operator [] (const string &name) const
+{
+    return this->operator[] (name.c_str());
+}
+
+
+DeepSlice *
+DeepFrameBuffer::findSlice (const char name[])
+{
+    SliceMap::iterator i = _map.find (name);
+    return (i == _map.end())? 0: &i->second;
+}
+
+
+const DeepSlice *
+DeepFrameBuffer::findSlice (const char name[]) const
+{
+    SliceMap::const_iterator i = _map.find (name);
+    return (i == _map.end())? 0: &i->second;
+}
+
+
+DeepSlice *
+DeepFrameBuffer::findSlice (const string &name)
+{
+    return findSlice (name.c_str());
+}
+
+
+const DeepSlice *
+DeepFrameBuffer::findSlice (const string &name) const
+{
+    return findSlice (name.c_str());
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::begin ()
+{
+    return _map.begin();
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::begin () const
+{
+    return _map.begin();
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::end ()
+{
+    return _map.end();
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::end () const
+{
+    return _map.end();
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::find (const char name[])
+{
+    return _map.find (name);
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::find (const char name[]) const
+{
+    return _map.find (name);
+}
+
+
+DeepFrameBuffer::Iterator
+DeepFrameBuffer::find (const string &name)
+{
+    return find (name.c_str());
+}
+
+
+DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::find (const string &name) const
+{
+    return find (name.c_str());
+}
+
+
+void
+DeepFrameBuffer::insertSampleCountSlice(const Slice & slice)
+{
+    if (slice.type != UINT)
+    {
+        throw IEX_NAMESPACE::ArgExc("The type of sample count slice should be UINT.");
+    }
+
+    _sampleCounts = slice;
+}
+
+
+const Slice &
+DeepFrameBuffer::getSampleCountSlice() const
+{
+    return _sampleCounts;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepFrameBuffer.h b/3rdparty/openexr/IlmImf/ImfDeepFrameBuffer.h
new file mode 100644 (file)
index 0000000..a3f062a
--- /dev/null
@@ -0,0 +1,373 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFDEEPFRAMEBUFFER_H_
+#define IMFDEEPFRAMEBUFFER_H_
+
+#include "ImfFrameBuffer.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//--------------------------------------------------------
+// Description of a single deep slice of the frame buffer:
+//--------------------------------------------------------
+
+struct DeepSlice : public Slice
+{
+    //---------------------------------------------------------------------
+    // The stride for each sample in this slice.
+    //
+    // Memory layout:  The address of sample i in pixel (x, y) is
+    //
+    //  base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
+    //       + i * sampleStride
+    //
+    // where xp and yp are computed as follows:
+    //
+    //  * If we are reading or writing a scanline-based file:
+    //
+    //      xp = x
+    //      yp = y
+    //
+    //  * If we are reading a tile whose upper left coorner is at (xt, yt):
+    //
+    //      if xTileCoords is true then xp = x - xt, else xp = x
+    //      if yTileCoords is true then yp = y - yt, else yp = y
+    //
+    //---------------------------------------------------------------------
+
+    int sampleStride;
+
+    //------------
+    // Constructor
+    //------------
+    IMF_EXPORT
+    DeepSlice (PixelType type = HALF,
+               char * base = 0,
+               size_t xStride = 0,
+               size_t yStride = 0,
+               size_t sampleStride = 0,
+               int xSampling = 1,
+               int ySampling = 1,
+               double fillValue = 0.0,
+               bool xTileCoords = false,
+               bool yTileCoords = false);
+};
+
+//-----------------
+// DeepFrameBuffer.
+//-----------------
+
+class DeepFrameBuffer
+{
+  public:
+
+
+    //------------
+    // Add a slice
+    //------------
+
+    IMF_EXPORT
+    void                        insert (const char name[],
+                                        const DeepSlice &slice);
+
+    IMF_EXPORT
+    void                        insert (const std::string &name,
+                                        const DeepSlice &slice);
+
+    //----------------------------------------------------------------
+    // Access to existing slices:
+    //
+    // [n]              Returns a reference to the slice with name n.
+    //                  If no slice with name n exists, an IEX_NAMESPACE::ArgExc
+    //                  is thrown.
+    //
+    // findSlice(n)     Returns a pointer to the slice with name n,
+    //                  or 0 if no slice with name n exists.
+    //
+    //----------------------------------------------------------------
+
+    IMF_EXPORT
+    DeepSlice &                 operator [] (const char name[]);
+    IMF_EXPORT
+    const DeepSlice &           operator [] (const char name[]) const;
+
+    IMF_EXPORT
+    DeepSlice &                 operator [] (const std::string &name);
+    IMF_EXPORT
+    const DeepSlice &           operator [] (const std::string &name) const;
+
+    IMF_EXPORT
+    DeepSlice *                 findSlice (const char name[]);
+    IMF_EXPORT
+    const DeepSlice *           findSlice (const char name[]) const;
+
+    IMF_EXPORT
+    DeepSlice *                 findSlice (const std::string &name);
+    IMF_EXPORT
+    const DeepSlice *           findSlice (const std::string &name) const;
+
+
+    //-----------------------------------------
+    // Iterator-style access to existing slices
+    //-----------------------------------------
+
+    typedef std::map <Name, DeepSlice> SliceMap;
+
+    class Iterator;
+    class ConstIterator;
+
+    IMF_EXPORT
+    Iterator                    begin ();
+    IMF_EXPORT
+    ConstIterator               begin () const;
+
+    IMF_EXPORT
+    Iterator                    end ();
+    IMF_EXPORT
+    ConstIterator               end () const;
+
+    IMF_EXPORT
+    Iterator                    find (const char name[]);
+    IMF_EXPORT
+    ConstIterator               find (const char name[]) const;
+
+    IMF_EXPORT
+    Iterator                    find (const std::string &name);
+    IMF_EXPORT
+    ConstIterator               find (const std::string &name) const;
+
+    //----------------------------------------------------
+    // Public function for accessing a sample count slice.
+    //----------------------------------------------------
+
+    IMF_EXPORT
+    void                        insertSampleCountSlice(const Slice & slice);
+    IMF_EXPORT
+    const Slice &               getSampleCountSlice() const;
+
+  private:
+
+    SliceMap                    _map;
+    Slice                       _sampleCounts;
+};
+
+//----------
+// Iterators
+//----------
+
+class DeepFrameBuffer::Iterator
+{
+  public:
+
+    IMF_EXPORT
+    Iterator ();
+    IMF_EXPORT
+    Iterator (const DeepFrameBuffer::SliceMap::iterator &i);
+
+    IMF_EXPORT
+    Iterator &                  operator ++ ();
+    IMF_EXPORT
+    Iterator                    operator ++ (int);
+
+    IMF_EXPORT
+    const char *                name () const;
+    IMF_EXPORT
+    DeepSlice &                 slice () const;
+
+  private:
+
+    friend class DeepFrameBuffer::ConstIterator;
+
+    DeepFrameBuffer::SliceMap::iterator _i;
+};
+
+
+class DeepFrameBuffer::ConstIterator
+{
+  public:
+
+    IMF_EXPORT
+    ConstIterator ();
+    IMF_EXPORT
+    ConstIterator (const DeepFrameBuffer::SliceMap::const_iterator &i);
+    IMF_EXPORT
+    ConstIterator (const DeepFrameBuffer::Iterator &other);
+
+    IMF_EXPORT
+    ConstIterator &             operator ++ ();
+    IMF_EXPORT
+    ConstIterator               operator ++ (int);
+
+    IMF_EXPORT
+    const char *                name () const;
+    IMF_EXPORT
+    const DeepSlice &           slice () const;
+
+  private:
+
+    friend bool operator == (const ConstIterator &, const ConstIterator &);
+    friend bool operator != (const ConstIterator &, const ConstIterator &);
+
+    DeepFrameBuffer::SliceMap::const_iterator _i;
+};
+
+
+//-----------------
+// Inline Functions
+//-----------------
+
+inline
+DeepFrameBuffer::Iterator::Iterator (): _i()
+{
+    // empty
+}
+
+
+inline
+DeepFrameBuffer::Iterator::Iterator (const DeepFrameBuffer::SliceMap::iterator &i):
+    _i (i)
+{
+    // empty
+}
+
+
+inline DeepFrameBuffer::Iterator &
+DeepFrameBuffer::Iterator::operator ++ ()
+{
+    ++_i;
+    return *this;
+}
+
+
+inline DeepFrameBuffer::Iterator
+DeepFrameBuffer::Iterator::operator ++ (int)
+{
+    Iterator tmp = *this;
+    ++_i;
+    return tmp;
+}
+
+
+inline const char *
+DeepFrameBuffer::Iterator::name () const
+{
+    return *_i->first;
+}
+
+
+inline DeepSlice &
+DeepFrameBuffer::Iterator::slice () const
+{
+    return _i->second;
+}
+
+
+inline
+DeepFrameBuffer::ConstIterator::ConstIterator (): _i()
+{
+    // empty
+}
+
+inline
+DeepFrameBuffer::ConstIterator::ConstIterator
+    (const DeepFrameBuffer::SliceMap::const_iterator &i): _i (i)
+{
+    // empty
+}
+
+
+inline
+DeepFrameBuffer::ConstIterator::ConstIterator (const DeepFrameBuffer::Iterator &other):
+    _i (other._i)
+{
+    // empty
+}
+
+inline DeepFrameBuffer::ConstIterator &
+DeepFrameBuffer::ConstIterator::operator ++ ()
+{
+    ++_i;
+    return *this;
+}
+
+
+inline DeepFrameBuffer::ConstIterator
+DeepFrameBuffer::ConstIterator::operator ++ (int)
+{
+    ConstIterator tmp = *this;
+    ++_i;
+    return tmp;
+}
+
+
+inline const char *
+DeepFrameBuffer::ConstIterator::name () const
+{
+    return *_i->first;
+}
+
+inline const DeepSlice &
+DeepFrameBuffer::ConstIterator::slice () const
+{
+    return _i->second;
+}
+
+
+inline bool
+operator == (const DeepFrameBuffer::ConstIterator &x,
+             const DeepFrameBuffer::ConstIterator &y)
+{
+    return x._i == y._i;
+}
+
+
+inline bool
+operator != (const DeepFrameBuffer::ConstIterator &x,
+             const DeepFrameBuffer::ConstIterator &y)
+{
+    return !(x == y);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+
+#endif /* IMFDEEPFRAMEBUFFER_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfDeepImageState.h b/3rdparty/openexr/IlmImf/ImfDeepImageState.h
new file mode 100644 (file)
index 0000000..a3941c4
--- /dev/null
@@ -0,0 +1,96 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEPIMAGESTATE_H
+#define INCLUDED_IMF_DEEPIMAGESTATE_H
+
+//-----------------------------------------------------------------------------
+//
+//      enum DeepImageState -- describes how orderly the pixel data
+//      in a deep image are
+//
+//      The samples in a deep image pixel may be sorted according to
+//      depth, and the sample depths or depth ranges may or may not
+//      overlap each other.  A pixel is
+//
+//          - SORTED if for every i and j with i < j
+//
+//              (Z[i] < Z[j]) || (Z[i] == Z[j] && ZBack[i] < ZBack[j]),
+//
+//          - NON_OVERLAPPING if for every i and j with i != j
+//
+//              (Z[i] <  Z[j] && ZBack[i] <= Z[j]) ||
+//              (Z[j] <  Z[i] && ZBack[j] <= Z[i]) ||
+//              (Z[i] == Z[j] && ZBack[i] <= Z[i] & ZBack[j] > Z[j]) ||
+//              (Z[i] == Z[j] && ZBack[j] <= Z[j] & ZBack[i] > Z[i]),
+//
+//          - TIDY if it is SORTED and NON_OVERLAPPING,
+//
+//          - MESSY if it is neither SORTED nor NON_OVERLAPPING.
+//
+//      A deep image is
+//
+//          - MESSY if at least one of its pixels is MESSY,
+//          - SORTED if all of its pixels are SORTED,
+//          - NON_OVERLAPPING if all of its pixels are NON_OVERLAPPING,
+//          - TIDY if all of its pixels are TIDY.
+//
+//      Note: the rather complicated definition of NON_OVERLAPPING prohibits
+//      overlapping volume samples, coincident point samples and point samples
+//      in the middle of a volume sample, but it does allow point samples at
+//      the front or back of a volume sample.
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+enum DeepImageState
+{
+    DIS_MESSY = 0,
+    DIS_SORTED = 1,
+    DIS_NON_OVERLAPPING = 2,
+    DIS_TIDY = 3,
+
+    DIS_NUMSTATES   // Number of different image states
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepImageStateAttribute.cpp b/3rdparty/openexr/IlmImf/ImfDeepImageStateAttribute.cpp
new file mode 100644 (file)
index 0000000..86a70a6
--- /dev/null
@@ -0,0 +1,78 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+//
+//     class DeepImageStateAttribute
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepImageStateAttribute.h>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
+
+template <>
+const char *
+DeepImageStateAttribute::staticTypeName ()
+{
+    return "deepImageState";
+}
+
+
+template <>
+void
+DeepImageStateAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
+{
+    unsigned char tmp = _value;
+    Xdr::write <StreamIO> (os, tmp);
+}
+
+
+template <>
+void
+DeepImageStateAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
+{
+    unsigned char tmp;
+    Xdr::read <StreamIO> (is, tmp);
+    _value = DeepImageState (tmp);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/3rdparty/openexr/IlmImf/ImfDeepImageStateAttribute.h b/3rdparty/openexr/IlmImf/ImfDeepImageStateAttribute.h
new file mode 100644 (file)
index 0000000..6174e94
--- /dev/null
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_DEEPIMAGESTATE_ATTRIBUTE_H
+#define INCLUDED_IMF_DEEPIMAGESTATE_ATTRIBUTE_H
+
+
+//-----------------------------------------------------------------------------
+//
+//     class DeepImageStateAttribute
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfAttribute.h"
+#include "ImfDeepImageState.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::DeepImageState>
+    DeepImageStateAttribute;
+
+template <> IMF_EXPORT const char *DeepImageStateAttribute::staticTypeName ();
+
+template <> IMF_EXPORT
+void DeepImageStateAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+
+template <> IMF_EXPORT
+void DeepImageStateAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineInputFile.cpp b/3rdparty/openexr/IlmImf/ImfDeepScanLineInputFile.cpp
new file mode 100644 (file)
index 0000000..b424676
--- /dev/null
@@ -0,0 +1,2025 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepScanLineInputFile.h>
+#include <ImfChannelList.h>
+#include <ImfMisc.h>
+#include <ImfStdIO.h>
+#include <ImfCompressor.h>
+#include <ImfXdr.h>
+#include <ImfConvert.h>
+#include <ImfThreading.h>
+#include <ImfPartType.h>
+#include <ImfVersion.h>
+#include "ImfMultiPartInputFile.h"
+#include "ImfDeepFrameBuffer.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+
+
+#include "ImathBox.h"
+#include "ImathFun.h"
+
+
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+
+#include "Iex.h"
+
+#include <string>
+#include <vector>
+#include <assert.h>
+#include <limits>
+#include <algorithm>
+
+
+#include "ImfNamespace.h"
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using std::string;
+using std::vector;
+using std::ifstream;
+using std::min;
+using std::max;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+struct InSliceInfo
+{
+    PixelType           typeInFrameBuffer;
+    PixelType           typeInFile;
+    char *              base;
+    char*               pointerArrayBase;
+    size_t              xPointerStride;
+    size_t              yPointerStride;
+    size_t              sampleStride;
+    int                 xSampling;
+    int                 ySampling;
+    bool                fill;
+    bool                skip;
+    double              fillValue;
+
+    InSliceInfo (PixelType typeInFrameBuffer = HALF,
+                 char * base = NULL,
+                 PixelType typeInFile = HALF,
+                 size_t xPointerStride = 0,
+                 size_t yPointerStride = 0,
+                 size_t sampleStride = 0,
+                 int xSampling = 1,
+                 int ySampling = 1,
+                 bool fill = false,
+                 bool skip = false,
+                 double fillValue = 0.0);
+};
+
+
+InSliceInfo::InSliceInfo (PixelType tifb,
+                          char * b,
+                          PixelType tifl,
+                          size_t xpst,
+                          size_t ypst,
+                          size_t spst,
+                          int xsm, int ysm,
+                          bool f, bool s,
+                          double fv)
+:
+    typeInFrameBuffer (tifb),
+    typeInFile (tifl),
+    base(b),
+    xPointerStride (xpst),
+    yPointerStride (ypst),
+    sampleStride (spst),
+    xSampling (xsm),
+    ySampling (ysm),
+    fill (f),
+    skip (s),
+    fillValue (fv)
+{
+    // empty
+}
+
+
+struct LineBuffer
+{
+    const char *        uncompressedData;
+    char *              buffer;
+    Int64               packedDataSize;
+    Int64               unpackedDataSize;
+
+    int                 minY;
+    int                 maxY;
+    Compressor *        compressor;
+    Compressor::Format  format;
+    int                 number;
+    bool                hasException;
+    string              exception;
+
+    LineBuffer ();
+    ~LineBuffer ();
+
+    inline void         wait () {_sem.wait();}
+    inline void         post () {_sem.post();}
+
+  private:
+
+    Semaphore           _sem;
+};
+
+
+LineBuffer::LineBuffer ():
+    uncompressedData (0),
+    buffer (0),
+    packedDataSize (0),
+    compressor (0),
+    format (defaultFormat(compressor)),
+    number (-1),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    // empty
+}
+
+
+LineBuffer::~LineBuffer ()
+{
+    if (compressor != 0)
+        delete compressor;
+}
+
+} // namespace
+
+
+struct DeepScanLineInputFile::Data: public Mutex
+{
+    Header                      header;             // the image header
+    int                         version;            // file's version
+    DeepFrameBuffer             frameBuffer;        // framebuffer to write into
+    LineOrder                   lineOrder;          // order of the scanlines in file
+    int                         minX;               // data window's min x coord
+    int                         maxX;               // data window's max x coord
+    int                         minY;               // data window's min y coord
+    int                         maxY;               // data window's max x coord
+    vector<Int64>               lineOffsets;        // stores offsets in file for
+                                                    // each line
+    bool                        fileIsComplete;     // True if no scanlines are missing
+                                                    // in the file
+    int                         nextLineBufferMinY; // minimum y of the next linebuffer
+    vector<size_t>              bytesPerLine;       // combined size of a line over all
+                                                    // channels
+    vector<size_t>              offsetInLineBuffer; // offset for each scanline in its
+                                                    // linebuffer
+    vector<InSliceInfo*>        slices;             // info about channels in file
+
+    vector<LineBuffer*>         lineBuffers;        // each holds one line buffer
+    int                         linesInBuffer;      // number of scanlines each buffer
+                                                    // holds
+    int                         partNumber;         // part number
+    int                         numThreads;         // number of threads
+    
+    bool                        multiPartBackwardSupport;       // if we are reading a multipart file using single file API
+    MultiPartInputFile*         multiPartFile;      // for multipart files opened as single part
+    bool                        memoryMapped;       // if the stream is memory mapped
+
+    Array2D<unsigned int>       sampleCount;        // the number of samples
+                                                    // in each pixel
+
+    Array<unsigned int>         lineSampleCount;    // the number of samples
+                                                    // in each line
+
+    Array<bool>                 gotSampleCount;     // for each scanline, indicating if
+                                                    // we have got its sample count table
+
+    char*                       sampleCountSliceBase; // pointer to the start of
+                                                      // the sample count array
+    int                         sampleCountXStride; // x stride of the sample count array
+    int                         sampleCountYStride; // y stride of the sample count array
+    bool                        frameBufferValid;   // set by setFrameBuffer: excepts if readPixelSampleCounts if false
+
+    Array<char>                 sampleCountTableBuffer;
+                                                    // the buffer for sample count table
+
+    Compressor*                 sampleCountTableComp;
+                                                    // the decompressor for sample count table
+
+    int                         combinedSampleSize; // total size of all channels combined: used to sanity check sample table size
+
+    int                         maxSampleCountTableSize;
+                                                    // the max size in bytes for a pixel
+                                                    // sample count table
+    InputStreamMutex*   _streamData;
+    bool                _deleteStream;
+                                                    
+
+    Data (int numThreads);
+    ~Data ();
+
+    inline LineBuffer * getLineBuffer (int number); // hash function from line
+                                                    // buffer indices into our
+                                                    // vector of line buffers
+};
+
+
+DeepScanLineInputFile::Data::Data (int numThreads):
+        partNumber(-1),
+        numThreads(numThreads),
+        multiPartBackwardSupport(false),
+        multiPartFile(NULL),
+        memoryMapped(false),
+        frameBufferValid(false),
+        _streamData(NULL),
+        _deleteStream(false)
+{
+    //
+    // We need at least one lineBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n lineBuffers
+    //
+
+    lineBuffers.resize (max (1, 2 * numThreads));
+
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        lineBuffers[i] = 0;
+
+    sampleCountTableComp = 0;
+}
+
+
+DeepScanLineInputFile::Data::~Data ()
+{
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        if (lineBuffers[i] != 0)
+            delete lineBuffers[i];
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+
+    if (sampleCountTableComp != 0)
+        delete sampleCountTableComp;
+    
+    if (multiPartBackwardSupport)
+        delete multiPartFile;
+}
+
+
+inline LineBuffer *
+DeepScanLineInputFile::Data::getLineBuffer (int lineBufferNumber)
+{
+    return lineBuffers[lineBufferNumber % lineBuffers.size()];
+}
+
+
+namespace {
+
+
+void
+reconstructLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                        LineOrder lineOrder,
+                        vector<Int64> &lineOffsets)
+{
+    Int64 position = is.tellg();
+
+    try
+    {
+        for (unsigned int i = 0; i < lineOffsets.size(); i++)
+        {
+            Int64 lineOffset = is.tellg();
+
+            int y;
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, y);
+            
+            Int64 packed_offset;
+            Int64 packed_sample;
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
+            //next is unpacked sample table size - skip this too
+            Xdr::skip <StreamIO> (is, packed_offset+packed_sample+8);
+
+            if (lineOrder == INCREASING_Y)
+                lineOffsets[i] = lineOffset;
+            else
+                lineOffsets[lineOffsets.size() - i - 1] = lineOffset;
+        }
+    }
+    catch (...)
+    {
+        //
+        // Suppress all exceptions.  This functions is
+        // called only to reconstruct the line offset
+        // table for incomplete files, and exceptions
+        // are likely.
+        //
+    }
+
+    is.clear();
+    is.seekg (position);
+}
+
+
+void
+readLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                 LineOrder lineOrder,
+                 vector<Int64> &lineOffsets,
+                 bool &complete)
+{
+    for (unsigned int i = 0; i < lineOffsets.size(); i++)
+    {
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, lineOffsets[i]);
+    }
+
+    complete = true;
+
+    for (unsigned int i = 0; i < lineOffsets.size(); i++)
+    {
+        if (lineOffsets[i] <= 0)
+        {
+            //
+            // Invalid data in the line offset table mean that
+            // the file is probably incomplete (the table is
+            // the last thing written to the file).  Either
+            // some process is still busy writing the file,
+            // or writing the file was aborted.
+            //
+            // We should still be able to read the existing
+            // parts of the file.  In order to do this, we
+            // have to make a sequential scan over the scan
+            // line data to reconstruct the line offset table.
+            //
+
+            complete = false;
+            reconstructLineOffsets (is, lineOrder, lineOffsets);
+            break;
+        }
+    }
+}
+
+
+void
+readPixelData (InputStreamMutex *streamData,
+               DeepScanLineInputFile::Data *ifd,
+               int minY,
+               char *&buffer,
+               Int64 &packedDataSize,
+               Int64 &unpackedDataSize)
+{
+    //
+    // Read a single line buffer from the input file.
+    //
+    // If the input file is not memory-mapped, we copy the pixel data into
+    // into the array pointed to by buffer.  If the file is memory-mapped,
+    // then we change where buffer points to instead of writing into the
+    // array (hence buffer needs to be a reference to a char *).
+    //
+
+    int lineBufferNumber = (minY - ifd->minY) / ifd->linesInBuffer;
+
+    Int64 lineOffset = ifd->lineOffsets[lineBufferNumber];
+
+    if (lineOffset == 0)
+        THROW (IEX_NAMESPACE::InputExc, "Scan line " << minY << " is missing.");
+
+    //
+    // Seek to the start of the scan line in the file,
+    // if necessary.
+    //
+
+    if (!isMultiPart(ifd->version))
+    {
+        if (ifd->nextLineBufferMinY != minY)
+            streamData->is->seekg (lineOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may have been moved by
+        // other parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != ifd->lineOffsets[lineBufferNumber])
+            streamData->is->seekg (lineOffset);
+    }
+
+    //
+    // Read the data block's header.
+    //
+
+    int yInFile;
+
+    //
+    // Read the part number when we are dealing with a multi-part file.
+    //
+
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, yInFile);
+
+    if (yInFile != minY)
+        throw IEX_NAMESPACE::InputExc ("Unexpected data block y coordinate.");
+
+    Int64 sampleCountTableSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, sampleCountTableSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, packedDataSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, unpackedDataSize);
+
+
+    //
+    // We make a check on the data size requirements here.
+    // Whilst we wish to store 64bit sizes on disk, not all the compressors
+    // have been made to work with such data sizes and are still limited to
+    // using signed 32 bit (int) for the data size. As such, this version
+    // insists that we validate that the data size does not exceed the data
+    // type max limit.
+    // @TODO refactor the compressor code to ensure full 64-bit support.
+    //
+
+    int compressorMaxDataSize = std::numeric_limits<int>::max();
+    if (packedDataSize   > Int64(compressorMaxDataSize) ||
+        unpackedDataSize > Int64(compressorMaxDataSize))
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "This version of the library does not support "
+              << "the allocation of data with size  > " << compressorMaxDataSize
+              << " file unpacked size :" << unpackedDataSize
+              << " file packed size   :" << packedDataSize << ".\n");
+    }
+
+    //
+    // Skip the pixel sample count table because we have read this data.
+    //
+
+    Xdr::skip <StreamIO> (*streamData->is, sampleCountTableSize);
+
+    //
+    // Read the pixel data.
+    //
+
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (packedDataSize);
+    else
+    {
+        // (TODO) check if the packed data size is too big?
+        // (TODO) better memory management. Don't delete buffer all the time.
+        if (buffer != 0) delete[] buffer;
+        buffer = new char[packedDataSize];
+        streamData->is->read (buffer, packedDataSize);
+    }
+
+    //
+    // Keep track of which scan line is the next one in
+    // the file, so that we can avoid redundant seekg()
+    // operations (seekg() can be fairly expensive).
+    //
+
+    if (ifd->lineOrder == INCREASING_Y)
+        ifd->nextLineBufferMinY = minY + ifd->linesInBuffer;
+    else
+        ifd->nextLineBufferMinY = minY - ifd->linesInBuffer;
+}
+
+//
+// A LineBufferTask encapsulates the task uncompressing a set of
+// scanlines (line buffer) and copying them into the frame buffer.
+//
+
+class LineBufferTask : public Task
+{
+  public:
+
+    LineBufferTask (TaskGroup *group,
+                    DeepScanLineInputFile::Data *ifd,
+                    LineBuffer *lineBuffer,
+                    int scanLineMin,
+                    int scanLineMax);
+
+    virtual ~LineBufferTask ();
+
+    virtual void                execute ();
+
+  private:
+
+    DeepScanLineInputFile::Data *   _ifd;
+    LineBuffer *                _lineBuffer;
+    int                         _scanLineMin;
+    int                         _scanLineMax;
+};
+
+
+LineBufferTask::LineBufferTask
+    (TaskGroup *group,
+     DeepScanLineInputFile::Data *ifd,
+     LineBuffer *lineBuffer,
+     int scanLineMin,
+     int scanLineMax)
+:
+    Task (group),
+    _ifd (ifd),
+    _lineBuffer (lineBuffer),
+    _scanLineMin (scanLineMin),
+    _scanLineMax (scanLineMax)
+{
+    // empty
+}
+
+
+LineBufferTask::~LineBufferTask ()
+{
+    //
+    // Signal that the line buffer is now free
+    //
+
+    _lineBuffer->post ();
+}
+
+
+void
+LineBufferTask::execute ()
+{
+    try
+    {
+        //
+        // Uncompress the data, if necessary
+        //
+
+        if (_lineBuffer->uncompressedData == 0)
+        {
+            Int64 uncompressedSize = 0;
+            int maxY = min (_lineBuffer->maxY, _ifd->maxY);
+
+            for (int i = _lineBuffer->minY - _ifd->minY;
+                 i <= maxY - _ifd->minY;
+                 ++i)
+            {
+                uncompressedSize += (int) _ifd->bytesPerLine[i];
+            }
+
+            //
+            // Create the compressor everytime when we want to use it,
+            // because we don't know maxBytesPerLine beforehand.
+            // (TODO) optimize this. don't do this every time.
+            //
+
+            if (_lineBuffer->compressor != 0)
+                delete _lineBuffer->compressor;
+            Int64 maxBytesPerLine = 0;
+            for (int i = _lineBuffer->minY - _ifd->minY;
+                 i <= maxY - _ifd->minY;
+                 ++i)
+            {
+                if (_ifd->bytesPerLine[i] > maxBytesPerLine)
+                    maxBytesPerLine = _ifd->bytesPerLine[i];
+            }
+            _lineBuffer->compressor = newCompressor(_ifd->header.compression(),
+                                                    maxBytesPerLine,
+                                                    _ifd->header);
+
+            if (_lineBuffer->compressor &&
+                _lineBuffer->packedDataSize < uncompressedSize)
+            {
+                _lineBuffer->format = _lineBuffer->compressor->format();
+
+                _lineBuffer->packedDataSize = _lineBuffer->compressor->uncompress
+                    (_lineBuffer->buffer, _lineBuffer->packedDataSize,
+                     _lineBuffer->minY, _lineBuffer->uncompressedData);
+            }
+            else
+            {
+                //
+                // If the line is uncompressed, it's in XDR format,
+                // regardless of the compressor's output format.
+                //
+
+                _lineBuffer->format = Compressor::XDR;
+                _lineBuffer->uncompressedData = _lineBuffer->buffer;
+            }
+        }
+
+        int yStart, yStop, dy;
+
+        if (_ifd->lineOrder == INCREASING_Y)
+        {
+            yStart = _scanLineMin;
+            yStop = _scanLineMax + 1;
+            dy = 1;
+        }
+        else
+        {
+            yStart = _scanLineMax;
+            yStop = _scanLineMin - 1;
+            dy = -1;
+        }
+
+        for (int y = yStart; y != yStop; y += dy)
+        {
+            //
+            // Convert one scan line's worth of pixel data back
+            // from the machine-independent representation, and
+            // store the result in the frame buffer.
+            //
+
+            const char *readPtr = _lineBuffer->uncompressedData +
+                                  _ifd->offsetInLineBuffer[y - _ifd->minY];
+
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ifd->slices.size(); ++i)
+            {
+                //
+                // Test if scan line y of this channel contains any data
+                // (the scan line contains data only if y % ySampling == 0).
+                //
+
+                InSliceInfo &slice = *_ifd->slices[i];
+
+                if (modp (y, slice.ySampling) != 0)
+                    continue;
+
+                //
+                // Find the x coordinates of the leftmost and rightmost
+                // sampled pixels (i.e. pixels within the data window
+                // for which x % xSampling == 0).
+                //
+
+                //
+                // Fill the frame buffer with pixel data.
+                //
+
+                if (slice.skip)
+                {
+                    //
+                    // The file contains data for this channel, but
+                    // the frame buffer contains no slice for this channel.
+                    //
+
+                    skipChannel (readPtr, slice.typeInFile,
+                                 _ifd->lineSampleCount[y - _ifd->minY]);
+                }
+                else
+                {
+                    //
+                    // The frame buffer contains a slice for this channel.
+                    //
+
+                    int width = (_ifd->maxX - _ifd->minX + 1);
+
+                    copyIntoDeepFrameBuffer (readPtr, slice.base,
+                                             (char*) (&_ifd->sampleCount[0][0]
+                                                      - _ifd->minX
+                                                      - _ifd->minY * width),
+                                             sizeof(unsigned int) * 1,
+                                             sizeof(unsigned int) * width,
+                                             y, _ifd->minX, _ifd->maxX,
+                                             0, 0,
+                                             0, 0,
+                                             slice.sampleStride, 
+                                             slice.xPointerStride,
+                                             slice.yPointerStride,
+                                             slice.fill,
+                                             slice.fillValue, _lineBuffer->format,
+                                             slice.typeInFrameBuffer,
+                                             slice.typeInFile);
+                }
+            }
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = e.what();
+            _lineBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = "unrecognized exception";
+            _lineBuffer->hasException = true;
+        }
+    }
+}
+
+
+LineBufferTask *
+newLineBufferTask
+    (TaskGroup *group,
+     DeepScanLineInputFile::Data *ifd,
+     int number,
+     int scanLineMin,
+     int scanLineMax)
+{
+    //
+    // Wait for a line buffer to become available, fill the line
+    // buffer with raw data from the file if necessary, and create
+    // a new LineBufferTask whose execute() method will uncompress
+    // the contents of the buffer and copy the pixels into the
+    // frame buffer.
+    //
+
+    LineBuffer *lineBuffer = ifd->getLineBuffer (number);
+
+    try
+    {
+        lineBuffer->wait ();
+
+        if (lineBuffer->number != number)
+        {
+            lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer;
+            lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1;
+
+            lineBuffer->number = number;
+            lineBuffer->uncompressedData = 0;
+
+            readPixelData (ifd->_streamData, ifd, lineBuffer->minY,
+                           lineBuffer->buffer,
+                           lineBuffer->packedDataSize,
+                           lineBuffer->unpackedDataSize);
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!lineBuffer->hasException)
+        {
+            lineBuffer->exception = e.what();
+            lineBuffer->hasException = true;
+        }
+        lineBuffer->number = -1;
+        lineBuffer->post();
+        throw;
+    }
+    catch (...)
+    {
+        //
+        // Reading from the file caused an exception.
+        // Signal that the line buffer is free, and
+        // re-throw the exception.
+        //
+
+        lineBuffer->exception = "unrecognized exception";
+        lineBuffer->hasException = true;
+        lineBuffer->number = -1;
+        lineBuffer->post();
+        throw;
+    }
+
+    scanLineMin = max (lineBuffer->minY, scanLineMin);
+    scanLineMax = min (lineBuffer->maxY, scanLineMax);
+
+    return new LineBufferTask (group, ifd, lineBuffer,
+                               scanLineMin, scanLineMax);
+}
+
+} // namespace
+
+
+void DeepScanLineInputFile::initialize(const Header& header)
+{
+    try
+    {
+        if (header.type() != DEEPSCANLINE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a DeepScanLineInputFile from "
+            "a type-mismatched part.");
+        
+        if(header.version()!=1)
+        {
+            THROW(IEX_NAMESPACE::ArgExc, "Version " << header.version() << " not supported for deepscanline images in this version of the library");
+        }
+        
+        _data->header = header;
+
+        _data->lineOrder = _data->header.lineOrder();
+
+        const Box2i &dataWindow = _data->header.dataWindow();
+
+        _data->minX = dataWindow.min.x;
+        _data->maxX = dataWindow.max.x;
+        _data->minY = dataWindow.min.y;
+        _data->maxY = dataWindow.max.y;
+
+        _data->sampleCount.resizeErase(_data->maxY - _data->minY + 1,
+                                       _data->maxX - _data->minX + 1);
+        _data->lineSampleCount.resizeErase(_data->maxY - _data->minY + 1);
+
+        Compressor* compressor = newCompressor(_data->header.compression(),
+                                               0,
+                                               _data->header);
+
+        _data->linesInBuffer = numLinesInBuffer (compressor);
+
+        delete compressor;
+
+        _data->nextLineBufferMinY = _data->minY - 1;
+
+        int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
+                              _data->linesInBuffer) / _data->linesInBuffer;
+
+        _data->lineOffsets.resize (lineOffsetSize);
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+            _data->lineBuffers[i] = new LineBuffer ();
+
+        _data->gotSampleCount.resizeErase(_data->maxY - _data->minY + 1);
+        for (int i = 0; i < _data->maxY - _data->minY + 1; i++)
+            _data->gotSampleCount[i] = false;
+
+        _data->maxSampleCountTableSize = min(_data->linesInBuffer, _data->maxY - _data->minY + 1) *
+                                        (_data->maxX - _data->minX + 1) *
+                                        sizeof(unsigned int);
+
+        _data->sampleCountTableBuffer.resizeErase(_data->maxSampleCountTableSize);
+
+        _data->sampleCountTableComp = newCompressor(_data->header.compression(),
+                                                    _data->maxSampleCountTableSize,
+                                                    _data->header);
+
+        _data->bytesPerLine.resize (_data->maxY - _data->minY + 1);
+        
+        const ChannelList & c=header.channels();
+        
+        _data->combinedSampleSize=0;
+        for(ChannelList::ConstIterator i=c.begin();i!=c.end();i++)
+        {
+            switch(i.channel().type)
+            {
+                case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF  :
+                    _data->combinedSampleSize+=Xdr::size<half>();
+                    break;
+                case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                    _data->combinedSampleSize+=Xdr::size<float>();
+                    break;
+                case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT  :
+                    _data->combinedSampleSize+=Xdr::size<unsigned int>();
+                    break;
+                default :
+                    THROW(IEX_NAMESPACE::ArgExc, "Bad type for channel " << i.name() << " initializing deepscanline reader");
+                    
+            }
+        }
+        
+    }
+    catch (...)
+    {
+        delete _data;
+        _data=NULL;
+        throw;
+    }
+}
+
+
+DeepScanLineInputFile::DeepScanLineInputFile(InputPartData* part)
+    
+{
+
+    _data = new Data(part->numThreads);
+    _data->_deleteStream=false;
+    _data->_streamData = part->mutex;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    _data->version = part->version;
+
+    initialize(part->header);
+
+    _data->lineOffsets = part->chunkOffsets;
+
+    _data->partNumber = part->partNumber;
+}
+
+
+DeepScanLineInputFile::DeepScanLineInputFile
+    (const char fileName[], int numThreads)
+:
+     _data (new Data (numThreads))
+{
+    _data->_streamData = new InputStreamMutex();
+    _data->_deleteStream = true;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is = 0;
+
+    try
+    {
+        is = new StdIFStream (fileName);
+        readMagicNumberAndVersionField(*is, _data->version);
+        //
+        // Backward compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(*is);
+            return;
+        }
+        _data->_streamData->is = is;
+        _data->memoryMapped = is->isMemoryMapped();
+        _data->header.readFrom (*_data->_streamData->is, _data->version);
+        _data->header.sanityCheck (isTiled (_data->version));
+
+        initialize(_data->header);
+
+        readLineOffsets (*_data->_streamData->is,
+                         _data->lineOrder,
+                         _data->lineOffsets,
+                         _data->fileIsComplete);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (is)          delete is;
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot read image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        if (is)          delete is;
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+
+DeepScanLineInputFile::DeepScanLineInputFile
+    (const Header &header,
+     OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+     int version,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+{
+    _data->_streamData=new InputStreamMutex();
+    _data->_deleteStream=false;
+    _data->_streamData->is = is;
+    
+    _data->memoryMapped = is->isMemoryMapped();
+
+    _data->version =version;
+    
+    initialize (header);
+
+    readLineOffsets (*_data->_streamData->is,
+                     _data->lineOrder,
+                     _data->lineOffsets,
+                     _data->fileIsComplete);
+}
+
+
+DeepScanLineInputFile::~DeepScanLineInputFile ()
+{
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
+
+    if (_data)
+    {
+        if (!_data->memoryMapped)
+            for (size_t i = 0; i < _data->lineBuffers.size(); i++)
+                delete [] _data->lineBuffers[i]->buffer;
+
+        //
+        // Unless this file was opened via the multipart API, delete the streamdata
+        // object too.
+        // (TODO) it should be "isMultiPart(data->version)", but when there is only
+        // single part,
+        // (see the above constructor) the version field is not set.
+        //
+        // (TODO) we should have a way to tell if the stream data is owned by this
+        // file or by a parent multipart file.
+        //
+
+        if (_data->partNumber == -1 && _data->_streamData)
+            delete _data->_streamData;
+
+        delete _data;
+    }
+}
+
+void
+DeepScanLineInputFile::compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
+{
+    is.seekg(0);
+    //
+    // Construct a MultiPartInputFile, initialize TiledInputFile
+    // with the part 0 data.
+    // (TODO) maybe change the third parameter of the constructor of MultiPartInputFile later.
+    //
+    _data->multiPartBackwardSupport = true;
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    InputPartData* part = _data->multiPartFile->getPart(0);
+    
+    multiPartInitialize(part);
+}
+
+void DeepScanLineInputFile::multiPartInitialize(InputPartData* part)
+{
+    
+    _data->_streamData = part->mutex;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    _data->version = part->version;
+    
+    initialize(part->header);
+    
+    _data->lineOffsets = part->chunkOffsets;
+    
+    _data->partNumber = part->partNumber;
+    
+}
+
+
+const char *
+DeepScanLineInputFile::fileName () const
+{
+    return _data->_streamData->is->fileName();
+}
+
+
+const Header &
+DeepScanLineInputFile::header () const
+{
+    return _data->header;
+}
+
+
+int
+DeepScanLineInputFile::version () const
+{
+    return _data->version;
+}
+
+
+void
+DeepScanLineInputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    
+    //
+    // Check if the new frame buffer descriptor is
+    // compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        ChannelList::ConstIterator i = channels.find (j.name());
+
+        if (i == channels.end())
+            continue;
+
+        if (i.channel().xSampling != j.slice().xSampling ||
+            i.channel().ySampling != j.slice().ySampling)
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                                "of \"" << i.name() << "\" channel "
+                                "of input file \"" << fileName() << "\" are "
+                                "not compatible with the frame buffer's "
+                                "subsampling factors.");
+    }
+
+    //
+    // Store the pixel sample count table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+    }
+
+    //
+    // Initialize the slice table for readPixels().
+    //
+
+    vector<InSliceInfo*> slices;
+    ChannelList::ConstIterator i = channels.begin();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
+        {
+            //
+            // Channel i is present in the file but not
+            // in the frame buffer; data for channel i
+            // will be skipped during readPixels().
+            //
+
+            slices.push_back (new InSliceInfo (i.channel().type,
+                                               NULL,
+                                               i.channel().type,
+                                               0,
+                                               0,
+                                               0, // sampleStride
+                                               i.channel().xSampling,
+                                               i.channel().ySampling,
+                                               false,  // fill
+                                               true, // skip
+                                               0.0)); // fillValue
+            ++i;
+        }
+
+        bool fill = false;
+
+        if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+        {
+            //
+            // Channel i is present in the frame buffer, but not in the file.
+            // In the frame buffer, slice j will be filled with a default value.
+            //
+
+            fill = true;
+        }
+
+        slices.push_back (new InSliceInfo (j.slice().type,
+                                           j.slice().base,
+                                           fill? j.slice().type:
+                                                 i.channel().type,
+                                           j.slice().xStride,
+                                           j.slice().yStride,
+                                           j.slice().sampleStride,
+                                           j.slice().xSampling,
+                                           j.slice().ySampling,
+                                           fill,
+                                           false, // skip
+                                           j.slice().fillValue));
+
+
+        if (i != channels.end() && !fill)
+            ++i;
+    }
+
+    //
+    // Client may want data to be filled in multiple arrays,
+    // so we reset gotSampleCount and bytesPerLine.
+    //
+
+    for (long i = 0; i < _data->gotSampleCount.size(); i++)
+        _data->gotSampleCount[i] = false;
+    for (size_t i = 0; i < _data->bytesPerLine.size(); i++)
+        _data->bytesPerLine[i] = 0;
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+    _data->frameBufferValid = true;
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineInputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+bool
+DeepScanLineInputFile::isComplete () const
+{
+    return _data->fileIsComplete;
+}
+
+
+void
+DeepScanLineInputFile::readPixels (int scanLine1, int scanLine2)
+{
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data destination.");
+
+        int scanLineMin = min (scanLine1, scanLine2);
+        int scanLineMax = max (scanLine1, scanLine2);
+
+        if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
+            throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
+                               "the image file's data window.");
+
+        for (int i = scanLineMin; i <= scanLineMax; i++)
+        {
+            if (_data->gotSampleCount[i - _data->minY] == false)
+                throw IEX_NAMESPACE::ArgExc ("Tried to read scan line without "
+                                   "knowing the sample counts, please"
+                                   "read the sample counts first.");
+        }
+
+        //
+        // We impose a numbering scheme on the lineBuffers where the first
+        // scanline is contained in lineBuffer 1.
+        //
+        // Determine the first and last lineBuffer numbers in this scanline
+        // range. We always attempt to read the scanlines in the order that
+        // they are stored in the file.
+        //
+
+        int start, stop, dl;
+
+        if (_data->lineOrder == INCREASING_Y)
+        {
+            start = (scanLineMin - _data->minY) / _data->linesInBuffer;
+            stop  = (scanLineMax - _data->minY) / _data->linesInBuffer + 1;
+            dl = 1;
+        }
+        else
+        {
+            start = (scanLineMax - _data->minY) / _data->linesInBuffer;
+            stop  = (scanLineMin - _data->minY) / _data->linesInBuffer - 1;
+            dl = -1;
+        }
+
+        //
+        // Create a task group for all line buffer tasks.  When the
+        // task group goes out of scope, the destructor waits until
+        // all tasks are complete.
+        //
+
+        {
+            TaskGroup taskGroup;
+
+            //
+            // Add the line buffer tasks.
+            //
+            // The tasks will execute in the order that they are created
+            // because we lock the line buffers during construction and the
+            // constructors are called by the main thread.  Hence, in order
+            // for a successive task to execute the previous task which
+            // used that line buffer must have completed already.
+            //
+
+            for (int l = start; l != stop; l += dl)
+            {
+                ThreadPool::addGlobalTask (newLineBufferTask (&taskGroup,
+                                                              _data, l,
+                                                              scanLineMin,
+                                                              scanLineMax));
+            }
+
+            //
+            // finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // LineBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to ScanLineInputFile::readPixels().
+        // LineBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the line buffers.
+        // Now we check if any line buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple line buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+        {
+            LineBuffer *lineBuffer = _data->lineBuffers[i];
+
+            if (lineBuffer->hasException && !exception)
+                exception = &lineBuffer->exception;
+
+            lineBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading pixel data from image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+void
+DeepScanLineInputFile::readPixels (int scanLine)
+{
+    readPixels (scanLine, scanLine);
+}
+
+
+void
+DeepScanLineInputFile::rawPixelData (int firstScanLine,
+                                     char *pixelData,
+                                     Int64 &pixelDataSize)
+{
+   
+    
+    int minY = lineBufferMinY
+    (firstScanLine, _data->minY, _data->linesInBuffer);
+    int lineBufferNumber = (minY - _data->minY) / _data->linesInBuffer;
+    
+    Int64 lineOffset = _data->lineOffsets[lineBufferNumber];
+    
+    if (lineOffset == 0)
+        THROW (IEX_NAMESPACE::InputExc, "Scan line " << minY << " is missing.");
+    
+    
+    // enter the lock here - prevent another thread reseeking the file during read
+    Lock lock (*_data->_streamData);
+    
+    //
+    // Seek to the start of the scan line in the file,
+    //
+    
+    if (_data->_streamData->is->tellg() != _data->lineOffsets[lineBufferNumber])
+        _data->_streamData->is->seekg (lineOffset);
+    
+    //
+    // Read the data block's header.
+    //
+    
+    int yInFile;
+    
+    //
+    // Read the part number when we are dealing with a multi-part file.
+    //
+    
+    if (isMultiPart(_data->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, partNumber);
+        if (partNumber != _data->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+            << ", should be " << _data->partNumber << ".");
+        }
+    }
+    
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, yInFile);
+    
+    if (yInFile != minY)
+        throw IEX_NAMESPACE::InputExc ("Unexpected data block y coordinate.");
+    
+    Int64 sampleCountTableSize;
+    Int64 packedDataSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, sampleCountTableSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*_data->_streamData->is, packedDataSize);
+    
+    // total requirement for reading all the data
+    
+    Int64 totalSizeRequired=28+sampleCountTableSize+packedDataSize;
+    
+    bool big_enough = totalSizeRequired<=pixelDataSize;
+    
+    pixelDataSize = totalSizeRequired;
+    
+    // was the block we were given big enough?
+    if(!big_enough || pixelData==NULL)
+    {        
+        // special case: seek stream back to start if we are at the beginning (regular reading pixels assumes it doesn't need to seek
+        // in single part files)
+        if(!isMultiPart(_data->version))
+        {
+          if (_data->nextLineBufferMinY == minY)
+              _data->_streamData->is->seekg (lineOffset);
+        }
+        // leave lock here - bail before reading more data
+        return;
+    }
+    
+    // copy the values we have read into the output block
+    *(int *) pixelData = yInFile;
+    *(Int64 *) (pixelData+4) =sampleCountTableSize;
+    *(Int64 *) (pixelData+12) = packedDataSize;
+    
+    // didn't read the unpackedsize - do that now
+    Xdr::read<StreamIO> (*_data->_streamData->is, *(Int64 *) (pixelData+20));
+    
+    // read the actual data
+    _data->_streamData->is->read(pixelData+28, sampleCountTableSize+packedDataSize);
+    
+    // special case: seek stream back to start if we are at the beginning (regular reading pixels assumes it doesn't need to seek
+    // in single part files)
+    if(!isMultiPart(_data->version))
+    {
+        if (_data->nextLineBufferMinY == minY)
+            _data->_streamData->is->seekg (lineOffset);
+    }
+    
+    // leave lock here
+    
+}
+
+void DeepScanLineInputFile::readPixels (const char* rawPixelData, 
+                                        const DeepFrameBuffer& frameBuffer, 
+                                        int scanLine1, 
+                                        int scanLine2) const
+{
+    //
+    // read header from block - already converted from Xdr to native format
+    //
+    int data_scanline = *(int *) rawPixelData;
+    Int64 sampleCountTableDataSize=*(Int64 *) (rawPixelData+4);
+    Int64 packedDataSize = *(Int64 *) (rawPixelData+12);
+    Int64 unpackedDataSize = *(Int64 *) (rawPixelData+20);
+
+    
+    
+    //
+    // Uncompress the data, if necessary
+    //
+    
+    
+    Compressor * decomp = NULL;
+    const char * uncompressed_data;
+    Compressor::Format format = Compressor::XDR;
+    if(packedDataSize <unpackedDataSize)
+    {
+        decomp = newCompressor(_data->header.compression(),
+                                             unpackedDataSize,
+                                             _data->header);
+                                             
+        decomp->uncompress(rawPixelData+28+sampleCountTableDataSize,
+                           packedDataSize,
+                           data_scanline, uncompressed_data);
+        format = decomp->format();
+    }
+    else
+    {
+        //
+        // If the line is uncompressed, it's in XDR format,
+        // regardless of the compressor's output format.
+        //
+        
+        format = Compressor::XDR;
+        uncompressed_data = rawPixelData+28+sampleCountTableDataSize;
+    }
+  
+    
+    int yStart, yStop, dy;
+    
+    if (_data->lineOrder == INCREASING_Y)
+    {
+        yStart = scanLine1;
+        yStop = scanLine2 + 1;
+        dy = 1;
+    }
+    else
+    {
+        yStart = scanLine2;
+        yStop = scanLine1 - 1;
+        dy = -1;
+    }
+    
+    
+    
+    const char* samplecount_base = frameBuffer.getSampleCountSlice().base;
+    int samplecount_xstride = frameBuffer.getSampleCountSlice().xStride;
+    int samplecount_ystride = frameBuffer.getSampleCountSlice().yStride;
+    
+    //
+    // For each line within the block, get the count of bytes.
+    //
+    
+    int minYInLineBuffer = data_scanline;
+    int maxYInLineBuffer = min(minYInLineBuffer + _data->linesInBuffer - 1, _data->maxY);
+    
+    vector<size_t> bytesPerLine(1+_data->maxY-_data->minY);
+    
+    
+    bytesPerDeepLineTable (_data->header,
+                           minYInLineBuffer,
+                           maxYInLineBuffer,
+                           samplecount_base,
+                           samplecount_xstride,
+                           samplecount_ystride,
+                           bytesPerLine);
+                           
+    //
+    // For each scanline within the block, get the offset.
+    //
+      
+    vector<size_t> offsetInLineBuffer;
+    offsetInLineBufferTable (bytesPerLine,
+                             minYInLineBuffer - _data->minY,
+                             maxYInLineBuffer - _data->minY,
+                             _data->linesInBuffer,
+                             offsetInLineBuffer);
+                             
+                             
+    const ChannelList & channels=header().channels();    
+    
+    
+    for (int y = yStart; y != yStop; y += dy)
+    {
+        
+        const char *readPtr =uncompressed_data +
+        offsetInLineBuffer[y - _data->minY];
+
+        //
+        // need to know the total number of samples on a scanline to skip channels
+        // compute on demand: -1 means uncomputed
+        //
+        int lineSampleCount = -1;
+        
+        
+        //
+        // Iterate over all image channels in frame buffer
+        //
+    
+    
+        ChannelList::ConstIterator i = channels.begin();
+                             
+        for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+                                            j != frameBuffer.end();
+             ++j)
+        {
+            while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
+            {
+                //
+                // Channel i is present in the file but not
+                // in the frame buffer; skip
+                    
+                if(lineSampleCount==-1)
+                {
+                     lineSampleCount=0;
+                     const char * ptr = (samplecount_base+y*samplecount_ystride + samplecount_xstride*_data->minX);
+                     for(int x=_data->minX;x<=_data->maxX;x++)
+                     { 
+                         
+                          lineSampleCount+=*(const unsigned int *) ptr;
+                          ptr+=samplecount_xstride;
+                     }
+                }
+
+               skipChannel (readPtr, i.channel().type, lineSampleCount );
+        
+                ++i;
+            }
+                                 
+            bool fill = false;
+                                 
+            if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+            {
+                //
+                // Channel i is present in the frame buffer, but not in the file.
+                // In the frame buffer, slice j will be filled with a default value.
+                //
+                                     
+               fill = true;
+            }
+            if (modp (y, i.channel().ySampling) == 0)
+            {        
+                
+                copyIntoDeepFrameBuffer (readPtr, j.slice().base,
+                                         samplecount_base,
+                                         samplecount_xstride,
+                                         samplecount_ystride,
+                                         y, _data->minX, _data->maxX,
+                                         0, 0,
+                                         0, 0,
+                                         j.slice().sampleStride, 
+                                         j.slice().xStride,
+                                         j.slice().yStride,
+                                         fill,
+                                         j.slice().fillValue, 
+                                         format,
+                                         j.slice().type,
+                                         i.channel().type);
+                                         
+                ++i;
+                                         
+            }
+        }//next slice in framebuffer
+    }//next row in image
+    
+    //
+    // clean up
+    //
+    
+    delete decomp;    
+}
+        
+      
+
+void DeepScanLineInputFile::readPixelSampleCounts (const char* rawPixelData, 
+                                                   const DeepFrameBuffer& frameBuffer, 
+                                                   int scanLine1, 
+                                                   int scanLine2) const
+{
+    //
+    // read header from block - already converted from Xdr to native format
+    //
+    int data_scanline = *(int *) rawPixelData;
+    Int64 sampleCountTableDataSize=*(Int64 *) (rawPixelData+4);
+    
+    
+    int maxY;
+    maxY = min(data_scanline + _data->linesInBuffer - 1, _data->maxY);
+    
+    if(scanLine1 != data_scanline)
+    {
+        THROW(IEX_NAMESPACE::ArgExc,"readPixelSampleCounts(rawPixelData,frameBuffer,"<< scanLine1 << ',' << scanLine2 << ") called with incorrect start scanline - should be " << data_scanline );
+    }
+    
+    if(scanLine2 != maxY)
+    {
+        THROW(IEX_NAMESPACE::ArgExc,"readPixelSampleCounts(rawPixelData,frameBuffer,"<< scanLine1 << ',' << scanLine2 << ") called with incorrect end scanline - should be " << maxY );
+    }
+    
+    
+    //
+    // If the sample count table is compressed, we'll uncompress it.
+    //
+    
+    Int64 rawSampleCountTableSize = (maxY - data_scanline + 1) * (_data->maxX - _data->minX + 1) *
+    Xdr::size <unsigned int> ();
+    
+    
+    Compressor * decomp=NULL;
+    const char* readPtr;
+    if (sampleCountTableDataSize < rawSampleCountTableSize)
+    {
+        decomp = newCompressor(_data->header.compression(),
+                               rawSampleCountTableSize,
+                               _data->header);
+                                                    
+        decomp->uncompress(rawPixelData+28,
+                                               sampleCountTableDataSize,
+                                               data_scanline,
+                                               readPtr);
+    }
+    else readPtr = rawPixelData+28;
+    
+    char* base = frameBuffer.getSampleCountSlice().base;
+    int xStride = frameBuffer.getSampleCountSlice().xStride;
+    int yStride = frameBuffer.getSampleCountSlice().yStride;
+    
+   
+    
+    for (int y = scanLine1; y <= scanLine2; y++)
+    {
+        int lastAccumulatedCount = 0;
+        for (int x = _data->minX; x <= _data->maxX; x++)
+        {
+            int accumulatedCount, count;
+            
+            //
+            // Read the sample count for pixel (x, y).
+            //
+            
+            Xdr::read <CharPtrIO> (readPtr, accumulatedCount);
+            if (x == _data->minX)
+                count = accumulatedCount;
+            else
+                count = accumulatedCount - lastAccumulatedCount;
+            lastAccumulatedCount = accumulatedCount;
+            
+            //
+            // Store the data in both internal and external data structure.
+            //
+            
+            sampleCount(base, xStride, yStride, x, y) = count;
+        }
+    }
+    
+    if(decomp)
+    {
+       delete decomp;
+    }
+}
+
+
+
+namespace
+{
+
+void
+readSampleCountForLineBlock(InputStreamMutex* streamData,
+                            DeepScanLineInputFile::Data* data,
+                            int lineBlockId)
+{
+    streamData->is->seekg(data->lineOffsets[lineBlockId]);
+
+    if (isMultiPart(data->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, partNumber);
+
+        if (partNumber != data->partNumber)
+            throw IEX_NAMESPACE::ArgExc("Unexpected part number.");
+    }
+
+    int minY;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, minY);
+
+    //
+    // Check the correctness of minY.
+    //
+
+    if (minY != data->minY + lineBlockId * data->linesInBuffer)
+        throw IEX_NAMESPACE::ArgExc("Unexpected data block y coordinate.");
+
+    int maxY;
+    maxY = min(minY + data->linesInBuffer - 1, data->maxY);
+
+    Int64 sampleCountTableDataSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, sampleCountTableDataSize);
+
+    
+    
+    if(sampleCountTableDataSize>data->maxSampleCountTableSize)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Bad sampleCountTableDataSize read from chunk "<< lineBlockId << ": expected " << data->maxSampleCountTableSize << " or less, got "<< sampleCountTableDataSize);
+    }
+    
+    Int64 packedDataSize;
+    Int64 unpackedDataSize;
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, packedDataSize);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, unpackedDataSize);
+
+    
+    
+    //
+    // We make a check on the data size requirements here.
+    // Whilst we wish to store 64bit sizes on disk, not all the compressors
+    // have been made to work with such data sizes and are still limited to
+    // using signed 32 bit (int) for the data size. As such, this version
+    // insists that we validate that the data size does not exceed the data
+    // type max limit.
+    // @TODO refactor the compressor code to ensure full 64-bit support.
+    //
+
+    int compressorMaxDataSize = std::numeric_limits<int>::max();
+    if (sampleCountTableDataSize > Int64(compressorMaxDataSize))
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "This version of the library does not "
+              << "support the allocation of data with size  > "
+              << compressorMaxDataSize
+              << " file table size    :" << sampleCountTableDataSize << ".\n");
+    }
+    streamData->is->read(data->sampleCountTableBuffer, sampleCountTableDataSize);
+    
+    const char* readPtr;
+
+    //
+    // If the sample count table is compressed, we'll uncompress it.
+    //
+
+
+    if (sampleCountTableDataSize < data->maxSampleCountTableSize)
+    {
+        if(!data->sampleCountTableComp)
+        {
+            THROW(IEX_NAMESPACE::ArgExc,"Deep scanline data corrupt at chunk " << lineBlockId << " (sampleCountTableDataSize error)");
+        }
+        data->sampleCountTableComp->uncompress(data->sampleCountTableBuffer,
+                                               sampleCountTableDataSize,
+                                               minY,
+                                               readPtr);
+    }
+    else readPtr = data->sampleCountTableBuffer;
+
+    char* base = data->sampleCountSliceBase;
+    int xStride = data->sampleCountXStride;
+    int yStride = data->sampleCountYStride;
+
+    // total number of samples in block: used to check samplecount table doesn't
+    // reference more data than exists
+    
+    size_t cumulative_total_samples=0;
+    
+    for (int y = minY; y <= maxY; y++)
+    {
+        int yInDataWindow = y - data->minY;
+        data->lineSampleCount[yInDataWindow] = 0;
+
+        int lastAccumulatedCount = 0;
+        for (int x = data->minX; x <= data->maxX; x++)
+        {
+            int accumulatedCount, count;
+
+            //
+            // Read the sample count for pixel (x, y).
+            //
+
+            Xdr::read <CharPtrIO> (readPtr, accumulatedCount);
+            
+            // sample count table should always contain monotonically
+            // increasing values.
+            if (accumulatedCount < lastAccumulatedCount)
+            {
+                THROW(IEX_NAMESPACE::ArgExc,"Deep scanline sampleCount data corrupt at chunk " << lineBlockId << " (negative sample count detected)");
+            }
+
+            count = accumulatedCount - lastAccumulatedCount;
+            lastAccumulatedCount = accumulatedCount;
+
+            //
+            // Store the data in both internal and external data structure.
+            //
+
+            data->sampleCount[yInDataWindow][x - data->minX] = count;
+            data->lineSampleCount[yInDataWindow] += count;
+            sampleCount(base, xStride, yStride, x, y) = count;
+        }
+        cumulative_total_samples+=data->lineSampleCount[yInDataWindow];
+        if(cumulative_total_samples*data->combinedSampleSize > unpackedDataSize)
+        {
+            THROW(IEX_NAMESPACE::ArgExc,"Deep scanline sampleCount data corrupt at chunk " << lineBlockId << ": pixel data only contains " << unpackedDataSize 
+            << " bytes of data but table references at least " << cumulative_total_samples*data->combinedSampleSize << " bytes of sample data" );            
+        }
+        data->gotSampleCount[y - data->minY] = true;
+    }
+}
+
+
+void
+fillSampleCountFromCache(int y, DeepScanLineInputFile::Data* data)
+{
+    int yInDataWindow = y - data->minY;
+    char* base = data->sampleCountSliceBase;
+    int xStride = data->sampleCountXStride;
+    int yStride = data->sampleCountYStride;
+    
+    for (int x = data->minX; x <= data->maxX; x++)
+    {
+        unsigned int count = data->sampleCount[yInDataWindow][x - data->minX];    
+        sampleCount(base, xStride, yStride, x, y) = count;
+    }
+}
+
+} // namespace
+
+void
+DeepScanLineInputFile::readPixelSampleCounts (int scanline1, int scanline2)
+{
+    Int64 savedFilePos = 0;
+
+    if(!_data->frameBufferValid)
+    {
+        throw IEX_NAMESPACE::ArgExc("readPixelSampleCounts called with no valid frame buffer");
+    }
+    
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        savedFilePos = _data->_streamData->is->tellg();
+
+        int scanLineMin = min (scanline1, scanline2);
+        int scanLineMax = max (scanline1, scanline2);
+
+        if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
+            throw IEX_NAMESPACE::ArgExc ("Tried to read scan line sample counts outside "
+                               "the image file's data window.");
+
+        for (int i = scanLineMin; i <= scanLineMax; i++)
+        {
+            //
+            // if scanline is already read, it'll be in the cache
+            // otherwise, read from file, store in cache and in caller's framebuffer
+            //
+            if (_data->gotSampleCount[i - _data->minY])
+            {
+                fillSampleCountFromCache(i,_data);
+                                         
+            }else{
+
+                int lineBlockId = ( i - _data->minY ) / _data->linesInBuffer;
+
+                readSampleCountForLineBlock ( _data->_streamData, _data, lineBlockId );
+
+                int minYInLineBuffer = lineBlockId * _data->linesInBuffer + _data->minY;
+                int maxYInLineBuffer = min ( minYInLineBuffer + _data->linesInBuffer - 1, _data->maxY );
+
+                //
+                // For each line within the block, get the count of bytes.
+                //
+
+                bytesPerDeepLineTable ( _data->header,
+                                        minYInLineBuffer,
+                                        maxYInLineBuffer,
+                                        _data->sampleCountSliceBase,
+                                        _data->sampleCountXStride,
+                                        _data->sampleCountYStride,
+                                        _data->bytesPerLine );
+
+                //
+                // For each scanline within the block, get the offset.
+                //
+
+                offsetInLineBufferTable ( _data->bytesPerLine,
+                                          minYInLineBuffer - _data->minY,
+                                          maxYInLineBuffer - _data->minY,
+                                          _data->linesInBuffer,
+                                          _data->offsetInLineBuffer );
+            }
+        }
+
+        _data->_streamData->is->seekg(savedFilePos);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading sample count data from image "
+                     "file \"" << fileName() << "\". " << e.what());
+
+        _data->_streamData->is->seekg(savedFilePos);
+
+        throw;
+    }
+}
+
+void
+DeepScanLineInputFile::readPixelSampleCounts(int scanline)
+{
+    readPixelSampleCounts(scanline, scanline);
+}
+
+int 
+DeepScanLineInputFile::firstScanLineInChunk(int y) const
+{
+    return int((y-_data->minY)/_data->linesInBuffer)*_data->linesInBuffer + _data->minY;
+}
+
+int
+DeepScanLineInputFile::lastScanLineInChunk(int y) const
+{
+    int minY = firstScanLineInChunk(y);
+    return min(minY+_data->linesInBuffer-1,_data->maxY);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineInputFile.h b/3rdparty/openexr/IlmImf/ImfDeepScanLineInputFile.h
new file mode 100644 (file)
index 0000000..7ef9cc2
--- /dev/null
@@ -0,0 +1,294 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEP_SCAN_LINE_INPUT_FILE_H
+#define INCLUDED_IMF_DEEP_SCAN_LINE_INPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfDeepScanLineOutputFile.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class DeepScanLineInputFile : public GenericInputFile
+{
+  public:
+
+    //------------
+    // Constructor
+    //------------
+
+    IMF_EXPORT
+    DeepScanLineInputFile (const char fileName[],
+                           int numThreads = globalThreadCount());
+
+    IMF_EXPORT
+    DeepScanLineInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+                           int version, /*version field from file*/
+                           int numThreads = globalThreadCount());
+
+
+    //-----------------------------------------
+    // Destructor -- deallocates internal data
+    // structures, but does not close the file.
+    //-----------------------------------------
+
+    IMF_EXPORT
+    virtual ~DeepScanLineInputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    IMF_EXPORT
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the InputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readPixels() is called.
+    // The current frame buffer can be changed after each call
+    // to readPixels().
+    //-----------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //---------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window are
+    // present in the input file, or false if any pixels are missing.
+    // (Another program may still be busy writing the file, or file
+    // writing may have been aborted prematurely.)
+    //---------------------------------------------------------------
+
+    IMF_EXPORT
+    bool                isComplete () const;
+
+
+    //---------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readPixels(s1,s2) reads all scan lines with y coordinates
+    // in the interval [min (s1, s2), max (s1, s2)] from the file,
+    // and stores them in the current frame buffer.
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // The scan lines can be read from the file in random order, and
+    // individual scan lines may be skipped or read multiple times.
+    // For maximum efficiency, the scan lines should be read in the
+    // order in which they were written to the file.
+    //
+    // readPixels(s) calls readPixels(s,s).
+    //
+    // If threading is enabled, readPixels (s1, s2) tries to perform
+    // decopmression of multiple scanlines in parallel.
+    //
+    //---------------------------------------------------------------
+
+    IMF_EXPORT
+    void                readPixels (int scanLine1, int scanLine2);
+    IMF_EXPORT
+    void                readPixels (int scanLine);
+
+    
+  
+    //---------------------------------------------------------------
+    // Extract pixel data from pre-read block
+    //
+    // readPixels(rawPixelData,frameBuffer,s1,s2) reads all scan lines with y coordinates
+    // in the interval [min (s1, s2), max (s1, s2)] from the data provided and
+    // stores them in the provided frameBuffer.
+    // the data can be obtained from a call to rawPixelData()
+    //
+    //
+    // Both s1 and s2 must be within the data specified
+    //
+    // you must provide a frameBuffer with a samplecountslice, which must have been read
+    // and the data valid - readPixels uses your sample count buffer to compute
+    // offsets to the data it needs
+    //
+    // This call does not block, and is thread safe for clients with an existing
+    // threading model. The InputFile's frameBuffer is not used in this call.
+    //
+    // This call is only provided for clients which have an existing threading model in place
+    // and unpredictable access patterns to the data.
+    // The fastest way to read an entire image is to enable threading,use setFrameBuffer then
+    // readPixels(header().dataWindow().min.y, header.dataWindow().max.y)
+    //
+    //---------------------------------------------------------------
+    
+    IMF_EXPORT
+    void                readPixels (const char * rawPixelData,
+                                    const DeepFrameBuffer & frameBuffer,
+                                    int scanLine1,
+                                    int scanLine2) const;
+
+    //----------------------------------------------
+    // Read a block of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement OutputFile::copyPixels()).
+    // note: returns the entire payload of the relevant chunk of data, not including part number
+    // including compressed and uncompressed sizes
+    // on entry, if pixelDataSize is insufficiently large, no bytes are read (pixelData can safely be NULL)
+    // on exit, pixelDataSize is the number of bytes required to read the chunk
+    // 
+    //----------------------------------------------
+
+    IMF_EXPORT
+    void                rawPixelData (int firstScanLine,
+                                      char * pixelData,
+                                      Int64 &pixelDataSize);
+
+                                      
+    //-------------------------------------------------
+    // firstScanLineInChunk() returns the row number of the first row that's stored in the
+    // same chunk as scanline y. Depending on the compression mode, this may not be the same as y
+    //
+    // lastScanLineInChunk() returns the row number of the last row that's stored in the same
+    // chunk as scanline y.  Depending on the compression mode, this may not be the same as y.
+    // The last chunk in the file may be smaller than all the others
+    //
+    //------------------------------------------------
+    IMF_EXPORT
+    int                 firstScanLineInChunk(int y) const;
+    IMF_EXPORT
+    int                 lastScanLineInChunk (int y) const;
+                                      
+    //-----------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCounts(s1, s2) reads all the counts of
+    // pixel samples with y coordinates in the interval
+    // [min (s1, s2), max (s1, s2)] from the file, and stores
+    // them in the slice naming "sample count".
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // readPixelSampleCounts(s) calls readPixelSampleCounts(s,s).
+    // 
+    //-----------------------------------------------------------
+
+    IMF_EXPORT
+    void                readPixelSampleCounts (int scanline1,
+                                               int scanline2);
+    IMF_EXPORT
+    void                readPixelSampleCounts (int scanline);
+    
+    
+    //----------------------------------------------------------
+    // Read pixel sample counts into the provided frameBuffer
+    // using a block read of data read by rawPixelData    
+    // for multi-scanline compression schemes, you must decode the entire block
+    // so scanline1=firstScanLineInChunk(y) and scanline2=lastScanLineInChunk(y)
+    // 
+    // This call does not block, and is thread safe for clients with an existing
+    // threading model. The InputFile's frameBuffer is not used in this call.
+    //
+    // The fastest way to read an entire image is to enable threading in OpenEXR, use setFrameBuffer then
+    // readPixelSampleCounts(header().dataWindow().min.y, header.dataWindow().max.y)
+    //
+    //----------------------------------------------------------
+    IMF_EXPORT
+    void                readPixelSampleCounts (const char * rawdata , 
+                                               const DeepFrameBuffer & frameBuffer,
+                                               int scanLine1 , 
+                                               int scanLine2) const;
+
+    struct Data;
+
+  private:
+
+    Data *              _data;
+
+    DeepScanLineInputFile   (InputPartData* part);
+
+    void                initialize(const Header& header);
+    void compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream & is);
+    void multiPartInitialize(InputPartData* part);
+
+    friend class         InputFile;
+    friend class MultiPartInputFile;
+    friend void DeepScanLineOutputFile::copyPixels(DeepScanLineInputFile &);
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineInputPart.cpp b/3rdparty/openexr/IlmImf/ImfDeepScanLineInputPart.cpp
new file mode 100644 (file)
index 0000000..068e1d4
--- /dev/null
@@ -0,0 +1,149 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "ImfDeepScanLineInputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepScanLineInputPart::DeepScanLineInputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<DeepScanLineInputFile>(partNumber);
+}
+
+
+const char *
+DeepScanLineInputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepScanLineInputPart::header () const
+{
+    return file->header();
+}
+
+
+int
+DeepScanLineInputPart::version () const
+{
+    return file->version();
+}
+
+
+void
+DeepScanLineInputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineInputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+bool
+DeepScanLineInputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+
+void
+DeepScanLineInputPart::readPixels (int scanLine1, int scanLine2)
+{
+    file->readPixels(scanLine1, scanLine2);
+}
+
+
+void
+DeepScanLineInputPart::readPixels (int scanLine)
+{
+    file->readPixels(scanLine);
+}
+
+
+void
+DeepScanLineInputPart::rawPixelData (int firstScanLine,
+                                     char *pixelData,
+                                     Int64 &pixelDataSize)
+{
+    file->rawPixelData(firstScanLine, pixelData, pixelDataSize);
+}
+
+
+void
+DeepScanLineInputPart::readPixelSampleCounts(int scanline1,
+                                            int scanline2)
+{
+    file->readPixelSampleCounts(scanline1, scanline2);
+}
+
+
+void
+DeepScanLineInputPart::readPixelSampleCounts(int scanline)
+{
+    file->readPixelSampleCounts(scanline);
+}
+
+int 
+DeepScanLineInputPart::firstScanLineInChunk(int y) const
+{
+    return file->firstScanLineInChunk(y);
+}
+
+int 
+DeepScanLineInputPart::lastScanLineInChunk(int y) const
+{
+    return file->lastScanLineInChunk(y);
+}
+
+void 
+DeepScanLineInputPart::readPixels(const char* rawPixelData, const DeepFrameBuffer& frameBuffer, int scanLine1, int scanLine2) const
+{
+    return file->readPixels(rawPixelData,frameBuffer,scanLine1,scanLine2);
+}
+void 
+DeepScanLineInputPart::readPixelSampleCounts(const char* rawdata, const DeepFrameBuffer& frameBuffer, int scanLine1, int scanLine2) const
+{
+   return file->readPixelSampleCounts(rawdata,frameBuffer,scanLine1,scanLine2);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineInputPart.h b/3rdparty/openexr/IlmImf/ImfDeepScanLineInputPart.h
new file mode 100644 (file)
index 0000000..89245c8
--- /dev/null
@@ -0,0 +1,197 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef IMFDEEPSCANLINEINPUTPART_H_
+#define IMFDEEPSCANLINEINPUTPART_H_
+
+#include "ImfMultiPartInputFile.h"
+#include "ImfDeepScanLineInputFile.h"
+#include "ImfDeepScanLineOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class DeepScanLineInputPart
+{
+  public:
+
+    IMF_EXPORT
+    DeepScanLineInputPart(MultiPartInputFile& file, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    IMF_EXPORT
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the InputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readPixels() is called.
+    // The current frame buffer can be changed after each call
+    // to readPixels().
+    //-----------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //---------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window are
+    // present in the input file, or false if any pixels are missing.
+    // (Another program may still be busy writing the file, or file
+    // writing may have been aborted prematurely.)
+    //---------------------------------------------------------------
+
+    IMF_EXPORT
+    bool                isComplete () const;
+
+
+    //---------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readPixels(s1,s2) reads all scan lines with y coordinates
+    // in the interval [min (s1, s2), max (s1, s2)] from the file,
+    // and stores them in the current frame buffer.
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // The scan lines can be read from the file in random order, and
+    // individual scan lines may be skipped or read multiple times.
+    // For maximum efficiency, the scan lines should be read in the
+    // order in which they were written to the file.
+    //
+    // readPixels(s) calls readPixels(s,s).
+    //
+    // If threading is enabled, readPixels (s1, s2) tries to perform
+    // decopmression of multiple scanlines in parallel.
+    //
+    //---------------------------------------------------------------
+
+    IMF_EXPORT
+    void                readPixels (int scanLine1, int scanLine2);
+    IMF_EXPORT
+    void                readPixels (int scanLine);
+    IMF_EXPORT
+    void                readPixels (const char * rawPixelData,const DeepFrameBuffer & frameBuffer,
+                                    int scanLine1,int scanLine2) const;
+
+    //----------------------------------------------
+    // Read a block of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement OutputFile::copyPixels()).
+    //----------------------------------------------
+
+    IMF_EXPORT
+    void                rawPixelData (int firstScanLine,
+                                      char * pixelData,
+                                      Int64 &pixelDataSize);
+                             
+                                      
+    //-----------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCounts(s1, s2) reads all the counts of
+    // pixel samples with y coordinates in the interval
+    // [min (s1, s2), max (s1, s2)] from the file, and stores
+    // them in the slice naming "sample count".
+    //
+    // Both s1 and s2 must be within the interval
+    // [header().dataWindow().min.y, header.dataWindow().max.y]
+    //
+    // readPixelSampleCounts(s) calls readPixelSampleCounts(s,s).
+    //-----------------------------------------------------------
+
+    IMF_EXPORT
+    void                readPixelSampleCounts(int scanline1,
+                                              int scanline2);
+    IMF_EXPORT
+    void                readPixelSampleCounts(int scanline);
+    
+    IMF_EXPORT
+    void                readPixelSampleCounts( const char * rawdata , const DeepFrameBuffer & frameBuffer,
+                                               int scanLine1 , int scanLine2) const;
+                                               
+    IMF_EXPORT
+    int                 firstScanLineInChunk(int y) const;
+    IMF_EXPORT
+    int                 lastScanLineInChunk (int y) const;
+  private:
+    DeepScanLineInputFile *file;
+    
+    // needed for copyPixels 
+    friend void DeepScanLineOutputFile::copyPixels(DeepScanLineInputPart &);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFDEEPSCANLINEINPUTPART_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputFile.cpp b/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputFile.cpp
new file mode 100644 (file)
index 0000000..5fe0be3
--- /dev/null
@@ -0,0 +1,1554 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepScanLineOutputFile.h>
+#include <ImfDeepScanLineInputFile.h>
+#include <ImfDeepScanLineInputPart.h>
+#include <ImfChannelList.h>
+#include <ImfMisc.h>
+#include <ImfStdIO.h>
+#include <ImfCompressor.h>
+#include "ImathBox.h"
+#include "ImathFun.h"
+#include <ImfArray.h>
+#include <ImfXdr.h>
+#include <ImfPreviewImageAttribute.h>
+#include <ImfPartType.h>
+#include "ImfDeepFrameBuffer.h"
+#include "ImfOutputStreamMutex.h"
+#include "ImfOutputPartData.h"
+
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+#include "Iex.h"
+#include <string>
+#include <vector>
+#include <fstream>
+#include <assert.h>
+#include <algorithm>
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using std::string;
+using std::vector;
+using std::ofstream;
+using std::min;
+using std::max;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+
+struct OutSliceInfo
+{
+    PixelType                    type;
+    const char *                 base;
+    ptrdiff_t                    sampleStride;
+    ptrdiff_t                    xStride;
+    ptrdiff_t                    yStride;
+    int                          xSampling;
+    int                          ySampling;
+    bool                         zero;
+
+    OutSliceInfo (PixelType type = HALF,
+                  const char * base =NULL,
+                  ptrdiff_t sampleStride = 0,
+                  ptrdiff_t xStride = 0,
+                  ptrdiff_t yStride =0,
+                  int xSampling = 1,
+                  int ySampling = 1,
+                  bool zero = false);
+};
+
+
+OutSliceInfo::OutSliceInfo (PixelType t,
+                            const char * base,
+                            ptrdiff_t spstride,
+                            ptrdiff_t xst,
+                            ptrdiff_t yst,
+                            int xsm, int ysm,
+                            bool z)
+:
+    type (t),
+    base (base),
+    sampleStride (spstride),
+    xStride(xst),
+    yStride(yst),
+    xSampling (xsm),
+    ySampling (ysm),
+    zero (z)
+{
+    // empty
+}
+
+
+struct LineBuffer
+{
+    Array< Array<char> >  buffer;
+    Array<char>           consecutiveBuffer;
+    const char *          dataPtr;
+    Int64                 uncompressedDataSize;
+    Int64                 dataSize;
+    Array<char>           sampleCountTableBuffer;
+    const char *          sampleCountTablePtr;
+    Int64                 sampleCountTableSize;
+    Compressor*           sampleCountTableCompressor;
+    int                   minY;                 // the min y scanline stored
+    int                   maxY;                 // the max y scanline stored
+    int                   scanLineMin;          // the min y scanline writing out
+    int                   scanLineMax;          // the max y scanline writing out
+    Compressor *          compressor;
+    bool                  partiallyFull;        // has incomplete data
+    bool                  hasException;
+    string                exception;
+
+    LineBuffer (int linesInBuffer);
+    ~LineBuffer ();
+
+    void                  wait () {_sem.wait();}
+    void                  post () {_sem.post();}
+
+  private:
+
+    Semaphore             _sem;
+};
+
+
+LineBuffer::LineBuffer (int linesInBuffer) :
+    dataPtr (0),
+    dataSize (0),
+    sampleCountTablePtr (0),
+    sampleCountTableCompressor (0),
+    compressor (0),
+    partiallyFull (false),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    buffer.resizeErase(linesInBuffer);
+}
+
+
+LineBuffer::~LineBuffer ()
+{
+    if (compressor != 0)
+        delete compressor;
+
+    if (sampleCountTableCompressor != 0)
+        delete sampleCountTableCompressor;
+}
+
+} // namespace
+
+
+struct DeepScanLineOutputFile::Data
+{
+    Header                      header;                // the image header
+    int                         version;               // file format version
+    bool                        multipart;             // from a multipart file
+    Int64                       previewPosition;       // file position for preview
+    DeepFrameBuffer             frameBuffer;           // framebuffer to write into
+    int                         currentScanLine;       // next scanline to be written
+    int                         missingScanLines;      // number of lines to write
+    LineOrder                   lineOrder;             // the file's lineorder
+    int                         minX;                  // data window's min x coord
+    int                         maxX;                  // data window's max x coord
+    int                         minY;                  // data window's min y coord
+    int                         maxY;                  // data window's max x coord
+    vector<Int64>               lineOffsets;           // stores offsets in file for
+                                                       // each scanline
+    vector<size_t>              bytesPerLine;          // combined size of a line over
+                                                       // all channels
+    Compressor::Format          format;                // compressor's data format
+    vector<OutSliceInfo*>       slices;                // info about channels in file
+    Int64                       lineOffsetsPosition;   // file position for line
+                                                       // offset table
+
+    vector<LineBuffer*>         lineBuffers;           // each holds one line buffer
+    int                         linesInBuffer;         // number of scanlines each
+                                                       // buffer holds
+    int                         partNumber;            // the output part number
+
+    char*                       sampleCountSliceBase;  // the pointer to the number
+                                                       // of samples in each pixel
+    int                         sampleCountXStride;    // the x stride for sampleCountSliceBase
+    int                         sampleCountYStride;    // the y stride for sampleCountSliceBase
+
+    Array<unsigned int>         lineSampleCount;       // the number of samples
+                                                       // in each line
+
+    Int64                       maxSampleCountTableSize;
+                                                       // the max size in bytes for a pixel
+                                                       // sample count table
+    OutputStreamMutex*  _streamData;
+    bool                _deleteStream;
+
+    Data (int numThreads);
+    ~Data ();
+
+
+    inline LineBuffer *         getLineBuffer (int number);// hash function from line
+                                                           // buffer indices into our
+                                                           // vector of line buffers
+
+    inline int&                 getSampleCount(int x, int y); // get the number of samples
+                                                              // in each pixel
+};
+
+
+DeepScanLineOutputFile::Data::Data (int numThreads):
+    lineOffsetsPosition (0),
+    partNumber (-1) ,
+    _streamData(NULL),
+    _deleteStream(false)
+{
+    //
+    // We need at least one lineBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n lineBuffers.
+    //
+
+    lineBuffers.resize (max (1, 2 * numThreads));
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        lineBuffers[i] = 0;
+}
+
+
+DeepScanLineOutputFile::Data::~Data ()
+{
+    for (size_t i = 0; i < lineBuffers.size(); i++)
+        if (lineBuffers[i] != 0)
+            delete lineBuffers[i];
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+}
+
+
+int&
+DeepScanLineOutputFile::Data::getSampleCount(int x, int y)
+{
+    return sampleCount(sampleCountSliceBase,
+                       sampleCountXStride,
+                       sampleCountYStride,
+                       x, y);
+}
+
+
+LineBuffer*
+DeepScanLineOutputFile::Data::getLineBuffer (int number)
+{
+    return lineBuffers[number % lineBuffers.size()];
+}
+
+
+namespace {
+
+Int64
+writeLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const vector<Int64> &lineOffsets)
+{
+    Int64 pos = os.tellp();
+
+    if (pos == -1)
+        IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
+
+    for (unsigned int i = 0; i < lineOffsets.size(); i++)
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, lineOffsets[i]);
+
+    return pos;
+}
+
+
+void
+writePixelData (OutputStreamMutex *filedata,
+                DeepScanLineOutputFile::Data *partdata,
+                int lineBufferMinY,
+                const char pixelData[],
+                Int64 packedDataSize,
+                Int64 unpackedDataSize,
+                const char sampleCountTableData[],
+                Int64 sampleCountTableSize)
+{
+    //
+    // Store a block of pixel data in the output file, and try
+    // to keep track of the current writing position the file
+    // without calling tellp() (tellp() can be fairly expensive).
+    //
+
+    Int64 currentPosition = filedata->currentPosition;
+    filedata->currentPosition = 0;
+
+    if (currentPosition == 0)
+        currentPosition = filedata->os->tellp();
+
+    partdata->lineOffsets[(partdata->currentScanLine - partdata->minY) / partdata->linesInBuffer] =
+        currentPosition;
+
+    #ifdef DEBUG
+
+        assert (filedata->os->tellp() == currentPosition);
+
+    #endif
+
+    //
+    // Write the optional part number.
+    //
+
+    if (partdata->multipart)
+    {
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, partdata->partNumber);
+    }
+
+    //
+    // Write the y coordinate of the first scanline in the chunk.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, lineBufferMinY);
+
+    //
+    // Write the packed size of the pixel sample count table.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, sampleCountTableSize);
+
+    //
+    // Write the packed pixel data size.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, packedDataSize);
+
+    //
+    // Write the unpacked pixel data size.
+    //
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, unpackedDataSize);
+
+    //
+    // Write the packed pixel sample count table.
+    //
+
+    filedata->os->write (sampleCountTableData, sampleCountTableSize);
+
+    //
+    // Write the compressed data.
+    //
+
+    filedata->os->write (pixelData, packedDataSize);
+
+    //
+    // Update stream position.
+    //
+
+    filedata->currentPosition = currentPosition      +
+                                Xdr::size<int>()     +  // y coordinate
+                                Xdr::size<Int64>()   +  // packed sample count table size
+                                Xdr::size<Int64>()   +  // packed data size
+                                Xdr::size<Int64>()   +  // unpacked data size
+                                sampleCountTableSize +  // pixel sample count table
+                                packedDataSize;         // pixel data
+
+    if (partdata->multipart)
+    {
+        filedata->currentPosition += Xdr::size<int>();  // optional part number
+    }
+}
+
+
+inline void
+writePixelData (OutputStreamMutex* filedata,
+                DeepScanLineOutputFile::Data *partdata,
+                const LineBuffer *lineBuffer)
+{
+    writePixelData (filedata, partdata,
+                    lineBuffer->minY,
+                    lineBuffer->dataPtr,
+                    lineBuffer->dataSize,
+                    lineBuffer->uncompressedDataSize,
+                    lineBuffer->sampleCountTablePtr,
+                    lineBuffer->sampleCountTableSize);
+}
+
+
+void
+convertToXdr (DeepScanLineOutputFile::Data *ofd,
+              Array<char> &lineBuffer,
+              int lineBufferMinY,
+              int lineBufferMaxY,
+              int inSize)
+{
+    //
+    // Convert the contents of a lineBuffer from the machine's native
+    // representation to Xdr format.  This function is called by
+    // CompressLineBuffer::execute(), below, if the compressor wanted
+    // its input pixel data in the machine's native format, but then
+    // failed to compress the data (most compressors will expand rather
+    // than compress random input data).
+    //
+    // Note that this routine assumes that the machine's native
+    // representation of the pixel data has the same size as the
+    // Xdr representation.  This makes it possible to convert the
+    // pixel data in place, without an intermediate temporary buffer.
+    //
+
+    //
+    // Iterate over all scanlines in the lineBuffer to convert.
+    //
+
+    char* writePtr = &lineBuffer[0];
+    for (int y = lineBufferMinY; y <= lineBufferMaxY; y++)
+    {
+        //
+        // Set these to point to the start of line y.
+        // We will write to writePtr from readPtr.
+        //
+
+        const char *readPtr = writePtr;
+
+        //
+        // Iterate over all slices in the file.
+        //
+
+        for (unsigned int i = 0; i < ofd->slices.size(); ++i)
+        {
+            //
+            // Test if scan line y of this channel is
+            // contains any data (the scan line contains
+            // data only if y % ySampling == 0).
+            //
+
+            const OutSliceInfo &slice = *ofd->slices[i];
+
+            if (modp (y, slice.ySampling) != 0)
+                continue;
+
+            //
+            // Find the number of sampled pixels, dMaxX-dMinX+1, for
+            // slice i in scan line y (i.e. pixels within the data window
+            // for which x % xSampling == 0).
+            //
+
+            int xSampleCount = ofd->lineSampleCount[y - ofd->minY];
+
+            //
+            // Convert the samples in place.
+            //
+
+            convertInPlace (writePtr, readPtr, slice.type, xSampleCount);
+        }
+    }
+}
+
+
+//
+// A LineBufferTask encapsulates the task of copying a set of scanlines
+// from the user's frame buffer into a LineBuffer object, compressing
+// the data if necessary.
+//
+
+class LineBufferTask: public Task
+{
+  public:
+
+    LineBufferTask (TaskGroup *group,
+                    DeepScanLineOutputFile::Data *ofd,
+                    int number,
+                    int scanLineMin,
+                    int scanLineMax);
+
+    virtual ~LineBufferTask ();
+
+    virtual void        execute ();
+
+  private:
+
+    DeepScanLineOutputFile::Data *  _ofd;
+    LineBuffer *        _lineBuffer;
+};
+
+
+LineBufferTask::LineBufferTask
+    (TaskGroup *group,
+     DeepScanLineOutputFile::Data *ofd,
+     int number,
+     int scanLineMin,
+     int scanLineMax)
+:
+    Task (group),
+    _ofd (ofd),
+    _lineBuffer (_ofd->getLineBuffer(number))
+{
+    //
+    // Wait for the lineBuffer to become available
+    //
+
+    _lineBuffer->wait ();
+
+    //
+    // Initialize the lineBuffer data if necessary
+    //
+
+    if (!_lineBuffer->partiallyFull)
+    {
+
+        _lineBuffer->minY = _ofd->minY + number * _ofd->linesInBuffer;
+
+        _lineBuffer->maxY = min (_lineBuffer->minY + _ofd->linesInBuffer - 1,
+                                 _ofd->maxY);
+
+        _lineBuffer->partiallyFull = true;
+    }
+
+    _lineBuffer->scanLineMin = max (_lineBuffer->minY, scanLineMin);
+    _lineBuffer->scanLineMax = min (_lineBuffer->maxY, scanLineMax);
+}
+
+
+LineBufferTask::~LineBufferTask ()
+{
+    //
+    // Signal that the line buffer is now free
+    //
+
+    _lineBuffer->post ();
+}
+
+
+void
+LineBufferTask::execute ()
+{
+    try
+    {
+        //
+        // First copy the pixel data from the
+        // frame buffer into the line buffer
+        //
+
+        int yStart, yStop, dy;
+
+        if (_ofd->lineOrder == INCREASING_Y)
+        {
+            yStart = _lineBuffer->scanLineMin;
+            yStop = _lineBuffer->scanLineMax + 1;
+            dy = 1;
+        }
+        else
+        {
+            yStart = _lineBuffer->scanLineMax;
+            yStop = _lineBuffer->scanLineMin - 1;
+            dy = -1;
+        }
+
+        //
+        // Allocate buffers for scanlines.
+        // And calculate the sample counts for each line.
+        //
+
+        bytesPerDeepLineTable (_ofd->header,
+                               _lineBuffer->scanLineMin,
+                               _lineBuffer->scanLineMax,
+                               _ofd->sampleCountSliceBase,
+                               _ofd->sampleCountXStride,
+                               _ofd->sampleCountYStride,
+                               _ofd->bytesPerLine);
+        for (int i = _lineBuffer->scanLineMin; i <= _lineBuffer->scanLineMax; i++)
+        {
+            // (TODO) don't do this all the time.
+            _lineBuffer->buffer[i - _lineBuffer->minY].resizeErase(
+                            _ofd->bytesPerLine[i - _ofd->minY]);
+
+            for (int j = _ofd->minX; j <= _ofd->maxX; j++)
+                _ofd->lineSampleCount[i - _ofd->minY] += _ofd->getSampleCount(j, i);
+        }
+
+        //
+        // Copy data from frame buffer to line buffer.
+        //
+
+        int y;
+
+        for (y = yStart; y != yStop; y += dy)
+        {
+            //
+            // Gather one scan line's worth of pixel data and store
+            // them in _ofd->lineBuffer.
+            //
+
+            char *writePtr = &_lineBuffer->buffer[y - _lineBuffer->minY][0];
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ofd->slices.size(); ++i)
+            {
+                //
+                // Test if scan line y of this channel contains any data
+                // (the scan line contains data only if y % ySampling == 0).
+                //
+
+                const OutSliceInfo &slice = *_ofd->slices[i];
+
+                if (modp (y, slice.ySampling) != 0)
+                    continue;
+
+                //
+                // Fill the line buffer with with pixel data.
+                //
+
+                if (slice.zero)
+                {
+                    //
+                    // The frame buffer contains no data for this channel.
+                    // Store zeroes in _lineBuffer->buffer.
+                    //
+
+                    fillChannelWithZeroes (writePtr, _ofd->format, slice.type,
+                                           _ofd->lineSampleCount[y - _ofd->minY]);
+                }
+                else
+                {
+
+                    copyFromDeepFrameBuffer (writePtr, slice.base,
+                                             _ofd->sampleCountSliceBase,
+                                             _ofd->sampleCountXStride,
+                                             _ofd->sampleCountYStride,
+                                             y, _ofd->minX, _ofd->maxX,
+                                             0, 0,//offsets for samplecount
+                                             0, 0,//offsets for data
+                                             slice.sampleStride, 
+                                             slice.xStride,
+                                             slice.yStride,
+                                             _ofd->format,
+                                             slice.type);
+                }
+            }
+        }
+
+        //
+        // If the next scanline isn't past the bounds of the lineBuffer
+        // then we have partially filled the linebuffer,
+        // otherwise the whole linebuffer is filled and then
+        // we compress the linebuffer and write it out.
+        //
+
+        if (y >= _lineBuffer->minY && y <= _lineBuffer->maxY)
+            return;
+
+        //
+        // Copy all data into a consecutive buffer.
+        //
+
+        Int64 totalBytes = 0;
+        Int64 maxBytesPerLine = 0;
+        for (int i = 0; i < _lineBuffer->maxY - _lineBuffer->minY + 1; i++)
+        {
+            totalBytes += _lineBuffer->buffer[i].size();
+            if (Int64(_lineBuffer->buffer[i].size()) > maxBytesPerLine)
+                maxBytesPerLine = _lineBuffer->buffer[i].size();
+        }
+        _lineBuffer->consecutiveBuffer.resizeErase(totalBytes);
+
+        int pos = 0;
+        for (int i = 0; i < _lineBuffer->maxY - _lineBuffer->minY + 1; i++)
+        {
+            memcpy(_lineBuffer->consecutiveBuffer + pos,
+                   &_lineBuffer->buffer[i][0],
+                   _lineBuffer->buffer[i].size());
+            pos += _lineBuffer->buffer[i].size();
+        }
+
+        _lineBuffer->dataPtr = _lineBuffer->consecutiveBuffer;
+
+        _lineBuffer->dataSize = totalBytes;
+        _lineBuffer->uncompressedDataSize = _lineBuffer->dataSize;
+
+        //
+        // Compress the pixel sample count table.
+        //
+
+        char* ptr = _lineBuffer->sampleCountTableBuffer;
+        Int64 tableDataSize = 0;
+        for (int i = _lineBuffer->minY; i <= _lineBuffer->maxY; i++)
+        {
+            int count = 0;
+            for (int j = _ofd->minX; j <= _ofd->maxX; j++)
+            {
+                count += _ofd->getSampleCount(j, i);
+                Xdr::write <CharPtrIO> (ptr, count);
+                tableDataSize += sizeof (int);
+            }
+        }
+
+       if(_lineBuffer->sampleCountTableCompressor)
+       {
+          _lineBuffer->sampleCountTableSize =
+                  _lineBuffer->sampleCountTableCompressor->compress (
+                                                      _lineBuffer->sampleCountTableBuffer,
+                                                      tableDataSize,
+                                                      _lineBuffer->minY,
+                                                      _lineBuffer->sampleCountTablePtr);
+       }
+
+        //
+        // If we can't make data shrink (or we weren't compressing), then just use the raw data.
+        //
+
+        if (!_lineBuffer->sampleCountTableCompressor || 
+            _lineBuffer->sampleCountTableSize >= tableDataSize)
+        {
+            _lineBuffer->sampleCountTableSize = tableDataSize;
+            _lineBuffer->sampleCountTablePtr = _lineBuffer->sampleCountTableBuffer;
+        }
+
+        //
+        // Compress the sample data
+        //
+
+        // (TODO) don't do this all the time.
+        if (_lineBuffer->compressor != 0)
+            delete _lineBuffer->compressor;
+        _lineBuffer->compressor = newCompressor (_ofd->header.compression(),
+                                                 maxBytesPerLine,
+                                                 _ofd->header);
+
+        Compressor *compressor = _lineBuffer->compressor;
+
+        if (compressor)
+        {
+            const char *compPtr;
+
+            Int64 compSize = compressor->compress (_lineBuffer->dataPtr,
+                                                 _lineBuffer->dataSize,
+                                                 _lineBuffer->minY, compPtr);
+
+            if (compSize < _lineBuffer->dataSize)
+            {
+                _lineBuffer->dataSize = compSize;
+                _lineBuffer->dataPtr = compPtr;
+            }
+            else if (_ofd->format == Compressor::NATIVE)
+            {
+                //
+                // The data did not shrink during compression, but
+                // we cannot write to the file using the machine's
+                // native format, so we need to convert the lineBuffer
+                // to Xdr.
+                //
+
+                convertToXdr (_ofd, _lineBuffer->consecutiveBuffer, _lineBuffer->minY,
+                              _lineBuffer->maxY, _lineBuffer->dataSize);
+            }
+        }
+
+        _lineBuffer->partiallyFull = false;
+    }
+    catch (std::exception &e)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = e.what ();
+            _lineBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = "unrecognized exception";
+            _lineBuffer->hasException = true;
+        }
+    }
+}
+
+} // namespace
+
+
+DeepScanLineOutputFile::DeepScanLineOutputFile
+    (const char fileName[],
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+{
+    _data->_streamData=new OutputStreamMutex ();
+    _data->_deleteStream=true;
+    try
+    {
+        header.sanityCheck();
+        _data->_streamData->os = new StdOFStream (fileName);
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition =
+                _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+                writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+        _data->multipart=false;// not multipart; only one header
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data->_streamData->os;
+        delete _data->_streamData;
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data->_streamData->os;
+        delete _data->_streamData;
+        delete _data;
+        throw;
+    }
+}
+
+
+DeepScanLineOutputFile::DeepScanLineOutputFile
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+    
+{
+    _data->_streamData   = new OutputStreamMutex ();
+    _data->_deleteStream = false;
+    try
+    {
+        header.sanityCheck();
+        _data->_streamData->os = &os;
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition =
+                _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+                writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+       _data->multipart=false;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data->_streamData;
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << os.fileName() << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data->_streamData;
+        delete _data;
+        throw;
+    }
+}
+
+DeepScanLineOutputFile::DeepScanLineOutputFile(const OutputPartData* part)
+{
+    try
+    {
+        if (part->header.type() != DEEPSCANLINE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a DeepScanLineOutputFile from a type-mismatched part.");
+
+        _data = new Data (part->numThreads);
+        _data->_streamData = part->mutex;
+        _data->_deleteStream=false;
+        initialize (part->header);
+        _data->partNumber = part->partNumber;
+        _data->lineOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+       _data->multipart=part->multipart;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                     "\"" << part->partNumber << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+void
+DeepScanLineOutputFile::initialize (const Header &header)
+{
+    _data->header = header;
+
+    _data->header.setType(DEEPSCANLINE);
+    
+    const Box2i &dataWindow = header.dataWindow();
+
+    _data->currentScanLine = (header.lineOrder() == INCREASING_Y)?
+                                 dataWindow.min.y: dataWindow.max.y;
+
+    _data->missingScanLines = dataWindow.max.y - dataWindow.min.y + 1;
+    _data->lineOrder = header.lineOrder();
+    _data->minX = dataWindow.min.x;
+    _data->maxX = dataWindow.max.x;
+    _data->minY = dataWindow.min.y;
+    _data->maxY = dataWindow.max.y;
+
+    _data->lineSampleCount.resizeErase(_data->maxY - _data->minY + 1);
+
+    Compressor* compressor = newCompressor (_data->header.compression(),
+                                            0,
+                                            _data->header);
+    _data->format = defaultFormat (compressor);
+    _data->linesInBuffer = numLinesInBuffer (compressor);
+    if (compressor != 0)
+        delete compressor;
+
+    int lineOffsetSize = (_data->maxY - _data->minY +
+                          _data->linesInBuffer) / _data->linesInBuffer;
+
+
+    _data->header.setChunkCount(lineOffsetSize);
+
+    _data->lineOffsets.resize (lineOffsetSize);
+
+    _data->bytesPerLine.resize (_data->maxY - _data->minY + 1);
+
+    _data->maxSampleCountTableSize = min(_data->linesInBuffer, _data->maxY - _data->minY + 1) *
+                                     (_data->maxX - _data->minX + 1) *
+                                     sizeof(unsigned int);
+
+    for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+    {
+        _data->lineBuffers[i] = new LineBuffer (_data->linesInBuffer);
+        _data->lineBuffers[i]->sampleCountTableBuffer.resizeErase(_data->maxSampleCountTableSize);
+
+        _data->lineBuffers[i]->sampleCountTableCompressor =
+        newCompressor (_data->header.compression(),
+                               _data->maxSampleCountTableSize,
+                               _data->header);
+    }
+}
+
+
+DeepScanLineOutputFile::~DeepScanLineOutputFile ()
+{
+    {
+        Lock lock(*_data->_streamData);
+        Int64 originalPosition = _data->_streamData->os->tellp();
+
+        if (_data->lineOffsetsPosition > 0)
+        {
+            try
+            {
+                _data->_streamData->os->seekp (_data->lineOffsetsPosition);
+                writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+
+                //
+                // Restore the original position.
+                //
+                _data->_streamData->os->seekp (originalPosition);
+            }
+            catch (...)
+            {
+                //
+                // We cannot safely throw any exceptions from here.
+                // This destructor may have been called because the
+                // stack is currently being unwound for another
+                // exception.
+                //
+            }
+        }
+    }
+
+    if (_data->_deleteStream)
+        delete _data->_streamData->os;
+
+    //
+    // (TODO) we should have a way to tell if the stream data is owned by this file or
+    // by a parent multipart file.
+    //
+
+    if (_data->partNumber == -1)
+        delete _data->_streamData;
+
+    delete _data;
+}
+
+
+const char *
+DeepScanLineOutputFile::fileName () const
+{
+    return _data->_streamData->os->fileName();
+}
+
+
+const Header &
+DeepScanLineOutputFile::header () const
+{
+    return _data->header;
+}
+
+
+void
+DeepScanLineOutputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    //
+    // Check if the new frame buffer descriptor
+    // is compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+            continue;
+
+        if (i.channel().type != j.slice().type)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+                                "of output file \"" << fileName() << "\" is "
+                                "not compatible with the frame buffer's "
+                                "pixel type.");
+        }
+
+        if (i.channel().xSampling != j.slice().xSampling ||
+            i.channel().ySampling != j.slice().ySampling)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                                "of \"" << i.name() << "\" channel "
+                                "of output file \"" << fileName() << "\" are "
+                                "not compatible with the frame buffer's "
+                                "subsampling factors.");
+        }
+    }
+
+    //
+    // Store the pixel sample count table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+    }
+
+    //
+    // Initialize slice table for writePixels().
+    // Pixel sample count slice is not presented in the header,
+    // so it wouldn't be added here.
+    // Store the pixel base pointer table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    vector<OutSliceInfo*> slices;
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+        {
+            //
+            // Channel i is not present in the frame buffer.
+            // In the file, channel i will contain only zeroes.
+            //
+
+            slices.push_back (new OutSliceInfo (i.channel().type,
+                                                NULL,// base
+                                                0,// sampleStride,
+                                                0,// xStride
+                                                0,// yStride
+                                                i.channel().xSampling,
+                                                i.channel().ySampling,
+                                                true)); // zero
+        }
+        else
+        {
+            //
+            // Channel i is present in the frame buffer.
+            //
+
+            slices.push_back (new OutSliceInfo (j.slice().type,
+                                                j.slice().base,                      
+                                                j.slice().sampleStride,
+                                                j.slice().xStride,
+                                                j.slice().yStride,
+                                                j.slice().xSampling,
+                                                j.slice().ySampling,
+                                                false)); // zero
+
+        }
+    }
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineOutputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+void
+DeepScanLineOutputFile::writePixels (int numScanLines)
+{
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data source.");
+
+        //
+        // Maintain two iterators:
+        //     nextWriteBuffer: next linebuffer to be written to the file
+        //     nextCompressBuffer: next linebuffer to compress
+        //
+
+        int first = (_data->currentScanLine - _data->minY) /
+                         _data->linesInBuffer;
+
+        int nextWriteBuffer = first;
+        int nextCompressBuffer;
+        int stop;
+        int step;
+        int scanLineMin;
+        int scanLineMax;
+
+        {
+            //
+            // Create a task group for all line buffer tasks. When the
+            // taskgroup goes out of scope, the destructor waits until
+            // all tasks are complete.
+            //
+
+            TaskGroup taskGroup;
+
+            //
+            // Determine the range of lineBuffers that intersect the scan
+            // line range.  Then add the initial compression tasks to the
+            // thread pool.  We always add in at least one task but the
+            // individual task might not do anything if numScanLines == 0.
+            //
+
+            if (_data->lineOrder == INCREASING_Y)
+            {
+                int last = (_data->currentScanLine + (numScanLines - 1) -
+                            _data->minY) / _data->linesInBuffer;
+
+                scanLineMin = _data->currentScanLine;
+                scanLineMax = _data->currentScanLine + numScanLines - 1;
+
+                int numTasks = max (min ((int)_data->lineBuffers.size(),
+                                         last - first + 1),
+                                    1);
+
+                for (int i = 0; i < numTasks; i++)
+                {
+                    ThreadPool::addGlobalTask
+                        (new LineBufferTask (&taskGroup, _data, first + i,
+                                             scanLineMin, scanLineMax));
+                }
+
+                nextCompressBuffer = first + numTasks;
+                stop = last + 1;
+                step = 1;
+            }
+            else
+            {
+                int last = (_data->currentScanLine - (numScanLines - 1) -
+                            _data->minY) / _data->linesInBuffer;
+
+                scanLineMax = _data->currentScanLine;
+                scanLineMin = _data->currentScanLine - numScanLines + 1;
+
+                int numTasks = max (min ((int)_data->lineBuffers.size(),
+                                         first - last + 1),
+                                    1);
+
+                for (int i = 0; i < numTasks; i++)
+                {
+                    ThreadPool::addGlobalTask
+                        (new LineBufferTask (&taskGroup, _data, first - i,
+                                             scanLineMin, scanLineMax));
+                }
+
+                nextCompressBuffer = first - numTasks;
+                stop = last - 1;
+                step = -1;
+            }
+
+            while (true)
+            {
+                if (_data->missingScanLines <= 0)
+                {
+                    throw IEX_NAMESPACE::ArgExc ("Tried to write more scan lines "
+                                       "than specified by the data window.");
+                }
+
+                //
+                // Wait until the next line buffer is ready to be written
+                //
+
+                LineBuffer *writeBuffer =
+                    _data->getLineBuffer (nextWriteBuffer);
+
+                writeBuffer->wait();
+
+                int numLines = writeBuffer->scanLineMax -
+                               writeBuffer->scanLineMin + 1;
+
+                _data->missingScanLines -= numLines;
+
+                //
+                // If the line buffer is only partially full, then it is
+                // not complete and we cannot write it to disk yet.
+                //
+
+                if (writeBuffer->partiallyFull)
+                {
+                    _data->currentScanLine = _data->currentScanLine +
+                                             step * numLines;
+                    writeBuffer->post();
+
+                    return;
+                }
+
+                //
+                // Write the line buffer
+                //
+
+                writePixelData (_data->_streamData, _data, writeBuffer);
+                nextWriteBuffer += step;
+
+                _data->currentScanLine = _data->currentScanLine +
+                                         step * numLines;
+
+                #ifdef DEBUG
+
+                    assert (_data->currentScanLine ==
+                            ((_data->lineOrder == INCREASING_Y) ?
+                             writeBuffer->scanLineMax + 1:
+                             writeBuffer->scanLineMin - 1));
+
+                #endif
+
+                //
+                // Release the lock on the line buffer
+                //
+
+                writeBuffer->post();
+
+                //
+                // If this was the last line buffer in the scanline range
+                //
+
+                if (nextWriteBuffer == stop)
+                    break;
+
+                //
+                // If there are no more line buffers to compress,
+                // then only continue to write out remaining lineBuffers
+                //
+
+                if (nextCompressBuffer == stop)
+                    continue;
+
+                //
+                // Add nextCompressBuffer as a compression task
+                //
+
+                ThreadPool::addGlobalTask
+                    (new LineBufferTask (&taskGroup, _data, nextCompressBuffer,
+                                         scanLineMin, scanLineMax));
+
+                //
+                // Update the next line buffer we need to compress
+                //
+
+                nextCompressBuffer += step;
+            }
+
+            //
+            // Finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // LineBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to OutputFile::writePixels().
+        // LineBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the line buffers.
+        // Now we check if any line buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple line buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+        {
+            LineBuffer *lineBuffer = _data->lineBuffers[i];
+
+            if (lineBuffer->hasException && !exception)
+                exception = &lineBuffer->exception;
+
+            lineBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Failed to write pixel data to image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+int
+DeepScanLineOutputFile::currentScanLine () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->currentScanLine;
+}
+
+
+void
+DeepScanLineOutputFile::copyPixels (DeepScanLineInputPart &in)
+{
+    copyPixels(*in.file);
+}
+
+void
+DeepScanLineOutputFile::copyPixels (DeepScanLineInputFile &in)
+{
+
+    Lock lock (*_data->_streamData);
+
+    //
+    // Check if this file's and and the InputFile's
+    // headers are compatible.
+    //
+
+    const Header &hdr = _data->header;
+    const Header &inHdr = in.header();
+
+    if(!inHdr.hasType() || inHdr.type()!=DEEPSCANLINE)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\": the input needs to be a deep scanline image");
+    }
+    if (!(hdr.dataWindow() == inHdr.dataWindow()))
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\". "
+                            "The files have different data windows.");
+
+    if (!(hdr.lineOrder() == inHdr.lineOrder()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files have different line orders.");
+
+    if (!(hdr.compression() == inHdr.compression()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files use different compression methods.");
+
+    if (!(hdr.channels() == inHdr.channels()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed.  "
+                            "The files have different channel lists.");
+
+    //
+    // Verify that no pixel data have been written to this file yet.
+    //
+
+    const Box2i &dataWindow = hdr.dataWindow();
+
+    if (_data->missingScanLines != dataWindow.max.y - dataWindow.min.y + 1)
+        THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
+                              "file \"" << in.fileName() << "\" to image "
+                              "file \"" << fileName() << "\" failed. "
+                              "\"" << fileName() << "\" already contains "
+                              "pixel data.");
+
+    //
+    // Copy the pixel data.
+    //
+
+    vector<char> data(4096);
+    
+    while (_data->missingScanLines > 0)
+    {
+        Int64 dataSize = (Int64) data.size();
+        in.rawPixelData(_data->currentScanLine, &data[0], dataSize);
+        if(dataSize > data.size())
+        {
+            // block wasn't big enough - go again with enough memory this time
+            data.resize(dataSize);
+            in.rawPixelData(_data->currentScanLine, &data[0], dataSize);
+        }
+
+        // extract header from block to pass to writePixelData
+        
+        Int64 packedSampleCountSize = *(Int64 *) (&data[4]);
+        Int64 packedDataSize = *(Int64 *) (&data[12]);
+        Int64 unpackedDataSize = *(Int64 *) (&data[20]);
+        const char * sampleCountTable = &data[0]+28;
+        const char * pixelData = sampleCountTable + packedSampleCountSize;
+        
+        
+        writePixelData (_data->_streamData, _data, lineBufferMinY (_data->currentScanLine,
+                                               _data->minY,
+                                               _data->linesInBuffer),
+                        pixelData, packedDataSize, unpackedDataSize,sampleCountTable,packedSampleCountSize);
+
+        _data->currentScanLine += (_data->lineOrder == INCREASING_Y)?
+                                   _data->linesInBuffer: -_data->linesInBuffer;
+
+        _data->missingScanLines -= _data->linesInBuffer;
+    }
+}
+
+
+void
+DeepScanLineOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    Lock lock (*_data->_streamData);
+
+    if (_data->previewPosition <= 0)
+        THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
+                              "File \"" << fileName() << "\" does not "
+                              "contain a preview image.");
+
+    //
+    // Store the new pixels in the header's preview image attribute.
+    //
+
+    PreviewImageAttribute &pia =
+        _data->header.typedAttribute <PreviewImageAttribute> ("preview");
+
+    PreviewImage &pi = pia.value();
+    PreviewRgba *pixels = pi.pixels();
+    int numPixels = pi.width() * pi.height();
+
+    for (int i = 0; i < numPixels; ++i)
+        pixels[i] = newPixels[i];
+
+    //
+    // Save the current file position, jump to the position in
+    // the file where the preview image starts, store the new
+    // preview image, and jump back to the saved file position.
+    //
+
+    Int64 savedPosition = _data->_streamData->os->tellp();
+
+    try
+    {
+        _data->_streamData->os->seekp (_data->previewPosition);
+        pia.writeValueTo (*_data->_streamData->os, _data->version);
+        _data->_streamData->os->seekp (savedPosition);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Cannot update preview image pixels for "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputFile.h b/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputFile.h
new file mode 100644 (file)
index 0000000..945b00d
--- /dev/null
@@ -0,0 +1,256 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef INCLUDED_IMF_DEEP_SCAN_LINE_OUTPUT_FILE_H
+#define INCLUDED_IMF_DEEP_SCAN_LINE_OUTPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepScanLineOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+struct PreviewRgba;
+
+class DeepScanLineOutputFile : public GenericOutputFile
+{
+  public:
+
+    //-----------------------------------------------------------
+    // Constructor -- opens the file and writes the file header.
+    // The file header is also copied into the DeepScanLineOutputFile
+    // object, and can later be accessed via the header() method.
+    // Destroying this DeepScanLineOutputFile object automatically closes
+    // the file.
+    //
+    // numThreads determines the number of threads that will be
+    // used to write the file (see ImfThreading.h).
+    //-----------------------------------------------------------
+
+    IMF_EXPORT
+    DeepScanLineOutputFile (const char fileName[], const Header &header,
+                int numThreads = globalThreadCount());
+
+
+    //------------------------------------------------------------
+    // Constructor -- attaches the new DeepScanLineOutputFile object
+    // to a file that has already been opened, and writes the file header.
+    // The file header is also copied into the DeepScanLineOutputFile
+    // object, and can later be accessed via the header() method.
+    // Destroying this DeepScanLineOutputFile object does not automatically
+    // close the file.
+    //
+    // numThreads determines the number of threads that will be
+    // used to write the file (see ImfThreading.h).
+    //------------------------------------------------------------
+
+    IMF_EXPORT
+    DeepScanLineOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const Header &header,
+                int numThreads = globalThreadCount());
+
+
+    //-------------------------------------------------
+    // Destructor
+    //
+    // Destroying the DeepScanLineOutputFile object
+    // before writing all scan lines within the data
+    // window results in an incomplete file.
+    //-------------------------------------------------
+
+    IMF_EXPORT
+    virtual ~DeepScanLineOutputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the OutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writePixels() is
+    // called.  The current frame buffer can be changed
+    // after each call to writePixels.
+    //-------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writePixels(n) retrieves the next n scan lines worth of data from
+    // the current frame buffer, starting with the scan line indicated by
+    // currentScanLine(), and stores the data in the output file, and
+    // progressing in the direction indicated by header.lineOrder().
+    //
+    // To produce a complete and correct file, exactly m scan lines must
+    // be written, where m is equal to
+    // header().dataWindow().max.y - header().dataWindow().min.y + 1.
+    //-------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                writePixels (int numScanLines = 1);
+
+
+    //------------------------------------------------------------------
+    // Access to the current scan line:
+    //
+    // currentScanLine() returns the y coordinate of the first scan line
+    // that will be read from the current frame buffer during the next
+    // call to writePixels().
+    //
+    // If header.lineOrder() == INCREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().min.y.  After writing each scan line,
+    //  the current scan line is incremented by 1.
+    //
+    // If header.lineOrder() == DECREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().max.y.  After writing each scan line,
+    //  the current scan line is decremented by 1.
+    //
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 currentScanLine () const;
+
+
+    //--------------------------------------------------------------
+    // Shortcut to copy all pixels from an InputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the InputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder" and "channels" attributes must be the same.
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    void                copyPixels (DeepScanLineInputFile &in);
+    
+    // --------------------------------------------------------------
+    // Shortcut to copy pixels from a given part of a multipart file
+    // --------------------------------------------------------------
+    IMF_EXPORT
+    void                copyPixels (DeepScanLineInputPart &in);
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few scan lines at a
+    // time, while the image is being generated.  Since the preview
+    // image is an attribute in the file's header, it gets stored in
+    // the file as soon as the file is opened, but we may not know
+    // what the preview image should look like until we have written
+    // the last scan line of the main image.
+    //
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+
+    struct Data;
+
+  private:
+
+    //------------------------------------------------------------
+    // Constructor -- attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    //------------------------------------------------------------
+    DeepScanLineOutputFile (const OutputPartData* part);
+
+    DeepScanLineOutputFile (const DeepScanLineOutputFile &);                    // not implemented
+    DeepScanLineOutputFile & operator = (const DeepScanLineOutputFile &);       // not implemented
+
+    void                initialize (const Header &header);
+    void                initializeLineBuffer();
+
+    Data *              _data;
+
+
+
+    friend class MultiPartOutputFile;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputPart.cpp b/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputPart.cpp
new file mode 100644 (file)
index 0000000..d7a44e8
--- /dev/null
@@ -0,0 +1,107 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepScanLineOutputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepScanLineOutputPart::DeepScanLineOutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<DeepScanLineOutputFile>(partNumber);
+}
+
+
+const char *
+DeepScanLineOutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepScanLineOutputPart::header () const
+{
+    return file->header();
+}
+
+
+void
+DeepScanLineOutputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepScanLineOutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+void
+DeepScanLineOutputPart::writePixels (int numScanLines)
+{
+    file->writePixels(numScanLines);
+}
+
+
+int
+DeepScanLineOutputPart::currentScanLine () const
+{
+    return file->currentScanLine();
+}
+
+
+void
+DeepScanLineOutputPart::copyPixels (DeepScanLineInputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+DeepScanLineOutputPart::copyPixels (DeepScanLineInputPart &in)
+{
+    file->copyPixels(in);
+}
+
+void
+DeepScanLineOutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
diff --git a/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputPart.h b/3rdparty/openexr/IlmImf/ImfDeepScanLineOutputPart.h
new file mode 100644 (file)
index 0000000..22faa25
--- /dev/null
@@ -0,0 +1,178 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFDEEPSCANLINEOUTPUTPART_H_
+#define IMFDEEPSCANLINEOUTPUTPART_H_
+
+#include "ImfDeepScanLineOutputFile.h"
+#include "ImfMultiPartOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class DeepScanLineOutputPart
+{
+  public:
+
+    IMF_EXPORT
+    DeepScanLineOutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the OutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writePixels() is
+    // called.  The current frame buffer can be changed
+    // after each call to writePixels.
+    //-------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writePixels(n) retrieves the next n scan lines worth of data from
+    // the current frame buffer, starting with the scan line indicated by
+    // currentScanLine(), and stores the data in the output file, and
+    // progressing in the direction indicated by header.lineOrder().
+    //
+    // To produce a complete and correct file, exactly m scan lines must
+    // be written, where m is equal to
+    // header().dataWindow().max.y - header().dataWindow().min.y + 1.
+    //-------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                writePixels (int numScanLines = 1);
+
+
+    //------------------------------------------------------------------
+    // Access to the current scan line:
+    //
+    // currentScanLine() returns the y coordinate of the first scan line
+    // that will be read from the current frame buffer during the next
+    // call to writePixels().
+    //
+    // If header.lineOrder() == INCREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().min.y.  After writing each scan line,
+    //  the current scan line is incremented by 1.
+    //
+    // If header.lineOrder() == DECREASING_Y:
+    //
+    //  The current scan line before the first call to writePixels()
+    //  is header().dataWindow().max.y.  After writing each scan line,
+    //  the current scan line is decremented by 1.
+    //
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 currentScanLine () const;
+
+
+    //--------------------------------------------------------------
+    // Shortcut to copy all pixels from an InputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the InputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder" and "channels" attributes must be the same.
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    void                copyPixels (DeepScanLineInputFile &in);
+    IMF_EXPORT
+    void                copyPixels (DeepScanLineInputPart &in);
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few scan lines at a
+    // time, while the image is being generated.  Since the preview
+    // image is an attribute in the file's header, it gets stored in
+    // the file as soon as the file is opened, but we may not know
+    // what the preview image should look like until we have written
+    // the last scan line of the main image.
+    //
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+  private:
+      DeepScanLineOutputFile* file;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFDEEPSCANLINEOUTPUTPART_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledInputFile.cpp b/3rdparty/openexr/IlmImf/ImfDeepTiledInputFile.cpp
new file mode 100644 (file)
index 0000000..e34f606
--- /dev/null
@@ -0,0 +1,1979 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include <ImfDeepTiledInputFile.h>
+#include <ImfTileDescriptionAttribute.h>
+#include <ImfChannelList.h>
+#include <ImfMisc.h>
+#include <ImfTiledMisc.h>
+#include <ImfStdIO.h>
+#include <ImfCompressor.h>
+#include "ImathBox.h"
+#include <ImfXdr.h>
+#include <ImfConvert.h>
+#include <ImfVersion.h>
+#include <ImfTileOffsets.h>
+#include <ImfThreading.h>
+#include <ImfPartType.h>
+#include <ImfMultiPartInputFile.h>
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+#include "ImathVec.h"
+#include "Iex.h"
+#include <string>
+#include <vector>
+#include <algorithm>
+#include <assert.h>
+#include <limits>
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using std::string;
+using std::vector;
+using std::min;
+using std::max;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+struct TInSliceInfo
+{
+    PixelType           typeInFrameBuffer;
+    PixelType           typeInFile;
+    char*               pointerArrayBase;
+    size_t              xStride;
+    size_t              yStride;
+    ptrdiff_t           sampleStride;
+    bool                fill;
+    bool                skip;
+    double              fillValue;
+    int                 xTileCoords;
+    int                 yTileCoords;
+
+    TInSliceInfo (PixelType typeInFrameBuffer = HALF,
+                  char * base = NULL,
+                  PixelType typeInFile = HALF,
+                  size_t xStride = 0,
+                  size_t yStride = 0,
+                  ptrdiff_t sampleStride = 0,
+                  bool fill = false,
+                  bool skip = false,
+                  double fillValue = 0.0,
+                  int xTileCoords = 0,
+                  int yTileCoords = 0);
+};
+
+
+TInSliceInfo::TInSliceInfo (PixelType tifb,
+                            char * b,
+                            PixelType tifl,
+                            size_t xs, size_t ys,
+                            ptrdiff_t spst,
+                            bool f, bool s,
+                            double fv,
+                            int xtc,
+                            int ytc)
+:
+    typeInFrameBuffer (tifb),
+    typeInFile (tifl),
+    pointerArrayBase (b),
+    xStride (xs),
+    yStride (ys),
+    sampleStride (spst),
+    fill (f),
+    skip (s),
+    fillValue (fv),
+    xTileCoords (xtc),
+    yTileCoords (ytc)
+{
+    // empty
+}
+
+
+struct TileBuffer
+{
+    Array2D<unsigned int>       sampleCount;
+    const char *                uncompressedData;
+    char *                      buffer;
+    Int64                         dataSize;
+    Int64                         uncompressedDataSize;
+    Compressor *                compressor;
+    Compressor::Format          format;
+    int                         dx;
+    int                         dy;
+    int                         lx;
+    int                         ly;
+    bool                        hasException;
+    string                      exception;
+
+     TileBuffer ();
+    ~TileBuffer ();
+
+    inline void         wait () {_sem.wait();}
+    inline void         post () {_sem.post();}
+
+ protected:
+
+    Semaphore _sem;
+};
+
+
+TileBuffer::TileBuffer ():
+    uncompressedData (0),
+    buffer (0),
+    dataSize (0),
+    compressor (0),
+    format (defaultFormat (compressor)),
+    dx (-1),
+    dy (-1),
+    lx (-1),
+    ly (-1),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    // empty
+}
+
+
+TileBuffer::~TileBuffer ()
+{
+    delete compressor;
+}
+
+} // namespace
+
+
+class MultiPartInputFile;
+
+
+//
+// struct TiledInputFile::Data stores things that will be
+// needed between calls to readTile()
+//
+
+struct DeepTiledInputFile::Data: public Mutex
+{
+    Header          header;                         // the image header
+    TileDescription tileDesc;                       // describes the tile layout
+    int             version;                        // file's version
+    DeepFrameBuffer frameBuffer;                    // framebuffer to write into
+    LineOrder       lineOrder;                      // the file's lineorder
+    int             minX;                           // data window's min x coord
+    int             maxX;                           // data window's max x coord
+    int             minY;                           // data window's min y coord
+    int             maxY;                           // data window's max x coord
+
+    int             numXLevels;                     // number of x levels
+    int             numYLevels;                     // number of y levels
+    int *           numXTiles;                      // number of x tiles at a level
+    int *           numYTiles;                      // number of y tiles at a level
+
+    TileOffsets     tileOffsets;                    // stores offsets in file for
+    // each tile
+
+    bool            fileIsComplete;                 // True if no tiles are missing
+                                                    // in the file
+
+    vector<TInSliceInfo*> slices;                    // info about channels in file
+
+                                                    // ourselves? or does someone
+                                                    // else do it?
+
+    int             partNumber;                     // part number
+
+    bool            multiPartBackwardSupport;       // if we are reading a multipart file
+                                                    // using OpenEXR 1.7 API
+
+    int             numThreads;                     // number of threads
+
+    MultiPartInputFile* multiPartFile;              // the MultiPartInputFile used to
+                                                    // support backward compatibility
+
+    vector<TileBuffer*> tileBuffers;                // each holds a single tile
+
+    bool            memoryMapped;                   // if the stream is memory mapped
+
+    char*           sampleCountSliceBase;           // pointer to the start of
+                                                    // the sample count array
+    ptrdiff_t       sampleCountXStride;             // x stride of the sample count array
+    ptrdiff_t       sampleCountYStride;             // y stride of the sample count array
+
+    int             sampleCountXTileCoords;         // the value of xTileCoords from the
+                                                    // sample count slice
+    int             sampleCountYTileCoords;         // the value of yTileCoords from the
+                                                    // sample count slice
+
+    Array<char>     sampleCountTableBuffer;         // the buffer for sample count table
+
+    Compressor*     sampleCountTableComp;           // the decompressor for sample count table
+
+    Int64           maxSampleCountTableSize;        // the max size in bytes for a pixel
+                                                    // sample count table
+    int             combinedSampleSize;             // total size of all channels combined to check sampletable size
+                                                    
+    InputStreamMutex *  _streamData;
+    bool                _deleteStream; // should we delete the stream
+     Data (int numThreads);
+    ~Data ();
+
+    inline TileBuffer * getTileBuffer (int number);
+                                                    // hash function from tile indices
+                                                    // into our vector of tile buffers
+
+    int&                getSampleCount(int x, int y);
+                                                    // get the number of samples
+                                                    // in each pixel
+};
+
+
+DeepTiledInputFile::Data::Data (int numThreads):
+    numXTiles (0),
+    numYTiles (0),
+    partNumber (-1),
+    multiPartBackwardSupport(false),
+    numThreads(numThreads),
+    memoryMapped(false),
+    _streamData(NULL),
+    _deleteStream(false)
+{
+    //
+    // We need at least one tileBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n tileBuffers
+    //
+
+    tileBuffers.resize (max (1, 2 * numThreads));
+}
+
+
+DeepTiledInputFile::Data::~Data ()
+{
+    delete [] numXTiles;
+    delete [] numYTiles;
+
+    for (size_t i = 0; i < tileBuffers.size(); i++)
+        delete tileBuffers[i];
+
+    if (multiPartBackwardSupport)
+        delete multiPartFile;
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+}
+
+
+TileBuffer*
+DeepTiledInputFile::Data::getTileBuffer (int number)
+{
+    return tileBuffers[number % tileBuffers.size()];
+}
+
+
+int&
+DeepTiledInputFile::Data::getSampleCount(int x, int y)
+{
+    return sampleCount(sampleCountSliceBase,
+                       sampleCountXStride,
+                       sampleCountYStride,
+                       x, y);
+}
+
+
+namespace {
+
+void
+readTileData (InputStreamMutex *streamData,
+              DeepTiledInputFile::Data *ifd,
+              int dx, int dy,
+              int lx, int ly,
+              char *&buffer,
+              Int64 &dataSize,
+              Int64 &unpackedDataSize)
+{
+    //
+    // Read a single tile block from the file and into the array pointed
+    // to by buffer.  If the file is memory-mapped, then we change where
+    // buffer points instead of writing into the array (hence buffer needs
+    // to be a reference to a char *).
+    //
+
+    //
+    // Look up the location for this tile in the Index and
+    // seek to that position if necessary
+    //
+
+    Int64 tileOffset = ifd->tileOffsets (dx, dy, lx, ly);
+
+    if (tileOffset == 0)
+    {
+        THROW (IEX_NAMESPACE::InputExc, "Tile (" << dx << ", " << dy << ", " <<
+                              lx << ", " << ly << ") is missing.");
+    }
+
+    //
+    // In a multi-part file, the next chunk does not need to
+    // belong to the same part, so we have to compare the
+    // offset here.
+    //
+
+    if ( !isMultiPart(ifd->version) )
+    {
+        if (streamData->currentPosition != tileOffset)
+            streamData->is->seekg(tileOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may be moved by other
+        // parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != tileOffset)
+            streamData->is->seekg (tileOffset);
+    }
+
+    //
+    // Read the first few bytes of the tile (the header).
+    // Verify that the tile coordinates and the level number
+    // are correct.
+    //
+
+    int tileXCoord, tileYCoord, levelX, levelY;
+
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        Xdr::read <StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
+
+    Xdr::read <StreamIO> (*streamData->is, tileXCoord);
+    Xdr::read <StreamIO> (*streamData->is, tileYCoord);
+    Xdr::read <StreamIO> (*streamData->is, levelX);
+    Xdr::read <StreamIO> (*streamData->is, levelY);
+
+    Int64 tableSize;
+    Xdr::read <StreamIO> (*streamData->is, tableSize);
+
+    Xdr::read <StreamIO> (*streamData->is, dataSize);
+    Xdr::read <StreamIO> (*streamData->is, unpackedDataSize);
+
+
+    //
+    // Skip the pixel sample count table because we have read this data.
+    //
+
+    Xdr::skip <StreamIO> (*streamData->is, tableSize);
+
+
+    if (tileXCoord != dx)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
+
+    if (tileYCoord != dy)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
+
+    if (levelX != lx)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
+
+    if (levelY != ly)
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
+
+    //
+    // Read the pixel data.
+    //
+
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (dataSize);
+    else
+    {
+        // (TODO) check if the packed data size is too big?
+        // (TODO) better memory management here. Don't delete buffer everytime.
+        if (buffer != 0) delete[] buffer;
+        buffer = new char[dataSize];
+        streamData->is->read (buffer, dataSize);
+    }
+
+    //
+    // Keep track of which tile is the next one in
+    // the file, so that we can avoid redundant seekg()
+    // operations (seekg() can be fairly expensive).
+    //
+
+    streamData->currentPosition = tileOffset + 4 * Xdr::size<int>() +
+                                  3 * Xdr::size<Int64>()            +
+                                  tableSize                         +
+                                  dataSize;
+}
+
+
+void
+readNextTileData (InputStreamMutex *streamData,
+                  DeepTiledInputFile::Data *ifd,
+                  int &dx, int &dy,
+                  int &lx, int &ly,
+                  char * & buffer,
+                  Int64 &dataSize,
+                  Int64 &unpackedDataSize)
+{
+    //
+    // Read the next tile block from the file
+    //
+
+    //
+    // Read the first few bytes of the tile (the header).
+    //
+
+    Xdr::read <StreamIO> (*streamData->is, dx);
+    Xdr::read <StreamIO> (*streamData->is, dy);
+    Xdr::read <StreamIO> (*streamData->is, lx);
+    Xdr::read <StreamIO> (*streamData->is, ly);
+
+    Int64 tableSize;
+    Xdr::read <StreamIO> (*streamData->is, tableSize);
+
+    Xdr::read <StreamIO> (*streamData->is, dataSize);
+    Xdr::read <StreamIO> (*streamData->is, unpackedDataSize);
+
+    //
+    // Skip the pixel sample count table because we have read this data.
+    //
+
+    Xdr::skip <StreamIO> (*streamData->is, tableSize);
+
+    //
+    // Read the pixel data.
+    //
+
+    streamData->is->read (buffer, dataSize);
+
+    //
+    // Keep track of which tile is the next one in
+    // the file, so that we can avoid redundant seekg()
+    // operations (seekg() can be fairly expensive).
+    //
+
+    streamData->currentPosition += 4 * Xdr::size<int>()   +
+                                   3 * Xdr::size<Int64>() +
+                                   tableSize              +
+                                   dataSize;
+}
+
+
+//
+// A TileBufferTask encapsulates the task of uncompressing
+// a single tile and copying it into the frame buffer.
+//
+
+class TileBufferTask : public Task
+{
+  public:
+
+    TileBufferTask (TaskGroup *group,
+                    DeepTiledInputFile::Data *ifd,
+                    TileBuffer *tileBuffer);
+
+    virtual ~TileBufferTask ();
+
+    virtual void                execute ();
+
+  private:
+
+    DeepTiledInputFile::Data *      _ifd;
+    TileBuffer *                _tileBuffer;
+};
+
+
+TileBufferTask::TileBufferTask
+    (TaskGroup *group,
+     DeepTiledInputFile::Data *ifd,
+     TileBuffer *tileBuffer)
+:
+    Task (group),
+    _ifd (ifd),
+    _tileBuffer (tileBuffer)
+{
+    // empty
+}
+
+
+TileBufferTask::~TileBufferTask ()
+{
+    //
+    // Signal that the tile buffer is now free
+    //
+
+    _tileBuffer->post ();
+}
+
+
+void
+TileBufferTask::execute ()
+{
+    try
+    {
+        //
+        // Calculate information about the tile
+        //
+
+        Box2i tileRange = OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _ifd->tileDesc,
+                _ifd->minX, _ifd->maxX,
+                _ifd->minY, _ifd->maxY,
+                _tileBuffer->dx,
+                _tileBuffer->dy,
+                _tileBuffer->lx,
+                _tileBuffer->ly);
+
+        //
+        // Get the size of the tile.
+        //
+
+        Array<unsigned int> numPixelsPerScanLine;
+        numPixelsPerScanLine.resizeErase(tileRange.max.y - tileRange.min.y + 1);
+
+        int sizeOfTile = 0;
+        int maxBytesPerTileLine = 0;
+
+        for (int y = tileRange.min.y; y <= tileRange.max.y; y++)
+        {
+            numPixelsPerScanLine[y - tileRange.min.y] = 0;
+
+            int bytesPerLine = 0;
+
+            for (int x = tileRange.min.x; x <= tileRange.max.x; x++)
+            {
+                int xOffset = _ifd->sampleCountXTileCoords * tileRange.min.x;
+                int yOffset = _ifd->sampleCountYTileCoords * tileRange.min.y;
+
+                int count = _ifd->getSampleCount(x - xOffset, y - yOffset);
+                for (unsigned int c = 0; c < _ifd->slices.size(); ++c)
+                {
+                    sizeOfTile += count * pixelTypeSize(_ifd->slices[c]->typeInFile);
+                    bytesPerLine += count * pixelTypeSize(_ifd->slices[c]->typeInFile);
+                }
+                numPixelsPerScanLine[y - tileRange.min.y] += count;
+            }
+
+            if (bytesPerLine > maxBytesPerTileLine)
+                maxBytesPerTileLine = bytesPerLine;
+        }
+
+        // (TODO) don't do this every time.
+        if (_tileBuffer->compressor != 0)
+            delete _tileBuffer->compressor;
+        _tileBuffer->compressor = newTileCompressor
+                                  (_ifd->header.compression(),
+                                   maxBytesPerTileLine,
+                                   _ifd->tileDesc.ySize,
+                                   _ifd->header);
+
+        //
+        // Uncompress the data, if necessary
+        //
+
+        if (_tileBuffer->compressor && _tileBuffer->dataSize < Int64(sizeOfTile))
+        {
+            _tileBuffer->format = _tileBuffer->compressor->format();
+
+            _tileBuffer->dataSize = _tileBuffer->compressor->uncompressTile
+                (_tileBuffer->buffer, _tileBuffer->dataSize,
+                 tileRange, _tileBuffer->uncompressedData);
+        }
+        else
+        {
+            //
+            // If the line is uncompressed, it's in XDR format,
+            // regardless of the compressor's output format.
+            //
+
+            _tileBuffer->format = Compressor::XDR;
+            _tileBuffer->uncompressedData = _tileBuffer->buffer;
+        }
+
+        //
+        // Convert the tile of pixel data back from the machine-independent
+        // representation, and store the result in the frame buffer.
+        //
+
+        const char *readPtr = _tileBuffer->uncompressedData;
+                                                        // points to where we
+                                                        // read from in the
+                                                        // tile block
+
+        //
+        // Iterate over the scan lines in the tile.
+        //
+
+        for (int y = tileRange.min.y; y <= tileRange.max.y; ++y)
+        {
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ifd->slices.size(); ++i)
+            {
+                TInSliceInfo &slice = *_ifd->slices[i];
+
+                //
+                // These offsets are used to facilitate both
+                // absolute and tile-relative pixel coordinates.
+                //
+
+                int xOffsetForData = (slice.xTileCoords == 0) ? 0 : tileRange.min.x;
+                int yOffsetForData = (slice.yTileCoords == 0) ? 0 : tileRange.min.y;
+                int xOffsetForSampleCount =
+                        (_ifd->sampleCountXTileCoords == 0) ? 0 : tileRange.min.x;
+                int yOffsetForSampleCount =
+                        (_ifd->sampleCountYTileCoords == 0) ? 0 : tileRange.min.y;
+
+                //
+                // Fill the frame buffer with pixel data.
+                //
+
+                if (slice.skip)
+                {
+                    //
+                    // The file contains data for this channel, but
+                    // the frame buffer contains no slice for this channel.
+                    //
+
+                    skipChannel (readPtr, slice.typeInFile,
+                                 numPixelsPerScanLine[y - tileRange.min.y]);
+                }
+                else
+                {
+                    //
+                    // The frame buffer contains a slice for this channel.
+                    //
+
+                    copyIntoDeepFrameBuffer (readPtr, slice.pointerArrayBase,
+                                             _ifd->sampleCountSliceBase,
+                                             _ifd->sampleCountXStride,
+                                             _ifd->sampleCountYStride,
+                                             y,
+                                             tileRange.min.x,
+                                             tileRange.max.x,
+                                             xOffsetForSampleCount, yOffsetForSampleCount,
+                                             xOffsetForData, yOffsetForData,
+                                             slice.sampleStride, 
+                                             slice.xStride,
+                                             slice.yStride,
+                                             slice.fill,
+                                             slice.fillValue, _tileBuffer->format,
+                                             slice.typeInFrameBuffer,
+                                             slice.typeInFile);
+                }
+            }
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = e.what ();
+            _tileBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = "unrecognized exception";
+            _tileBuffer->hasException = true;
+        }
+    }
+}
+
+
+TileBufferTask *
+newTileBufferTask
+    (TaskGroup *group,
+     DeepTiledInputFile::Data *ifd,
+     int number,
+     int dx, int dy,
+     int lx, int ly)
+{
+    //
+    // Wait for a tile buffer to become available,
+    // fill the buffer with raw data from the file,
+    // and create a new TileBufferTask whose execute()
+    // method will uncompress the tile and copy the
+    // tile's pixels into the frame buffer.
+    //
+
+    TileBuffer *tileBuffer = ifd->getTileBuffer (number);
+
+    try
+    {
+        tileBuffer->wait();
+
+        tileBuffer->dx = dx;
+        tileBuffer->dy = dy;
+        tileBuffer->lx = lx;
+        tileBuffer->ly = ly;
+
+        tileBuffer->uncompressedData = 0;
+
+        readTileData (ifd->_streamData, ifd, dx, dy, lx, ly,
+                      tileBuffer->buffer,
+                      tileBuffer->dataSize,
+                      tileBuffer->uncompressedDataSize);
+    }
+    catch (...)
+    {
+        //
+        // Reading from the file caused an exception.
+        // Signal that the tile buffer is free, and
+        // re-throw the exception.
+        //
+
+        tileBuffer->post();
+        throw;
+    }
+
+    return new TileBufferTask (group, ifd, tileBuffer);
+}
+
+
+} // namespace
+
+
+DeepTiledInputFile::DeepTiledInputFile (const char fileName[], int numThreads):
+    _data (new Data (numThreads))
+{
+    _data->_deleteStream=true;
+    //
+    // This constructor is called when a user
+    // explicitly wants to read a tiled file.
+    //
+
+    IStream* is = 0;
+    try
+    {
+        is = new StdIFStream (fileName);
+        readMagicNumberAndVersionField(*is, _data->version);
+
+        //
+        // Compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(*is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            initialize();
+            _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,true);
+            _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+        }
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (is)          delete is;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        if (is)          delete is;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+
+DeepTiledInputFile::DeepTiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
+    _data (new Data (numThreads))
+{
+    _data->_streamData=0;
+    _data->_deleteStream=false;
+    
+    //
+    // This constructor is called when a user
+    // explicitly wants to read a tiled file.
+    //
+
+    try
+    {
+        readMagicNumberAndVersionField(is, _data->version);
+
+        //
+        // Backward compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = &is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            initialize();
+            // file is guaranteed not to be multipart, but is deep
+            _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete, false,true);
+            _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+            _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+        }
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << is.fileName() << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+
+DeepTiledInputFile::DeepTiledInputFile (const Header &header,
+                                        OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+                                        int version,
+                                        int numThreads) :
+    _data (new Data (numThreads))
+    
+{
+    _data->_streamData->is = is;
+    _data->_deleteStream=false;
+    
+    //
+    // This constructor called by class Imf::InputFile
+    // when a user wants to just read an image file, and
+    // doesn't care or know if the file is tiled.
+    // No need to have backward compatibility here, because
+    // we have the header.
+    //
+
+    _data->header = header;
+    _data->version = version;
+    initialize();
+    _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,true);
+    _data->memoryMapped = is->isMemoryMapped();
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
+
+DeepTiledInputFile::DeepTiledInputFile (InputPartData* part) :
+    _data (new Data (part->numThreads))
+{
+    _data->_deleteStream=false;
+    multiPartInitialize(part);
+}
+
+
+void
+DeepTiledInputFile::compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
+{
+    is.seekg(0);
+    //
+    // Construct a MultiPartInputFile, initialize TiledInputFile
+    // with the part 0 data.
+    // (TODO) maybe change the third parameter of the constructor of MultiPartInputFile later.
+    //
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    _data->multiPartBackwardSupport = true;
+    InputPartData* part = _data->multiPartFile->getPart(0);
+
+    multiPartInitialize(part);
+}
+
+
+void
+DeepTiledInputFile::multiPartInitialize(InputPartData* part)
+{
+    if (isTiled(part->header.type()) == false)
+        THROW (IEX_NAMESPACE::ArgExc, "Can't build a DeepTiledInputFile from a part of type " << part->header.type());
+
+    _data->_streamData = part->mutex;
+    _data->header = part->header;
+    _data->version = part->version;
+    _data->partNumber = part->partNumber;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    initialize();
+    _data->tileOffsets.readFrom(part->chunkOffsets , _data->fileIsComplete);
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
+
+void
+DeepTiledInputFile::initialize ()
+{
+    if (_data->partNumber == -1)
+        if (_data->header.type() != DEEPTILE)
+            throw IEX_NAMESPACE::ArgExc ("Expected a deep tiled file but the file is not deep tiled.");
+   if(_data->header.version()!=1)
+   {
+       THROW(IEX_NAMESPACE::ArgExc, "Version " << _data->header.version() << " not supported for deeptiled images in this version of the library");
+   }
+        
+    _data->header.sanityCheck (true);
+
+    _data->tileDesc = _data->header.tileDescription();
+    _data->lineOrder = _data->header.lineOrder();
+
+    //
+    // Save the dataWindow information
+    //
+
+    const Box2i &dataWindow = _data->header.dataWindow();
+    _data->minX = dataWindow.min.x;
+    _data->maxX = dataWindow.max.x;
+    _data->minY = dataWindow.min.y;
+    _data->maxY = dataWindow.max.y;
+
+    //
+    // Precompute level and tile information to speed up utility functions
+    //
+
+    precalculateTileInfo (_data->tileDesc,
+                          _data->minX, _data->maxX,
+                          _data->minY, _data->maxY,
+                          _data->numXTiles, _data->numYTiles,
+                          _data->numXLevels, _data->numYLevels);
+
+    //
+    // Create all the TileBuffers and allocate their internal buffers
+    //
+
+    _data->tileOffsets = TileOffsets (_data->tileDesc.mode,
+                                      _data->numXLevels,
+                                      _data->numYLevels,
+                                      _data->numXTiles,
+                                      _data->numYTiles);
+
+    for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+        _data->tileBuffers[i] = new TileBuffer ();
+
+    _data->maxSampleCountTableSize = _data->tileDesc.ySize *
+                                     _data->tileDesc.xSize *
+                                     sizeof(int);
+
+    _data->sampleCountTableBuffer.resizeErase(_data->maxSampleCountTableSize);
+
+    _data->sampleCountTableComp = newCompressor(_data->header.compression(),
+                                                _data->maxSampleCountTableSize,
+                                                _data->header);
+                                                
+                                                
+    const ChannelList & c=_data->header.channels();
+    _data->combinedSampleSize=0;
+    for(ChannelList::ConstIterator i=c.begin();i!=c.end();i++)
+    {
+        switch( i.channel().type )
+        {
+            case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF  :
+                _data->combinedSampleSize+=Xdr::size<half>();
+                break;
+            case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                _data->combinedSampleSize+=Xdr::size<float>();
+                break;
+            case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT  :
+                _data->combinedSampleSize+=Xdr::size<unsigned int>();
+                break;
+            default :
+                THROW(IEX_NAMESPACE::ArgExc, "Bad type for channel " << i.name() << " initializing deepscanline reader");
+        }
+    }
+                                                  
+}
+
+
+DeepTiledInputFile::~DeepTiledInputFile ()
+{
+    if (!_data->memoryMapped)
+        for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+            if (_data->tileBuffers[i]->buffer != 0)
+                delete [] _data->tileBuffers[i]->buffer;
+
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
+
+    //
+    // (TODO) we should have a way to tell if the stream data is owned by this file or
+    // by a parent multipart file.
+    //
+
+    if (_data->partNumber == -1)
+        delete _data->_streamData;
+
+    delete _data;
+}
+
+
+const char *
+DeepTiledInputFile::fileName () const
+{
+    return _data->_streamData->is->fileName();
+}
+
+
+const Header &
+DeepTiledInputFile::header () const
+{
+    return _data->header;
+}
+
+
+int
+DeepTiledInputFile::version () const
+{
+    return _data->version;
+}
+
+
+void
+DeepTiledInputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    //
+    // Set the frame buffer
+    //
+
+    //
+    // Check if the new frame buffer descriptor is
+    // compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        ChannelList::ConstIterator i = channels.find (j.name());
+
+        if (i == channels.end())
+            continue;
+
+        if (i.channel().xSampling != j.slice().xSampling ||
+            i.channel().ySampling != j.slice().ySampling)
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                                "of \"" << i.name() << "\" channel "
+                                "of input file \"" << fileName() << "\" are "
+                                "not compatible with the frame buffer's "
+                                "subsampling factors.");
+    }
+
+    //
+    // Store the pixel sample count table.
+    // (TODO) Support for different sampling rates?
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+        _data->sampleCountXTileCoords = sampleCountSlice.xTileCoords;
+        _data->sampleCountYTileCoords = sampleCountSlice.yTileCoords;
+    }
+
+    //
+    // Initialize the slice table for readPixels().
+    //
+
+    vector<TInSliceInfo*> slices;
+    ChannelList::ConstIterator i = channels.begin();
+
+    for (DeepFrameBuffer::ConstIterator j = frameBuffer.begin();
+         j != frameBuffer.end();
+         ++j)
+    {
+        while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
+        {
+            //
+            // Channel i is present in the file but not
+            // in the frame buffer; data for channel i
+            // will be skipped during readPixels().
+            //
+
+            slices.push_back (new TInSliceInfo (i.channel().type,
+                                                NULL,
+                                                i.channel().type,
+                                                0,      // xStride
+                                                0,      // yStride
+                                                0,      // sampleStride
+                                                false,  // fill
+                                                true,   // skip
+                                                0.0));  // fillValue
+            ++i;
+        }
+
+        bool fill = false;
+
+        if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+        {
+            //
+            // Channel i is present in the frame buffer, but not in the file.
+            // In the frame buffer, slice j will be filled with a default value.
+            //
+
+            fill = true;
+        }
+
+        slices.push_back (new TInSliceInfo (j.slice().type,
+                                            j.slice().base,
+                                            fill? j.slice().type: i.channel().type,
+                                            j.slice().xStride,
+                                            j.slice().yStride,
+                                            j.slice().sampleStride,
+                                            fill,
+                                            false, // skip
+                                            j.slice().fillValue,
+                                            (j.slice().xTileCoords)? 1: 0,
+                                            (j.slice().yTileCoords)? 1: 0));
+
+
+        if (i != channels.end() && !fill)
+            ++i;
+    }
+
+    // (TODO) inspect the following code. It's additional to the scanline input file.
+    // Is this needed?
+
+    while (i != channels.end())
+    {
+        //
+        // Channel i is present in the file but not
+        // in the frame buffer; data for channel i
+        // will be skipped during readPixels().
+        //
+
+        slices.push_back (new TInSliceInfo (i.channel().type,
+                                            NULL,
+                                            i.channel().type,
+                                            0, // xStride
+                                            0, // yStride
+                                            0, // sampleStride
+                                            false,  // fill
+                                            true, // skip
+                                            0.0)); // fillValue
+        ++i;
+    }
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+}
+
+
+const DeepFrameBuffer &
+DeepTiledInputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+bool
+DeepTiledInputFile::isComplete () const
+{
+    return _data->fileIsComplete;
+}
+
+
+void
+DeepTiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
+{
+    //
+    // Read a range of tiles from the file into the framebuffer
+    //
+
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data destination.");
+
+        if (!isValidLevel (lx, ly))
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
+
+        //
+        // Determine the first and last tile coordinates in both dimensions.
+        // We always attempt to read the range of tiles in the order that
+        // they are stored in the file.
+        //
+
+        if (dx1 > dx2)
+            std::swap (dx1, dx2);
+
+        if (dy1 > dy2)
+            std::swap (dy1, dy2);
+
+        int dyStart = dy1;
+        int dyStop  = dy2 + 1;
+        int dY      = 1;
+
+        if (_data->lineOrder == DECREASING_Y)
+        {
+            dyStart = dy2;
+            dyStop  = dy1 - 1;
+            dY      = -1;
+        }
+
+        //
+        // Create a task group for all tile buffer tasks.  When the
+        // task group goes out of scope, the destructor waits until
+        // all tasks are complete.
+        //
+
+        {
+            TaskGroup taskGroup;
+            int tileNumber = 0;
+
+            for (int dy = dyStart; dy != dyStop; dy += dY)
+            {
+                for (int dx = dx1; dx <= dx2; dx++)
+                {
+                    if (!isValidTile (dx, dy, lx, ly))
+                        THROW (IEX_NAMESPACE::ArgExc,
+                               "Tile (" << dx << ", " << dy << ", " <<
+                               lx << "," << ly << ") is not a valid tile.");
+
+                    ThreadPool::addGlobalTask (newTileBufferTask (&taskGroup,
+                                                                  _data,
+                                                                  tileNumber++,
+                                                                  dx, dy,
+                                                                  lx, ly));
+                }
+            }
+
+            //
+            // finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // TileBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to TiledInputFile::readTiles().
+        // TileBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the tile buffers.
+        // Now we check if any tile buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple tile buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
+        {
+            TileBuffer *tileBuffer = _data->tileBuffers[i];
+
+            if (tileBuffer->hasException && !exception)
+                exception = &tileBuffer->exception;
+
+            tileBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading pixel data from image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+void
+DeepTiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int l)
+{
+    readTiles (dx1, dx2, dy1, dy2, l, l);
+}
+
+
+void
+DeepTiledInputFile::readTile (int dx, int dy, int lx, int ly)
+{
+    readTiles (dx, dx, dy, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputFile::readTile (int dx, int dy, int l)
+{
+    readTile (dx, dy, l, l);
+}
+
+
+void
+DeepTiledInputFile::rawTileData (int &dx, int &dy,
+                             int &lx, int &ly,
+                             char * pixelData,
+                             Int64 &pixelDataSize) const
+{
+     if (!isValidTile (dx, dy, lx, ly))
+               throw IEX_NAMESPACE::ArgExc ("Tried to read a tile outside "
+                                   "the image file's data window.");
+    
+     Int64 tileOffset = _data->tileOffsets (dx, dy, lx, ly);
+                                   
+     if(tileOffset == 0)
+     {
+        THROW (IEX_NAMESPACE::InputExc, "Tile (" << dx << ", " << dy << ", " <<
+        lx << ", " << ly << ") is missing.");
+     }
+     
+     Lock lock(*_data->_streamData);
+                                   
+     if (_data->_streamData->is->tellg() != tileOffset)
+                                          _data->_streamData->is->seekg (tileOffset);
+                                   
+     
+     //
+     // Read the first few bytes of the tile (the header).
+     // Verify that the tile coordinates and the level number
+     // are correct.
+     //
+     
+     int tileXCoord, tileYCoord, levelX, levelY;
+     
+     if (isMultiPart(_data->version))
+     {
+         int partNumber;
+         Xdr::read <StreamIO> (*_data->_streamData->is, partNumber);
+         if (partNumber != _data->partNumber)
+         {
+             THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+             << ", should be " << _data->partNumber << ".");
+         }
+     }
+     
+     Xdr::read <StreamIO> (*_data->_streamData->is, tileXCoord);
+     Xdr::read <StreamIO> (*_data->_streamData->is, tileYCoord);
+     Xdr::read <StreamIO> (*_data->_streamData->is, levelX);
+     Xdr::read <StreamIO> (*_data->_streamData->is, levelY);
+     
+     Int64 sampleCountTableSize;
+     Int64 packedDataSize;
+     Xdr::read <StreamIO> (*_data->_streamData->is, sampleCountTableSize);
+     
+     Xdr::read <StreamIO> (*_data->_streamData->is, packedDataSize);
+     
+          
+     
+     if (tileXCoord != dx)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
+     
+     if (tileYCoord != dy)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
+     
+     if (levelX != lx)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
+     
+     if (levelY != ly)
+         throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
+     
+     
+     // total requirement for reading all the data
+     
+     Int64 totalSizeRequired=40+sampleCountTableSize+packedDataSize;
+     
+     bool big_enough = totalSizeRequired<=pixelDataSize;
+     
+     pixelDataSize = totalSizeRequired;
+     
+     // was the block we were given big enough?
+     if(!big_enough || pixelData==NULL)
+     {        
+         // special case: seek stream back to start if we are at the beginning (regular reading pixels assumes it doesn't need to seek
+         // in single part files)
+         if(!isMultiPart(_data->version))
+         {
+             _data->_streamData->is->seekg(_data->_streamData->currentPosition); 
+         }
+         // leave lock here - bail before reading more data
+         return;
+     }
+     
+     // copy the values we have read into the output block
+     *(int *) (pixelData+0) = dx;
+     *(int *) (pixelData+4) = dy;
+     *(int *) (pixelData+8) = levelX;
+     *(int *) (pixelData+12) = levelY;
+     *(Int64 *) (pixelData+16) =sampleCountTableSize;
+     *(Int64 *) (pixelData+24) = packedDataSize;
+     
+     // didn't read the unpackedsize - do that now
+     Xdr::read<StreamIO> (*_data->_streamData->is, *(Int64 *) (pixelData+32));
+     
+     // read the actual data
+     _data->_streamData->is->read(pixelData+40, sampleCountTableSize+packedDataSize);
+     
+     
+     if(!isMultiPart(_data->version))
+     {
+         _data->_streamData->currentPosition+=sampleCountTableSize+packedDataSize+40;
+     }
+     
+     // leave lock here
+     
+     
+}
+
+
+unsigned int
+DeepTiledInputFile::tileXSize () const
+{
+    return _data->tileDesc.xSize;
+}
+
+
+unsigned int
+DeepTiledInputFile::tileYSize () const
+{
+    return _data->tileDesc.ySize;
+}
+
+
+LevelMode
+DeepTiledInputFile::levelMode () const
+{
+    return _data->tileDesc.mode;
+}
+
+
+LevelRoundingMode
+DeepTiledInputFile::levelRoundingMode () const
+{
+    return _data->tileDesc.roundingMode;
+}
+
+
+int
+DeepTiledInputFile::numLevels () const
+{
+    if (levelMode() == RIPMAP_LEVELS)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
+                              "file \"" << fileName() << "\" "
+                              "(numLevels() is not defined for files "
+                              "with RIPMAP level mode).");
+
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledInputFile::numXLevels () const
+{
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledInputFile::numYLevels () const
+{
+    return _data->numYLevels;
+}
+
+
+bool
+DeepTiledInputFile::isValidLevel (int lx, int ly) const
+{
+    if (lx < 0 || ly < 0)
+        return false;
+
+    if (levelMode() == MIPMAP_LEVELS && lx != ly)
+        return false;
+
+    if (lx >= numXLevels() || ly >= numYLevels())
+        return false;
+
+    return true;
+}
+
+
+int
+DeepTiledInputFile::levelWidth (int lx) const
+{
+    try
+    {
+        return levelSize (_data->minX, _data->maxX, lx,
+                          _data->tileDesc.roundingMode);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelWidth() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+int
+DeepTiledInputFile::levelHeight (int ly) const
+{
+    try
+    {
+        return levelSize (_data->minY, _data->maxY, ly,
+                          _data->tileDesc.roundingMode);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelHeight() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+int
+DeepTiledInputFile::numXTiles (int lx) const
+{
+    if (lx < 0 || lx >= _data->numXLevels)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numXTiles() on image "
+                            "file \"" << _data->_streamData->is->fileName() << "\" "
+                            "(Argument is not in valid range).");
+
+    }
+
+    return _data->numXTiles[lx];
+}
+
+
+int
+DeepTiledInputFile::numYTiles (int ly) const
+{
+    if (ly < 0 || ly >= _data->numYLevels)
+    {
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numYTiles() on image "
+                            "file \"" << _data->_streamData->is->fileName() << "\" "
+                            "(Argument is not in valid range).");
+    }
+
+    return _data->numYTiles[ly];
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForLevel (int l) const
+{
+    return dataWindowForLevel (l, l);
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForLevel (int lx, int ly) const
+{
+    try
+    {
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForTile (int dx, int dy, int l) const
+{
+    return dataWindowForTile (dx, dy, l, l);
+}
+
+
+Box2i
+DeepTiledInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    try
+    {
+        if (!isValidTile (dx, dy, lx, ly))
+            throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
+
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                dx, dy, lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+bool
+DeepTiledInputFile::isValidTile (int dx, int dy, int lx, int ly) const
+{
+    return ((lx < _data->numXLevels && lx >= 0) &&
+            (ly < _data->numYLevels && ly >= 0) &&
+            (dx < _data->numXTiles[lx] && dx >= 0) &&
+            (dy < _data->numYTiles[ly] && dy >= 0));
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCounts (int dx1, int dx2,
+                                           int dy1, int dy2,
+                                           int lx,  int ly)
+{
+    Int64 savedFilePos = 0;
+
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        savedFilePos = _data->_streamData->is->tellg();
+
+        
+        if (!isValidLevel (lx, ly))
+        {
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
+        }
+        
+        if (dx1 > dx2)
+            std::swap (dx1, dx2);
+
+        if (dy1 > dy2)
+            std::swap (dy1, dy2);
+
+        int dyStart = dy1;
+        int dyStop  = dy2 + 1;
+        int dY      = 1;
+
+        if (_data->lineOrder == DECREASING_Y)
+        {
+            dyStart = dy2;
+            dyStop  = dy1 - 1;
+            dY      = -1;
+        }
+
+        // (TODO) Check if we have read the sample counts for those tiles,
+        // if we have, no need to read again.
+        for (int dy = dyStart; dy != dyStop; dy += dY)
+        {
+            for (int dx = dx1; dx <= dx2; dx++)
+            {
+                
+                if (!isValidTile (dx, dy, lx, ly))
+                {
+                    THROW (IEX_NAMESPACE::ArgExc,
+                           "Tile (" << dx << ", " << dy << ", " <<
+                           lx << "," << ly << ") is not a valid tile.");
+                }
+                
+                Box2i tileRange = OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                        _data->tileDesc,
+                        _data->minX, _data->maxX,
+                        _data->minY, _data->maxY,
+                        dx, dy, lx, ly);
+
+                int xOffset = _data->sampleCountXTileCoords * tileRange.min.x;
+                int yOffset = _data->sampleCountYTileCoords * tileRange.min.y;
+
+                //
+                // Skip and check the tile coordinates.
+                //
+
+                _data->_streamData->is->seekg(_data->tileOffsets(dx, dy, lx, ly));
+
+                if (isMultiPart(_data->version))
+                {
+                    int partNumber;
+                    Xdr::read <StreamIO> (*_data->_streamData->is, partNumber);
+
+                    if (partNumber != _data->partNumber)
+                        throw IEX_NAMESPACE::InputExc ("Unexpected part number.");
+                }
+
+                int xInFile, yInFile, lxInFile, lyInFile;
+                Xdr::read <StreamIO> (*_data->_streamData->is, xInFile);
+                Xdr::read <StreamIO> (*_data->_streamData->is, yInFile);
+                Xdr::read <StreamIO> (*_data->_streamData->is, lxInFile);
+                Xdr::read <StreamIO> (*_data->_streamData->is, lyInFile);
+
+                if (xInFile != dx)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
+
+                if (yInFile != dy)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
+
+                if (lxInFile != lx)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
+
+                if (lyInFile != ly)
+                    throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
+
+                Int64 tableSize, dataSize, unpackedDataSize;
+                Xdr::read <StreamIO> (*_data->_streamData->is, tableSize);
+                Xdr::read <StreamIO> (*_data->_streamData->is, dataSize);
+                Xdr::read <StreamIO> (*_data->_streamData->is, unpackedDataSize);
+
+                
+                if(tableSize>_data->maxSampleCountTableSize)
+                {
+                    THROW (IEX_NAMESPACE::ArgExc, "Bad sampleCountTableDataSize read from tile "<< dx << ',' << dy << ',' << lx << ',' << ly << ": expected " << _data->maxSampleCountTableSize << " or less, got "<< tableSize);
+                }
+                    
+                
+                //
+                // We make a check on the data size requirements here.
+                // Whilst we wish to store 64bit sizes on disk, not all the compressors
+                // have been made to work with such data sizes and are still limited to
+                // using signed 32 bit (int) for the data size. As such, this version
+                // insists that we validate that the data size does not exceed the data
+                // type max limit.
+                // @TODO refactor the compressor code to ensure full 64-bit support.
+                //
+
+                Int64 compressorMaxDataSize = Int64(std::numeric_limits<int>::max());
+                if (dataSize         > compressorMaxDataSize ||
+                    unpackedDataSize > compressorMaxDataSize ||
+                    tableSize        > compressorMaxDataSize)
+                {
+                    THROW (IEX_NAMESPACE::ArgExc, "This version of the library does not"
+                          << "support the allocation of data with size  > "
+                          << compressorMaxDataSize
+                          << " file table size    :" << tableSize
+                          << " file unpacked size :" << unpackedDataSize
+                          << " file packed size   :" << dataSize << ".\n");
+                }
+
+                //
+                // Read and uncompress the pixel sample count table.
+                //
+
+                _data->_streamData->is->read(_data->sampleCountTableBuffer, tableSize);
+
+                const char* readPtr;
+
+                if (tableSize < _data->maxSampleCountTableSize)
+                {
+                    if(!_data->sampleCountTableComp)
+                    {
+                        THROW(IEX_NAMESPACE::ArgExc,"Deep scanline data corrupt at tile " << dx << ',' << dy << ',' << lx << ',' <<  ly << " (sampleCountTableDataSize error)");
+                    }
+                    _data->sampleCountTableComp->uncompress(_data->sampleCountTableBuffer,
+                                                            tableSize,
+                                                            tileRange.min.y,
+                                                            readPtr);
+                }
+                else
+                    readPtr = _data->sampleCountTableBuffer;
+
+                size_t cumulative_total_samples =0;
+                int lastAccumulatedCount;
+                for (int j = tileRange.min.y; j <= tileRange.max.y; j++)
+                {
+                    lastAccumulatedCount = 0;
+                    for (int i = tileRange.min.x; i <= tileRange.max.x; i++)
+                    {
+                        int accumulatedCount;
+                        Xdr::read <CharPtrIO> (readPtr, accumulatedCount);
+                        
+                        if (accumulatedCount < lastAccumulatedCount)
+                        {
+                            THROW(IEX_NAMESPACE::ArgExc,"Deep tile sampleCount data corrupt at tile " 
+                                  << dx << ',' << dy << ',' << lx << ',' <<  ly << " (negative sample count detected)");
+                        }
+
+                        int count = accumulatedCount - lastAccumulatedCount;
+                        lastAccumulatedCount = accumulatedCount;
+                        
+                        _data->getSampleCount(i - xOffset, j - yOffset) =count;
+                    }
+                    cumulative_total_samples += lastAccumulatedCount;
+                }
+                
+                if(cumulative_total_samples * _data->combinedSampleSize > unpackedDataSize)
+                {
+                    THROW(IEX_NAMESPACE::ArgExc,"Deep scanline sampleCount data corrupt at tile " 
+                                                << dx << ',' << dy << ',' << lx << ',' <<  ly 
+                                                << ": pixel data only contains " << unpackedDataSize 
+                                                << " bytes of data but table references at least " 
+                                                << cumulative_total_samples*_data->combinedSampleSize << " bytes of sample data" );            
+                }
+                    
+            }
+        }
+
+        _data->_streamData->is->seekg(savedFilePos);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error reading sample count data from image "
+                     "file \"" << fileName() << "\". " << e.what());
+
+         _data->_streamData->is->seekg(savedFilePos);
+
+        throw;
+    }
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCount (int dx, int dy, int l)
+{
+    readPixelSampleCount (dx, dy, l, l);
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCount (int dx, int dy, int lx, int ly)
+{
+    readPixelSampleCounts (dx, dx, dy, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputFile::readPixelSampleCounts (int dx1, int dx2,
+                                           int dy1, int dy2,
+                                           int l)
+{
+    readPixelSampleCounts (dx1, dx2, dy1, dy2, l, l);
+}
+
+
+size_t
+DeepTiledInputFile::totalTiles() const
+{
+    //
+    // Calculate the total number of tiles in the file
+    //
+    
+    int numAllTiles = 0;
+    
+    switch (levelMode ())
+    {
+        case ONE_LEVEL:
+        case MIPMAP_LEVELS:
+            
+            for (int i_l = 0; i_l < numLevels (); ++i_l)
+                numAllTiles += numXTiles (i_l) * numYTiles (i_l);
+            
+            break;
+            
+        case RIPMAP_LEVELS:
+            
+            for (int i_ly = 0; i_ly < numYLevels (); ++i_ly)
+                for (int i_lx = 0; i_lx < numXLevels (); ++i_lx)
+                    numAllTiles += numXTiles (i_lx) * numYTiles (i_ly);
+                
+                break;
+            
+        default:
+            
+            throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
+    }
+    return numAllTiles;
+}
+
+
+
+
+void 
+DeepTiledInputFile::getTileOrder(int dx[],int dy[],int lx[],int ly[]) const
+{
+  return _data->tileOffsets.getTileOrder(dx,dy,lx,ly);
+  
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledInputFile.h b/3rdparty/openexr/IlmImf/ImfDeepTiledInputFile.h
new file mode 100644 (file)
index 0000000..2643fe5
--- /dev/null
@@ -0,0 +1,472 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEP_TILED_INPUT_FILE_H
+#define INCLUDED_IMF_DEEP_TILED_INPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledInputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImathBox.h"
+#include "ImfTileDescription.h"
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfDeepFrameBuffer.h"
+#include "ImfDeepTiledOutputFile.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class DeepTiledInputFile : public GenericInputFile
+{
+  public:
+
+    //--------------------------------------------------------------------
+    // A constructor that opens the file with the specified name, and
+    // reads the file header.  The constructor throws an IEX_NAMESPACE::ArgExc
+    // exception if the file is not tiled.
+    // The numThreads parameter specifies how many worker threads this
+    // file will try to keep busy when decompressing individual tiles.
+    // Destroying TiledInputFile objects constructed with this constructor
+    // automatically closes the corresponding files.
+    //--------------------------------------------------------------------
+
+    IMF_EXPORT
+    DeepTiledInputFile (const char fileName[],
+                    int numThreads = globalThreadCount ());
+
+
+    // ----------------------------------------------------------
+    // A constructor that attaches the new TiledInputFile object
+    // to a file that has already been opened.
+    // Destroying TiledInputFile objects constructed with this
+    // constructor does not automatically close the corresponding
+    // files.
+    // ----------------------------------------------------------
+
+    IMF_EXPORT
+    DeepTiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount ());
+
+
+    //-----------
+    // Destructor
+    //-----------
+
+    IMF_EXPORT
+    virtual ~DeepTiledInputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    IMF_EXPORT
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledInputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readTile() is called.
+    // The current frame buffer can be changed after each call
+    // to readTile().
+    //-----------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window
+    // (in all levels) are present in the input file, or false if
+    // any pixels are missing.  (Another program may still be busy
+    // writing the file, or file writing may have been aborted
+    // prematurely.)
+    //------------------------------------------------------------
+
+    IMF_EXPORT
+    bool                isComplete () const;
+
+
+    //--------------------------------------------------
+    // Utility functions:
+    //--------------------------------------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    unsigned int        tileXSize () const;
+    IMF_EXPORT
+    unsigned int        tileYSize () const;
+    IMF_EXPORT
+    LevelMode           levelMode () const;
+    IMF_EXPORT
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with
+    // MIPMAP_LEVELS files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    // totalTiles() returns the total number of tiles in the image
+    //
+    //--------------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numLevels () const;
+    IMF_EXPORT
+    int                 numXLevels () const;
+    IMF_EXPORT
+    int                 numYLevels () const;
+    IMF_EXPORT
+    bool                isValidLevel (int lx, int ly) const;
+    IMF_EXPORT
+    size_t              totalTiles() const;
+
+    //----------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //----------------------------------------------------------
+
+    IMF_EXPORT
+    int                 levelWidth  (int lx) const;
+    IMF_EXPORT
+    int                 levelHeight (int ly) const;
+
+
+    //--------------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numXTiles (int lx = 0) const;
+    IMF_EXPORT
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional region of
+    // valid pixel coordinates for a level with level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy, int l = 0) const;
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                           int lx, int ly) const;
+
+    //------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readTile(dx, dy, lx, ly) reads the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly),
+    // and stores it in the current frame buffer.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx)-1]
+    //   dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    //   lx must lie in the interval [0, numXLevels()-1]
+    //   ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readTile(dx, dy, level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It calls
+    // readTile(dx, dy, level, level).
+    //
+    // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // reading multiple tiles at once.  If multi-threading is used
+    // the multiple tiles are read concurrently.
+    //
+    // Pixels that are outside the pixel coordinate range for the
+    // tile's level, are never accessed by readTile().
+    //
+    // Attempting to access a tile that is not present in the file
+    // throws an InputExc exception.
+    //
+    //------------------------------------------------------------
+
+    IMF_EXPORT
+    void                readTile  (int dx, int dy, int l = 0);
+    IMF_EXPORT
+    void                readTile  (int dx, int dy, int lx, int ly);
+
+    IMF_EXPORT
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                   int lx, int ly);
+
+    IMF_EXPORT
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                   int l = 0);
+
+
+    //--------------------------------------------------
+    // Read a tile of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement TiledOutputFile::copyPixels()).
+    //--------------------------------------------------
+
+    IMF_EXPORT
+    void                rawTileData (int &dx, int &dy,
+                                     int &lx, int &ly,
+                                     char *pixelData,
+                                     Int64 &dataSize) const;
+
+    //------------------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCount(dx, dy, lx, ly) reads the sample counts
+    // for tile (dx, dy) in level (lx, ly).
+    //
+    // readPixelSampleCount(dx, dy, l) calls
+    // readPixelSampleCount(dx, dy, lx = l, ly = l)
+    //
+    // dx must lie in the interval [0, numXTiles(lx)-1]
+    // dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    // lx must lie in the interval [0, numXLevels()-1]
+    // ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx, ly) reads all
+    // the sample counts for tiles within range
+    // [(min(dx1, dx2), min(dy1, dy2))...(max(dx1, dx2), max(dy1, dy2)],
+    // and on level (lx, ly)
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, l) calls
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx = l, ly = l).
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                readPixelSampleCount  (int dx, int dy, int l = 0);
+    IMF_EXPORT
+    void                readPixelSampleCount  (int dx, int dy, int lx, int ly);
+
+    IMF_EXPORT
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                              int dy1, int dy2,
+                                              int lx, int ly);
+
+    IMF_EXPORT
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                              int dy1, int dy2,
+                                              int l = 0);
+
+    struct Data;
+
+    
+    
+  private:
+
+    friend class InputFile;
+    friend class MultiPartInputFile;
+
+    DeepTiledInputFile (InputPartData* part);
+
+    DeepTiledInputFile (const DeepTiledInputFile &);              // not implemented
+    DeepTiledInputFile & operator = (const DeepTiledInputFile &); // not implemented
+
+    DeepTiledInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is, int version,
+                    int numThreads);
+
+    void                initialize ();
+    void                multiPartInitialize(InputPartData* part);
+    void                compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is);
+
+    bool                isValidTile (int dx, int dy,
+                                     int lx, int ly) const;
+
+    size_t              bytesPerLineForTile (int dx, int dy,
+                                             int lx, int ly) const;
+           
+                                                
+    void                getTileOrder(int dx[],int dy[],int lx[],int ly[]) const;
+                                             
+    
+    Data *              _data;
+
+
+    // needed for copyPixels
+    friend void DeepTiledOutputFile::copyPixels(DeepTiledInputFile &);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledInputPart.cpp b/3rdparty/openexr/IlmImf/ImfDeepTiledInputPart.cpp
new file mode 100644 (file)
index 0000000..0f0c012
--- /dev/null
@@ -0,0 +1,273 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "ImfDeepTiledInputPart.h"
+#include "ImfMultiPartInputFile.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepTiledInputPart::DeepTiledInputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<DeepTiledInputFile>(partNumber);
+}
+
+
+const char *
+DeepTiledInputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepTiledInputPart::header () const
+{
+    return file->header();
+}
+
+
+int
+DeepTiledInputPart::version () const
+{
+    return file->version();
+}
+
+
+void
+DeepTiledInputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepTiledInputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+bool
+DeepTiledInputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+
+unsigned int
+DeepTiledInputPart::tileXSize () const
+{
+    return file->tileXSize();
+}
+
+
+unsigned int
+DeepTiledInputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+
+LevelMode
+DeepTiledInputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+
+LevelRoundingMode
+DeepTiledInputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+
+int
+DeepTiledInputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+
+int
+DeepTiledInputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+
+int
+DeepTiledInputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+
+bool
+DeepTiledInputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+
+int
+DeepTiledInputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+
+int
+DeepTiledInputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+
+int
+DeepTiledInputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+
+int
+DeepTiledInputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForTile (int dx, int dy, int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledInputPart::dataWindowForTile (int dx, int dy,
+                                       int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readTile  (int dx, int dy, int l)
+{
+    file->readTile(dx, dy, l);
+}
+
+
+void
+DeepTiledInputPart::readTile  (int dx, int dy, int lx, int ly)
+{
+    file->readTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2,
+                               int lx, int ly)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2,
+                               int l)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, l);
+}
+
+
+void
+DeepTiledInputPart::rawTileData (int &dx, int &dy,
+                                 int &lx, int &ly,
+                                 char * pixelData,
+                                 Int64 & dataSize) const
+{
+    file->rawTileData(dx, dy, lx, ly, pixelData, dataSize );
+}
+
+
+void
+DeepTiledInputPart::readPixelSampleCount  (int dx, int dy, int l)
+{
+    file->readPixelSampleCount(dx, dy, l);
+}
+
+
+void
+DeepTiledInputPart::readPixelSampleCount  (int dx, int dy, int lx, int ly)
+{
+    file->readPixelSampleCount(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledInputPart::readPixelSampleCounts (int dx1, int dx2,
+                                          int dy1, int dy2,
+                                          int lx, int ly)
+{
+    file->readPixelSampleCounts(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+void
+DeepTiledInputPart::readPixelSampleCounts (int dx1, int dx2,
+                                          int dy1, int dy2,
+                                          int l)
+{
+    file->readPixelSampleCounts(dx1, dx2, dy1, dy2, l);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledInputPart.h b/3rdparty/openexr/IlmImf/ImfDeepTiledInputPart.h
new file mode 100644 (file)
index 0000000..0e665c2
--- /dev/null
@@ -0,0 +1,394 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef IMFDEEPTILEDINPUTPART_H_
+#define IMFDEEPTILEDINPUTPART_H_
+
+#include "ImfDeepTiledInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class DeepTiledInputPart
+{
+  public:
+
+    IMF_EXPORT
+    DeepTiledInputPart(MultiPartInputFile& multiPartFile, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    IMF_EXPORT
+    int                 version () const;
+
+
+    //-----------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledInputFile object.
+    //
+    // The current frame buffer is the destination for the pixel
+    // data read from the file.  The current frame buffer must be
+    // set at least once before readTile() is called.
+    // The current frame buffer can be changed after each call
+    // to readTile().
+    //-----------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //------------------------------------------------------------
+    // Check if the file is complete:
+    //
+    // isComplete() returns true if all pixels in the data window
+    // (in all levels) are present in the input file, or false if
+    // any pixels are missing.  (Another program may still be busy
+    // writing the file, or file writing may have been aborted
+    // prematurely.)
+    //------------------------------------------------------------
+
+    IMF_EXPORT
+    bool                isComplete () const;
+
+
+    //--------------------------------------------------
+    // Utility functions:
+    //--------------------------------------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    unsigned int        tileXSize () const;
+    IMF_EXPORT
+    unsigned int        tileYSize () const;
+    IMF_EXPORT
+    LevelMode           levelMode () const;
+    IMF_EXPORT
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with
+    // MIPMAP_LEVELS files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    //--------------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numLevels () const;
+    IMF_EXPORT
+    int                 numXLevels () const;
+    IMF_EXPORT
+    int                 numYLevels () const;
+    IMF_EXPORT
+    bool                isValidLevel (int lx, int ly) const;
+
+
+    //----------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //----------------------------------------------------------
+
+    IMF_EXPORT
+    int                 levelWidth  (int lx) const;
+    IMF_EXPORT
+    int                 levelHeight (int ly) const;
+
+
+    //--------------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numXTiles (int lx = 0) const;
+    IMF_EXPORT
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional region of
+    // valid pixel coordinates for a level with level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy, int l = 0) const;
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                         int lx, int ly) const;
+
+    //------------------------------------------------------------
+    // Read pixel data:
+    //
+    // readTile(dx, dy, lx, ly) reads the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly),
+    // and stores it in the current frame buffer.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx)-1]
+    //   dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    //   lx must lie in the interval [0, numXLevels()-1]
+    //   ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readTile(dx, dy, level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It calls
+    // readTile(dx, dy, level, level).
+    //
+    // The two readTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // reading multiple tiles at once.  If multi-threading is used
+    // the multiple tiles are read concurrently.
+    //
+    // Pixels that are outside the pixel coordinate range for the
+    // tile's level, are never accessed by readTile().
+    //
+    // Attempting to access a tile that is not present in the file
+    // throws an InputExc exception.
+    //
+    //------------------------------------------------------------
+
+    IMF_EXPORT
+    void                readTile  (int dx, int dy, int l = 0);
+    IMF_EXPORT
+    void                readTile  (int dx, int dy, int lx, int ly);
+
+    IMF_EXPORT
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int lx, int ly);
+
+    IMF_EXPORT
+    void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int l = 0);
+
+
+    //--------------------------------------------------
+    // Read a tile of raw pixel data from the file,
+    // without uncompressing it (this function is
+    // used to implement TiledOutputFile::copyPixels()).
+    //--------------------------------------------------
+
+    IMF_EXPORT
+    void                rawTileData (int &dx, int &dy,
+                                   int &lx, int &ly,
+                                   char *data,
+                                   Int64 &dataSize
+                                   ) const;
+
+    //------------------------------------------------------------------
+    // Read pixel sample counts into a slice in the frame buffer.
+    //
+    // readPixelSampleCount(dx, dy, lx, ly) reads the sample counts
+    // for tile (dx, dy) in level (lx, ly).
+    //
+    // readPixelSampleCount(dx, dy, l) calls
+    // readPixelSampleCount(dx, dy, lx = l, ly = l)
+    //
+    // dx must lie in the interval [0, numXTiles(lx)-1]
+    // dy must lie in the interval [0, numYTiles(ly)-1]
+    //
+    // lx must lie in the interval [0, numXLevels()-1]
+    // ly must lie in the inverval [0, numYLevels()-1]
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx, ly) reads all
+    // the sample counts for tiles within range
+    // [(min(dx1, dx2), min(dy1, dy2))...(max(dx1, dx2), max(dy1, dy2)],
+    // and on level (lx, ly)
+    //
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, l) calls
+    // readPixelSampleCounts(dx1, dx2, dy1, dy2, lx = l, ly = l).
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                readPixelSampleCount  (int dx, int dy, int l = 0);
+    IMF_EXPORT
+    void                readPixelSampleCount  (int dx, int dy, int lx, int ly);
+
+    IMF_EXPORT
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                            int dy1, int dy2,
+                                            int lx, int ly);
+
+    IMF_EXPORT
+    void                readPixelSampleCounts (int dx1, int dx2,
+                                            int dy1, int dy2,
+                                            int l = 0);
+
+  private:
+    DeepTiledInputFile* file;
+
+    friend void DeepTiledOutputFile::copyPixels(DeepTiledInputPart &);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif /* IMFDEEPTILEDINPUTPART_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledOutputFile.cpp b/3rdparty/openexr/IlmImf/ImfDeepTiledOutputFile.cpp
new file mode 100644 (file)
index 0000000..ef79135
--- /dev/null
@@ -0,0 +1,2055 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfDeepTiledOutputFile.h"
+#include "ImfDeepTiledInputFile.h"
+#include "ImfDeepTiledInputPart.h"
+#include "ImfInputFile.h"
+#include "ImfTileDescriptionAttribute.h"
+#include "ImfPreviewImageAttribute.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfTiledMisc.h"
+#include "ImfStdIO.h"
+#include "ImfCompressor.h"
+#include "ImfOutputStreamMutex.h"
+#include "ImfOutputPartData.h"
+#include "ImfArray.h"
+#include "ImfXdr.h"
+#include "ImfVersion.h"
+#include "ImfTileOffsets.h"
+#include "ImfThreading.h"
+#include "ImfPartType.h"
+
+#include "ImathBox.h"
+
+#include "IlmThreadPool.h"
+#include "IlmThreadSemaphore.h"
+#include "IlmThreadMutex.h"
+
+#include "Iex.h"
+
+#include <string>
+#include <vector>
+#include <fstream>
+#include <assert.h>
+#include <map>
+#include <algorithm>
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using std::string;
+using std::vector;
+using std::ofstream;
+using std::map;
+using std::min;
+using std::max;
+using std::swap;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
+namespace {
+
+struct TOutSliceInfo
+{
+    PixelType                   type;
+    const char *                base;
+    size_t                      sampleStride;
+    size_t                      xStride;
+    size_t                      yStride;
+    bool                        zero;
+    int                         xTileCoords;
+    int                         yTileCoords;
+
+    TOutSliceInfo (PixelType type = HALF,
+                   size_t sampleStride = 0,
+                   size_t xStride = 0,
+                   size_t yStride = 0,
+                   bool zero = false,
+                   int xTileCoords = 0,
+                   int yTileCoords = 0);
+};
+
+
+TOutSliceInfo::TOutSliceInfo (PixelType t,
+                              size_t spst,
+                              size_t xStride,
+                              size_t yStride,
+                              bool z,
+                              int xtc,
+                              int ytc)
+:
+    type (t),
+    sampleStride (spst),
+    xStride(xStride),
+    yStride(yStride),
+    zero (z),
+    xTileCoords (xtc),
+    yTileCoords (ytc)
+{
+    // empty
+}
+
+
+struct TileCoord
+{
+    int         dx;
+    int         dy;
+    int         lx;
+    int         ly;
+
+
+    TileCoord (int xTile = 0, int yTile = 0,
+               int xLevel = 0, int yLevel = 0)
+    :
+        dx (xTile),  dy (yTile),
+        lx (xLevel), ly (yLevel)
+    {
+        // empty
+    }
+
+
+    bool
+    operator < (const TileCoord &other) const
+    {
+        return (ly < other.ly) ||
+               (ly == other.ly && lx < other.lx) ||
+               ((ly == other.ly && lx == other.lx) &&
+                    ((dy < other.dy) || (dy == other.dy && dx < other.dx)));
+    }
+
+
+    bool
+    operator == (const TileCoord &other) const
+    {
+        return lx == other.lx &&
+               ly == other.ly &&
+               dx == other.dx &&
+               dy == other.dy;
+    }
+};
+
+
+struct BufferedTile
+{
+    char *      pixelData;
+    Int64         pixelDataSize;
+    Int64         unpackedDataSize;
+    char *      sampleCountTableData;
+    Int64         sampleCountTableSize;
+
+    BufferedTile (const char *data, int size, int unpackedSize,
+                  const char *tableData, int tableSize):
+        pixelData (0),
+        pixelDataSize(size),
+        unpackedDataSize(unpackedSize),
+        sampleCountTableData(0),
+        sampleCountTableSize(tableSize)
+    {
+        pixelData = new char[pixelDataSize];
+        memcpy (pixelData, data, pixelDataSize);
+
+        sampleCountTableData = new char[tableSize];
+        memcpy (sampleCountTableData, tableData, tableSize);
+    }
+
+    ~BufferedTile()
+    {
+        delete [] pixelData;
+        delete [] sampleCountTableData;
+    }
+};
+
+
+typedef map <TileCoord, BufferedTile *> TileMap;
+
+
+struct TileBuffer
+{
+    Array<char>         buffer;
+    const char *        dataPtr;
+    Int64               dataSize;
+    Int64               uncompressedSize;
+    Compressor *        compressor;
+    Array<char>         sampleCountTableBuffer;
+    const char *        sampleCountTablePtr;
+    Int64               sampleCountTableSize;
+    Compressor*         sampleCountTableCompressor;
+    TileCoord           tileCoord;
+    bool                hasException;
+    string              exception;
+
+     TileBuffer ();
+    ~TileBuffer ();
+
+    inline void         wait () {_sem.wait();}
+    inline void         post () {_sem.post();}
+
+  protected:
+
+    Semaphore           _sem;
+};
+
+
+TileBuffer::TileBuffer ():
+    dataPtr (0),
+    dataSize (0),
+    compressor (0),
+    sampleCountTablePtr (0),
+    sampleCountTableCompressor (0),
+    hasException (false),
+    exception (),
+    _sem (1)
+{
+    // empty
+}
+
+
+TileBuffer::~TileBuffer ()
+{
+    if (compressor != 0)
+        delete compressor;
+
+    if (sampleCountTableCompressor != 0)
+        delete sampleCountTableCompressor;
+}
+
+
+} // namespace
+
+
+struct DeepTiledOutputFile::Data
+{
+    Header              header;                 // the image header
+    int                 version;                // file format version
+    bool                multipart;              // file is multipart
+    TileDescription     tileDesc;               // describes the tile layout
+    DeepFrameBuffer     frameBuffer;            // framebuffer to write into
+    Int64               previewPosition;
+    LineOrder           lineOrder;              // the file's lineorder
+    int                 minX;                   // data window's min x coord
+    int                 maxX;                   // data window's max x coord
+    int                 minY;                   // data window's min y coord
+    int                 maxY;                   // data window's max x coord
+
+    int                 numXLevels;             // number of x levels
+    int                 numYLevels;             // number of y levels
+    int *               numXTiles;              // number of x tiles at a level
+    int *               numYTiles;              // number of y tiles at a level
+
+    TileOffsets         tileOffsets;            // stores offsets in file for
+                                                // each tile
+
+    Compressor::Format  format;                 // compressor's data format
+    vector<TOutSliceInfo*> slices;              // info about channels in file
+
+    vector<TileBuffer*> tileBuffers;
+
+    Int64               tileOffsetsPosition;    // position of the tile index
+
+    TileMap             tileMap;                // the map of buffered tiles
+    TileCoord           nextTileToWrite;
+
+    int                 partNumber;             // the output part number
+
+    char*               sampleCountSliceBase;   // the pointer to the number
+                                                // of samples in each pixel
+    int                 sampleCountXStride;     // the x stride for sampleCountSliceBase
+    int                 sampleCountYStride;     // the y stride for sampleCountSliceBase
+    int                 sampleCountXTileCoords; // using x coordinates relative to current tile
+    int                 sampleCountYTileCoords; // using y coordinates relative to current tile
+
+    Int64                 maxSampleCountTableSize;// the max size in bytes for a pixel
+                                                // sample count table
+    OutputStreamMutex*  _streamData;
+    bool                _deleteStream;
+                                                
+     Data (int numThreads);
+    ~Data ();
+
+    inline TileBuffer * getTileBuffer (int number);
+                                                // hash function from tile
+                                                // buffer coords into our
+                                                // vector of tile buffers
+
+    int&                getSampleCount(int x, int y);
+                                                // get the number of samples
+                                                // in each pixel
+
+    TileCoord           nextTileCoord (const TileCoord &a);
+};
+
+
+DeepTiledOutputFile::Data::Data (int numThreads):
+    numXTiles(0),
+    numYTiles(0),
+    tileOffsetsPosition (0),
+    partNumber(-1),
+    _streamData(NULL),
+    _deleteStream(true)
+{
+    //
+    // We need at least one tileBuffer, but if threading is used,
+    // to keep n threads busy we need 2*n tileBuffers
+    //
+
+    tileBuffers.resize (max (1, 2 * numThreads));
+    for (size_t i = 0; i < tileBuffers.size(); i++)
+        tileBuffers[i] = 0;
+}
+
+
+DeepTiledOutputFile::Data::~Data ()
+{
+    delete [] numXTiles;
+    delete [] numYTiles;
+
+    //
+    // Delete all the tile buffers, if any still happen to exist
+    //
+
+    for (TileMap::iterator i = tileMap.begin(); i != tileMap.end(); ++i)
+        delete i->second;
+
+    for (size_t i = 0; i < tileBuffers.size(); i++)
+        if (tileBuffers[i] != 0)
+            delete tileBuffers[i];
+
+    for (size_t i = 0; i < slices.size(); i++)
+        delete slices[i];
+}
+
+
+int&
+DeepTiledOutputFile::Data::getSampleCount(int x, int y)
+{
+    return sampleCount(sampleCountSliceBase,
+                       sampleCountXStride,
+                       sampleCountYStride,
+                       x, y);
+}
+
+
+TileBuffer*
+DeepTiledOutputFile::Data::getTileBuffer (int number)
+{
+    return tileBuffers[number % tileBuffers.size()];
+}
+
+
+TileCoord
+DeepTiledOutputFile::Data::nextTileCoord (const TileCoord &a)
+{
+    TileCoord b = a;
+
+    if (lineOrder == INCREASING_Y)
+    {
+        b.dx++;
+
+        if (b.dx >= numXTiles[b.lx])
+        {
+            b.dx = 0;
+            b.dy++;
+
+            if (b.dy >= numYTiles[b.ly])
+            {
+                //
+                // the next tile is in the next level
+                //
+
+                b.dy = 0;
+
+                switch (tileDesc.mode)
+                {
+                  case ONE_LEVEL:
+                  case MIPMAP_LEVELS:
+
+                    b.lx++;
+                    b.ly++;
+                    break;
+
+                  case RIPMAP_LEVELS:
+
+                    b.lx++;
+
+                    if (b.lx >= numXLevels)
+                    {
+                        b.lx = 0;
+                        b.ly++;
+
+                        #ifdef DEBUG
+                            assert (b.ly <= numYLevels);
+                        #endif
+                    }
+                    break;
+                  case NUM_LEVELMODES :
+                      throw IEX_NAMESPACE::LogicExc("unknown level mode computing nextTileCoord");
+                }
+            }
+        }
+    }
+    else if (lineOrder == DECREASING_Y)
+    {
+        b.dx++;
+
+        if (b.dx >= numXTiles[b.lx])
+        {
+            b.dx = 0;
+            b.dy--;
+
+            if (b.dy < 0)
+            {
+                //
+                // the next tile is in the next level
+                //
+
+                switch (tileDesc.mode)
+                {
+                  case ONE_LEVEL:
+                  case MIPMAP_LEVELS:
+
+                    b.lx++;
+                    b.ly++;
+                    break;
+
+                  case RIPMAP_LEVELS:
+
+                    b.lx++;
+
+                    if (b.lx >= numXLevels)
+                    {
+                        b.lx = 0;
+                        b.ly++;
+
+                        #ifdef DEBUG
+                            assert (b.ly <= numYLevels);
+                        #endif
+                    }
+                    break;
+                  case NUM_LEVELMODES :
+                      throw IEX_NAMESPACE::LogicExc("unknown level mode computing nextTileCoord");
+                }
+
+                if (b.ly < numYLevels)
+                    b.dy = numYTiles[b.ly] - 1;
+            }
+        }
+    }else if(lineOrder==RANDOM_Y)
+    {                 
+        THROW (IEX_NAMESPACE::ArgExc,
+              "can't compute next tile from randomly ordered image: use getTilesInOrder instead");
+        
+    }
+
+    return b;
+}
+
+
+namespace {
+
+void
+writeTileData (DeepTiledOutputFile::Data *ofd,
+               int dx, int dy,
+               int lx, int ly,
+               const char pixelData[],
+               Int64 pixelDataSize,
+               Int64 unpackedDataSize,
+               const char sampleCountTableData[],
+               Int64 sampleCountTableSize)
+{
+    
+    //
+    // Store a block of pixel data in the output file, and try
+    // to keep track of the current writing position the file,
+    // without calling tellp() (tellp() can be fairly expensive).
+    //
+
+    Int64 currentPosition = ofd->_streamData->currentPosition;
+    ofd->_streamData->currentPosition = 0;
+
+    if (currentPosition == 0)
+        currentPosition = ofd->_streamData->os->tellp();
+
+    ofd->tileOffsets (dx, dy, lx, ly) = currentPosition;
+
+    #ifdef DEBUG
+        assert (ofd->_streamData->os->tellp() == currentPosition);
+    #endif
+
+    //
+    // Write the tile header.
+    //
+
+    if (ofd->multipart)
+    {
+        Xdr::write <StreamIO> (*ofd->_streamData->os, ofd->partNumber);
+    }
+    Xdr::write <StreamIO> (*ofd->_streamData->os, dx);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, dy);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, lx);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, ly);
+
+    //
+    // Write the packed size of the pixel sample count table (64 bits)
+    //
+
+    Xdr::write <StreamIO> (*ofd->_streamData->os, sampleCountTableSize);
+
+    //
+    // Write the packed and unpacked data size (64 bits each)
+    //
+
+    Xdr::write <StreamIO> (*ofd->_streamData->os, pixelDataSize);
+    Xdr::write <StreamIO> (*ofd->_streamData->os, unpackedDataSize);
+
+    //
+    // Write the compressed pixel sample count table.
+    //
+
+    ofd->_streamData->os->write (sampleCountTableData, sampleCountTableSize);
+
+    //
+    // Write the compressed data.
+    //
+
+    ofd->_streamData->os->write (pixelData, pixelDataSize);
+
+    //
+    // Keep current position in the file so that we can avoid
+    // redundant seekg() operations (seekg() can be fairly expensive).
+    //
+
+    ofd->_streamData->currentPosition = currentPosition        +
+                                  4 * Xdr::size<int>()   + // dx, dy, lx, ly,
+                                  3 * Xdr::size<Int64>() + // sampleCountTableSize,
+                                                           // pixelDataSize,
+                                                           // unpackedDataSize
+                                  sampleCountTableSize   +
+                                  pixelDataSize;
+
+    if (ofd->multipart)
+    {
+        ofd->_streamData->currentPosition += Xdr::size<int>();
+    }
+}
+
+
+
+void
+bufferedTileWrite (
+                   DeepTiledOutputFile::Data *ofd,
+                   int dx, int dy,
+                   int lx, int ly,
+                   const char pixelData[],
+                   Int64 pixelDataSize,
+                   Int64 unpackedDataSize,
+                   const char sampleCountTableData[],
+                   Int64 sampleCountTableSize)
+{
+    //
+    // Check if a tile with coordinates (dx,dy,lx,ly) has already been written.
+    //
+
+    if (ofd->tileOffsets (dx, dy, lx, ly))
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Attempt to write tile "
+               "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
+               "more than once.");
+    }
+
+    //
+    // If tiles can be written in random order, then don't buffer anything.
+    //
+
+    if (ofd->lineOrder == RANDOM_Y)
+    {
+        writeTileData (ofd, dx, dy, lx, ly,
+                       pixelData, pixelDataSize, unpackedDataSize,
+                       sampleCountTableData, sampleCountTableSize);
+        return;
+    }
+
+    //
+    // If the tiles cannot be written in random order, then check if a
+    // tile with coordinates (dx,dy,lx,ly) has already been buffered.
+    //
+
+    TileCoord currentTile = TileCoord(dx, dy, lx, ly);
+
+    if (ofd->tileMap.find (currentTile) != ofd->tileMap.end())
+    {
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Attempt to write tile "
+               "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
+               "more than once.");
+    }
+
+    //
+    // If all the tiles before this one have already been written to the file,
+    // then write this tile immediately and check if we have buffered tiles
+    // that can be written after this tile.
+    //
+    // Otherwise, buffer the tile so it can be written to file later.
+    //
+
+    if (ofd->nextTileToWrite == currentTile)
+    {
+        writeTileData (ofd, dx, dy, lx, ly,
+                       pixelData, pixelDataSize, unpackedDataSize,
+                       sampleCountTableData, sampleCountTableSize);
+        ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite);
+
+        TileMap::iterator i = ofd->tileMap.find (ofd->nextTileToWrite);
+
+        //
+        // Step through the tiles and write all successive buffered tiles after
+        // the current one.
+        //
+
+        while(i != ofd->tileMap.end())
+        {
+            //
+            // Write the tile, and then delete the tile's buffered data
+            //
+
+            writeTileData (ofd,
+                           i->first.dx, i->first.dy,
+                           i->first.lx, i->first.ly,
+                           i->second->pixelData,
+                           i->second->pixelDataSize,
+                           i->second->unpackedDataSize,
+                           i->second->sampleCountTableData,
+                           i->second->sampleCountTableSize);
+
+            delete i->second;
+            ofd->tileMap.erase (i);
+
+            //
+            // Proceed to the next tile
+            //
+
+            ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite);
+            i = ofd->tileMap.find (ofd->nextTileToWrite);
+        }
+    }
+    else
+    {
+        //
+        // Create a new BufferedTile, copy the pixelData into it, and
+        // insert it into the tileMap.
+        //
+
+        ofd->tileMap[currentTile] =
+            new BufferedTile ((const char *)pixelData, pixelDataSize, unpackedDataSize,
+                              sampleCountTableData, sampleCountTableSize);
+    }
+}
+
+
+void
+convertToXdr (DeepTiledOutputFile::Data *ofd,
+              Array<char>& tileBuffer,
+              int numScanLines,
+              vector<Int64>& bytesPerLine)
+{
+    //
+    // Convert the contents of a TiledOutputFile's tileBuffer from the
+    // machine's native representation to Xdr format. This function is called
+    // by writeTile(), below, if the compressor wanted its input pixel data
+    // in the machine's native format, but then failed to compress the data
+    // (most compressors will expand rather than compress random input data).
+    //
+    // Note that this routine assumes that the machine's native representation
+    // of the pixel data has the same size as the Xdr representation.  This
+    // makes it possible to convert the pixel data in place, without an
+    // intermediate temporary buffer.
+    //
+
+    //
+    // Set these to point to the start of the tile.
+    // We will write to toPtr, and read from fromPtr.
+    //
+
+    char *writePtr = tileBuffer;
+    const char *readPtr = writePtr;
+
+    //
+    // Iterate over all scan lines in the tile.
+    //
+
+    for (int y = 0; y < numScanLines; ++y)
+    {
+        //
+        // Iterate over all slices in the file.
+        //
+
+        for (unsigned int i = 0; i < ofd->slices.size(); ++i)
+        {
+            const TOutSliceInfo &slice = *ofd->slices[i];
+
+            //
+            // Convert the samples in place.
+            //
+
+            Int64 numPixelsPerScanLine = bytesPerLine[y];
+
+            convertInPlace (writePtr, readPtr, slice.type,
+                            numPixelsPerScanLine);
+        }
+    }
+
+    #ifdef DEBUG
+
+        assert (writePtr == readPtr);
+
+    #endif
+}
+
+
+//
+// A TileBufferTask encapsulates the task of copying a tile from
+// the user's framebuffer into a LineBuffer and compressing the data
+// if necessary.
+//
+
+class TileBufferTask: public Task
+{
+  public:
+
+    TileBufferTask (TaskGroup *group,
+                    DeepTiledOutputFile::Data *ofd,
+                    int number,
+                    int dx, int dy,
+                    int lx, int ly);
+
+    virtual ~TileBufferTask ();
+
+    virtual void                execute ();
+
+  private:
+
+    DeepTiledOutputFile::Data *     _ofd;
+    TileBuffer *                _tileBuffer;
+};
+
+
+TileBufferTask::TileBufferTask
+    (TaskGroup *group,
+     DeepTiledOutputFile::Data *ofd,
+     int number,
+     int dx, int dy,
+     int lx, int ly)
+:
+    Task (group),
+    _ofd (ofd),
+    _tileBuffer (_ofd->getTileBuffer (number))
+{
+    //
+    // Wait for the tileBuffer to become available
+    //
+
+    _tileBuffer->wait ();
+    _tileBuffer->tileCoord = TileCoord (dx, dy, lx, ly);
+}
+
+
+TileBufferTask::~TileBufferTask ()
+{
+    //
+    // Signal that the tile buffer is now free
+    //
+
+    _tileBuffer->post ();
+}
+
+
+void
+TileBufferTask::execute ()
+{
+    try
+    {
+        //
+        // First copy the pixel data from the frame buffer
+        // into the tile buffer
+        //
+        // Convert one tile's worth of pixel data to
+        // a machine-independent representation, and store
+        // the result in _tileBuffer->buffer.
+        //
+
+        Box2i tileRange = OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _ofd->tileDesc,
+                _ofd->minX, _ofd->maxX,
+                _ofd->minY, _ofd->maxY,
+                _tileBuffer->tileCoord.dx,
+                _tileBuffer->tileCoord.dy,
+                _tileBuffer->tileCoord.lx,
+                _tileBuffer->tileCoord.ly);
+
+        int numScanLines = tileRange.max.y - tileRange.min.y + 1;
+//        int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1;
+
+        //
+        // Get the bytes for each line.
+        //
+
+        vector<Int64> bytesPerLine(_ofd->tileDesc.ySize);
+        vector<int> xOffsets(_ofd->slices.size());
+        vector<int> yOffsets(_ofd->slices.size());
+        for (size_t i = 0; i < _ofd->slices.size(); i++)
+        {
+            const TOutSliceInfo &slice = *_ofd->slices[i];
+            xOffsets[i] = slice.xTileCoords * tileRange.min.x;
+            yOffsets[i] = slice.yTileCoords * tileRange.min.y;
+        }
+
+        calculateBytesPerLine(_ofd->header,
+                              _ofd->sampleCountSliceBase,
+                              _ofd->sampleCountXStride,
+                              _ofd->sampleCountYStride,
+                              tileRange.min.x, tileRange.max.x,
+                              tileRange.min.y, tileRange.max.y,
+                              xOffsets, yOffsets,
+                              bytesPerLine);
+
+        //
+        // Allocate the memory for internal buffer.
+        // (TODO) more efficient memory management?
+        //
+
+        Int64 totalBytes = 0;
+        Int64 maxBytesPerTileLine = 0;
+        for (size_t i = 0; i < bytesPerLine.size(); i++)
+        {
+            totalBytes += bytesPerLine[i];
+            if (bytesPerLine[i] > maxBytesPerTileLine)
+                maxBytesPerTileLine = bytesPerLine[i];
+        }
+        _tileBuffer->buffer.resizeErase(totalBytes);
+
+        char *writePtr = _tileBuffer->buffer;
+
+        //
+        // Iterate over the scan lines in the tile.
+        //
+
+        int xOffsetForSampleCount =
+                (_ofd->sampleCountXTileCoords == 0) ? 0 : tileRange.min.x;
+        int yOffsetForSampleCount =
+                (_ofd->sampleCountYTileCoords == 0) ? 0 : tileRange.min.y;
+
+        for (int y = tileRange.min.y; y <= tileRange.max.y; ++y)
+        {
+            //
+            // Iterate over all image channels.
+            //
+
+            for (unsigned int i = 0; i < _ofd->slices.size(); ++i)
+            {
+                const TOutSliceInfo &slice = *_ofd->slices[i];
+
+
+                //
+                // Fill the tile buffer with pixel data.
+                //
+
+                if (slice.zero)
+                {
+                    //
+                    // The frame buffer contains no data for this channel.
+                    // Store zeroes in _data->tileBuffer.
+                    //
+
+                    fillChannelWithZeroes (writePtr, _ofd->format, slice.type,
+                                           bytesPerLine[y - tileRange.min.y]);
+                }
+                else
+                {
+                    //
+                    // The frame buffer contains data for this channel.
+                    //
+
+                
+                    int xOffsetForData = slice.xTileCoords ? tileRange.min.x : 0;
+                    int yOffsetForData = slice.yTileCoords ? tileRange.min.y : 0;
+
+                    // (TOOD) treat sample count offsets differently.
+                    copyFromDeepFrameBuffer (writePtr,
+                                             slice.base,
+                                             _ofd->sampleCountSliceBase,
+                                             _ofd->sampleCountXStride,
+                                             _ofd->sampleCountYStride,
+                                             y,
+                                             tileRange.min.x,
+                                             tileRange.max.x,
+                                             xOffsetForSampleCount,
+                                             yOffsetForSampleCount,
+                                             xOffsetForData,
+                                             yOffsetForData,
+                                             slice.sampleStride,
+                                             slice.xStride,
+                                             slice.yStride,
+                                             _ofd->format,
+                                             slice.type);
+#if defined(DEBUG)
+                      assert(writePtr-_tileBuffer->buffer<=totalBytes);
+#endif
+                }
+            }
+        }
+
+        //
+        // Compress the pixel sample count table.
+        //
+
+        char* ptr = _tileBuffer->sampleCountTableBuffer;
+        Int64 tableDataSize = 0;
+        for (int i = tileRange.min.y; i <= tileRange.max.y; i++)
+        {
+            int count = 0;
+            for (int j = tileRange.min.x; j <= tileRange.max.x; j++)
+            {
+                count += _ofd->getSampleCount(j - xOffsetForSampleCount,
+                                              i - yOffsetForSampleCount);
+                Xdr::write <CharPtrIO> (ptr, count);
+                tableDataSize += sizeof (int);
+            }
+        }
+
+       if(_tileBuffer->sampleCountTableCompressor)
+       {
+           _tileBuffer->sampleCountTableSize =
+                _tileBuffer->sampleCountTableCompressor->compress (
+                                                    _tileBuffer->sampleCountTableBuffer,
+                                                    tableDataSize,
+                                                    tileRange.min.y,
+                                                    _tileBuffer->sampleCountTablePtr);
+       }
+       
+        //
+        // If we can't make data shrink (or compression was disabled), then just use the raw data.
+        //
+
+        if ( ! _tileBuffer->sampleCountTableCompressor ||
+            _tileBuffer->sampleCountTableSize >= _ofd->maxSampleCountTableSize)
+        {
+            _tileBuffer->sampleCountTableSize = _ofd->maxSampleCountTableSize;
+            _tileBuffer->sampleCountTablePtr = _tileBuffer->sampleCountTableBuffer;
+        }
+
+        //
+        // Compress the contents of the tileBuffer,
+        // and store the compressed data in the output file.
+        //
+
+        _tileBuffer->dataSize = writePtr - _tileBuffer->buffer;
+        _tileBuffer->uncompressedSize = _tileBuffer->dataSize;
+        _tileBuffer->dataPtr = _tileBuffer->buffer;
+
+        // (TODO) don't do this all the time.
+        if (_tileBuffer->compressor != 0)
+            delete _tileBuffer->compressor;
+        _tileBuffer->compressor = newTileCompressor
+                                    (_ofd->header.compression(),
+                                     maxBytesPerTileLine,
+                                     _ofd->tileDesc.ySize,
+                                     _ofd->header);
+
+        if (_tileBuffer->compressor)
+        {
+            const char *compPtr;
+
+            Int64 compSize = _tileBuffer->compressor->compressTile
+                                                (_tileBuffer->dataPtr,
+                                                 _tileBuffer->dataSize,
+                                                 tileRange, compPtr);
+
+            if (compSize < _tileBuffer->dataSize)
+            {
+                _tileBuffer->dataSize = compSize;
+                _tileBuffer->dataPtr = compPtr;
+            }
+            else if (_ofd->format == Compressor::NATIVE)
+            {
+                //
+                // The data did not shrink during compression, but
+                // we cannot write to the file using native format,
+                // so we need to convert the lineBuffer to Xdr.
+                //
+
+                convertToXdr (_ofd, _tileBuffer->buffer, numScanLines,
+                              bytesPerLine);
+            }
+        }
+    }
+    catch (std::exception &e)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = e.what ();
+            _tileBuffer->hasException = true;
+        }
+    }
+    catch (...)
+    {
+        if (!_tileBuffer->hasException)
+        {
+            _tileBuffer->exception = "unrecognized exception";
+            _tileBuffer->hasException = true;
+        }
+    }
+}
+
+} // namespace
+
+
+DeepTiledOutputFile::DeepTiledOutputFile
+    (const char fileName[],
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+
+{
+    _data->_streamData=new OutputStreamMutex();
+    _data->_deleteStream =true;
+    try
+    {
+        header.sanityCheck (true);
+        _data->_streamData->os = new StdOFStream (fileName);
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition = _data->header.writeTo (*_data->_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_data->_streamData->os);
+       _data->multipart = false;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data && _data->_streamData && _data->_streamData->os) delete _data->_streamData->os;
+        if (_data && _data->_streamData)     delete _data->_streamData;
+        if (_data)           delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        if (_data && _data->_streamData && _data->_streamData->os) delete _data->_streamData->os;
+        if (_data->_streamData)     delete _data->_streamData;
+        if (_data)           delete _data;
+
+        throw;
+    }
+}
+
+
+DeepTiledOutputFile::DeepTiledOutputFile
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+     const Header &header,
+     int numThreads)
+:
+    _data (new Data (numThreads))
+{
+    _data->_streamData=new OutputStreamMutex();
+    _data->_deleteStream=false;
+    
+    try
+    {
+        header.sanityCheck(true);
+        _data->_streamData->os = &os;
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition = _data->header.writeTo (*_data->_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_data->_streamData->os);
+       _data->multipart = false;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << os.fileName() << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        if (_data && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+
+        throw;
+    }
+}
+
+DeepTiledOutputFile::DeepTiledOutputFile(const OutputPartData* part) 
+{
+   
+    try
+    {
+        if (part->header.type() != DEEPTILE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a DeepTiledOutputFile from "
+                              "a type-mismatched part.");
+
+        _data = new Data (part->numThreads);
+        _data->_streamData=part->mutex;
+        _data->_deleteStream=false;
+        initialize(part->header);
+        _data->partNumber = part->partNumber;
+        _data->tileOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+       _data->multipart = part->multipart;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data) delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                     "\"" << part->partNumber << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        if (_data) delete _data;
+
+        throw;
+    }
+}
+
+void
+DeepTiledOutputFile::initialize (const Header &header)
+{
+    _data->header = header;
+    _data->header.setType(DEEPTILE);
+    _data->lineOrder = _data->header.lineOrder();
+
+    //
+    // Check that the file is indeed tiled
+    //
+
+    _data->tileDesc = _data->header.tileDescription();
+
+    //
+    // Save the dataWindow information
+    //
+
+    const Box2i &dataWindow = _data->header.dataWindow();
+    _data->minX = dataWindow.min.x;
+    _data->maxX = dataWindow.max.x;
+    _data->minY = dataWindow.min.y;
+    _data->maxY = dataWindow.max.y;
+
+    //
+    // Precompute level and tile information to speed up utility functions
+    //
+
+    precalculateTileInfo (_data->tileDesc,
+                          _data->minX, _data->maxX,
+                          _data->minY, _data->maxY,
+                          _data->numXTiles, _data->numYTiles,
+                          _data->numXLevels, _data->numYLevels);
+
+    //
+    // Determine the first tile coordinate that we will be writing
+    // if the file is not RANDOM_Y.
+    //
+
+    _data->nextTileToWrite = (_data->lineOrder == INCREASING_Y)?
+                               TileCoord (0, 0, 0, 0):
+                               TileCoord (0, _data->numYTiles[0] - 1, 0, 0);
+
+    Compressor* compressor = newTileCompressor
+                                (_data->header.compression(),
+                                 0,
+                                 _data->tileDesc.ySize,
+                                 _data->header);
+
+    _data->format = defaultFormat (compressor);
+
+    if (compressor != 0)
+        delete compressor;
+
+    _data->tileOffsets = TileOffsets (_data->tileDesc.mode,
+                                      _data->numXLevels,
+                                      _data->numYLevels,
+                                      _data->numXTiles,
+                                      _data->numYTiles);
+                                      
+    //ignore the existing value of chunkCount - correct it if it's wrong
+    _data->header.setChunkCount(getChunkOffsetTableSize(_data->header,true));                                   
+                                      
+    _data->maxSampleCountTableSize = _data->tileDesc.ySize *
+                                     _data->tileDesc.xSize *
+                                     sizeof(int);
+
+                                     
+    for (size_t i = 0; i < _data->tileBuffers.size(); i++)
+    {
+        _data->tileBuffers[i] = new TileBuffer ();
+
+        _data->tileBuffers[i]->sampleCountTableBuffer.
+                resizeErase(_data->maxSampleCountTableSize);
+
+        char * p = &(_data->tileBuffers[i]->sampleCountTableBuffer[0]);
+        memset (p, 0, _data->maxSampleCountTableSize);
+
+        _data->tileBuffers[i]->sampleCountTableCompressor =
+                newCompressor (_data->header.compression(),
+                               _data->maxSampleCountTableSize,
+                               _data->header);
+    }
+}
+
+
+DeepTiledOutputFile::~DeepTiledOutputFile ()
+{
+    if (_data)
+    {
+        {
+            Lock lock(*_data->_streamData);
+            Int64 originalPosition = _data->_streamData->os->tellp();
+
+            if (_data->tileOffsetsPosition > 0)
+            {
+                try
+                {
+                    _data->_streamData->os->seekp (_data->tileOffsetsPosition);
+                    _data->tileOffsets.writeTo (*_data->_streamData->os);
+
+                    //
+                    // Restore the original position.
+                    //
+                    _data->_streamData->os->seekp (originalPosition);
+                }
+                catch (...)
+                {
+                    //
+                    // We cannot safely throw any exceptions from here.
+                    // This destructor may have been called because the
+                    // stack is currently being unwound for another
+                    // exception.
+                    //
+                }
+            }
+        }
+
+        if (_data->_deleteStream && _data->_streamData)
+            delete _data->_streamData->os;
+
+        //
+        // (TODO) we should have a way to tell if the stream data is owned by
+        // this file or by a parent multipart file.
+        //
+
+        if (_data->partNumber == -1 && _data->_streamData)
+            delete _data->_streamData;
+
+        delete _data;
+    }
+}
+
+
+const char *
+DeepTiledOutputFile::fileName () const
+{
+    return _data->_streamData->os->fileName();
+}
+
+
+const Header &
+DeepTiledOutputFile::header () const
+{
+    return _data->header;
+}
+
+
+void
+DeepTiledOutputFile::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    Lock lock (*_data->_streamData);
+
+    //
+    // Check if the new frame buffer descriptor
+    // is compatible with the image file header.
+    //
+
+    const ChannelList &channels = _data->header.channels();
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+            continue;
+
+        if (i.channel().type != j.slice().type)
+            THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+                                "of output file \"" << fileName() << "\" is "
+                                "not compatible with the frame buffer's "
+                                "pixel type.");
+
+        if (j.slice().xSampling != 1 || j.slice().ySampling != 1)
+            THROW (IEX_NAMESPACE::ArgExc, "All channels in a tiled file must have"
+                                "sampling (1,1).");
+    }
+
+    //
+    // Store the pixel sample count table.
+    //
+
+    const Slice& sampleCountSlice = frameBuffer.getSampleCountSlice();
+    if (sampleCountSlice.base == 0)
+    {
+        throw IEX_NAMESPACE::ArgExc ("Invalid base pointer, please set a proper sample count slice.");
+    }
+    else
+    {
+        _data->sampleCountSliceBase = sampleCountSlice.base;
+        _data->sampleCountXStride = sampleCountSlice.xStride;
+        _data->sampleCountYStride = sampleCountSlice.yStride;
+        _data->sampleCountXTileCoords = sampleCountSlice.xTileCoords;
+        _data->sampleCountYTileCoords = sampleCountSlice.yTileCoords;
+    }
+
+    //
+    // Initialize slice table for writePixels().
+    // Pixel sample count slice is not presented in the header,
+    // so it wouldn't be added here.
+    // Store the pixel base pointer table.
+    //
+
+    vector<TOutSliceInfo*> slices;
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        DeepFrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+        if (j == frameBuffer.end())
+        {
+            //
+            // Channel i is not present in the frame buffer.
+            // In the file, channel i will contain only zeroes.
+            //
+
+            slices.push_back (new TOutSliceInfo (i.channel().type,
+                                                 0, // sampleStride,
+                                                 0, // xStride
+                                                 0, // yStride
+                                                 true)); // zero
+        }
+        else
+        {
+            //
+            // Channel i is present in the frame buffer.
+            //
+
+            slices.push_back (new TOutSliceInfo (j.slice().type,
+                                                 j.slice().sampleStride,
+                                                 j.slice().xStride,
+                                                 j.slice().yStride,
+                                                 false, // zero
+                                                 (j.slice().xTileCoords)? 1: 0,
+                                                 (j.slice().yTileCoords)? 1: 0));
+
+            TOutSliceInfo* slice = slices.back();
+            slice->base = j.slice().base;
+            
+        }
+    }
+
+    //
+    // Store the new frame buffer.
+    //
+
+    _data->frameBuffer = frameBuffer;
+
+    for (size_t i = 0; i < _data->slices.size(); i++)
+        delete _data->slices[i];
+    _data->slices = slices;
+}
+
+
+const DeepFrameBuffer &
+DeepTiledOutputFile::frameBuffer () const
+{
+    Lock lock (*_data->_streamData);
+    return _data->frameBuffer;
+}
+
+
+void
+DeepTiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
+                             int lx, int ly)
+{
+    try
+    {
+        Lock lock (*_data->_streamData);
+
+        if (_data->slices.size() == 0)
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                               "as pixel data source.");
+
+        if (!isValidTile (dx1, dy1, lx, ly) || !isValidTile (dx2, dy2, lx, ly))
+            throw IEX_NAMESPACE::ArgExc ("Tile coordinates are invalid.");
+
+        if (!isValidLevel (lx, ly))
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
+        //
+        // Determine the first and last tile coordinates in both dimensions
+        // based on the file's lineOrder
+        //
+
+        if (dx1 > dx2)
+            swap (dx1, dx2);
+
+        if (dy1 > dy2)
+            swap (dy1, dy2);
+
+        int dyStart = dy1;
+        int dyStop  = dy2 + 1;
+        int dY      = 1;
+
+        if (_data->lineOrder == DECREASING_Y)
+        {
+            dyStart = dy2;
+            dyStop  = dy1 - 1;
+            dY      = -1;
+        }
+
+        int numTiles = (dx2 - dx1 + 1) * (dy2 - dy1 + 1);
+        int numTasks = min ((int)_data->tileBuffers.size(), numTiles);
+
+        //
+        // Create a task group for all tile buffer tasks.  When the
+        // task group goes out of scope, the destructor waits until
+        // all tasks are complete.
+        //
+
+        {
+            TaskGroup taskGroup;
+
+            //
+            // Add in the initial compression tasks to the thread pool
+            //
+
+            int nextCompBuffer = 0;
+            int dxComp         = dx1;
+            int dyComp         = dyStart;
+
+            while (nextCompBuffer < numTasks)
+            {
+                ThreadPool::addGlobalTask (new TileBufferTask (&taskGroup,
+                                                               _data,
+                                                               nextCompBuffer++,
+                                                               dxComp, dyComp,
+                                                               lx, ly));
+                dxComp++;
+
+                if (dxComp > dx2)
+                {
+                    dxComp = dx1;
+                    dyComp += dY;
+                }
+            }
+
+            //
+            // Write the compressed buffers and add in more compression
+            // tasks until done
+            //
+
+            int nextWriteBuffer = 0;
+            int dxWrite         = dx1;
+            int dyWrite         = dyStart;
+
+            while (nextWriteBuffer < numTiles)
+            {
+                //
+                // Wait until the nextWriteBuffer is ready to be written
+                //
+
+                TileBuffer* writeBuffer =
+                                    _data->getTileBuffer (nextWriteBuffer);
+
+                writeBuffer->wait();
+
+                //
+                // Write the tilebuffer
+                //
+
+                bufferedTileWrite ( _data, dxWrite, dyWrite, lx, ly,
+                                   writeBuffer->dataPtr,
+                                   writeBuffer->dataSize,
+                                   writeBuffer->uncompressedSize,
+                                   writeBuffer->sampleCountTablePtr,
+                                   writeBuffer->sampleCountTableSize);
+
+                //
+                // Release the lock on nextWriteBuffer
+                //
+
+                writeBuffer->post();
+
+                //
+                // If there are no more tileBuffers to compress, then
+                // only continue to write out remaining tileBuffers,
+                // otherwise keep adding compression tasks.
+                //
+
+                if (nextCompBuffer < numTiles)
+                {
+                    //
+                    // add nextCompBuffer as a compression Task
+                    //
+
+                    ThreadPool::addGlobalTask
+                        (new TileBufferTask (&taskGroup,
+                                             _data,
+                                             nextCompBuffer,
+                                             dxComp, dyComp,
+                                             lx, ly));
+                }
+
+                nextWriteBuffer++;
+                dxWrite++;
+
+                if (dxWrite > dx2)
+                {
+                    dxWrite = dx1;
+                    dyWrite += dY;
+                }
+
+                nextCompBuffer++;
+                dxComp++;
+
+                if (dxComp > dx2)
+                {
+                    dxComp = dx1;
+                    dyComp += dY;
+                }
+            }
+
+            //
+            // finish all tasks
+            //
+        }
+
+        //
+        // Exeption handling:
+        //
+        // TileBufferTask::execute() may have encountered exceptions, but
+        // those exceptions occurred in another thread, not in the thread
+        // that is executing this call to TiledOutputFile::writeTiles().
+        // TileBufferTask::execute() has caught all exceptions and stored
+        // the exceptions' what() strings in the tile buffers.
+        // Now we check if any tile buffer contains a stored exception; if
+        // this is the case then we re-throw the exception in this thread.
+        // (It is possible that multiple tile buffers contain stored
+        // exceptions.  We re-throw the first exception we find and
+        // ignore all others.)
+        //
+
+        const string *exception = 0;
+
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
+        {
+            TileBuffer *tileBuffer = _data->tileBuffers[i];
+
+            if (tileBuffer->hasException && !exception)
+                exception = &tileBuffer->exception;
+
+            tileBuffer->hasException = false;
+        }
+
+        if (exception)
+            throw IEX_NAMESPACE::IoExc (*exception);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Failed to write pixel data to image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+void
+DeepTiledOutputFile::writeTiles (int dx1, int dxMax, int dyMin, int dyMax, int l)
+{
+    writeTiles (dx1, dxMax, dyMin, dyMax, l, l);
+}
+
+
+void
+DeepTiledOutputFile::writeTile (int dx, int dy, int lx, int ly)
+{
+    writeTiles (dx, dx, dy, dy, lx, ly);
+}
+
+
+void
+DeepTiledOutputFile::writeTile (int dx, int dy, int l)
+{
+    writeTile(dx, dy, l, l);
+}
+
+
+void
+DeepTiledOutputFile::copyPixels (DeepTiledInputFile &in)
+{
+
+   //
+   // Check if this file's and and the InputFile's
+   // headers are compatible.
+   //
+
+   const Header &hdr = _data->header;
+   const Header &inHdr = in.header();
+
+   
+   
+   if (!(hdr.tileDescription() == inHdr.tileDescription()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files have different tile descriptions.");
+
+   if (!(hdr.dataWindow() == inHdr.dataWindow()))
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\". The "
+                            "files have different data windows.");
+
+    if (!(hdr.lineOrder() == inHdr.lineOrder()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files have different line orders.");
+
+    if (!(hdr.compression() == inHdr.compression()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" failed. "
+                            "The files use different compression methods.");
+
+    if (!(hdr.channels() == inHdr.channels()))
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                             "file \"" << in.fileName() << "\" to image "
+                             "file \"" << fileName() << "\" "
+                             "failed.  The files have different channel "
+                             "lists.");
+
+
+    // Verify that no pixel data have been written to this file yet.
+    //
+
+    if (!_data->tileOffsets.isEmpty())
+        THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
+                              "file \"" << in.fileName() << "\" to image "
+                              "file \"" << _data->_streamData->os->fileName() << "\" "
+                              "failed. \"" << fileName() << "\" "
+                              "already contains pixel data.");
+
+    int numAllTiles = in.totalTiles();                              
+                              
+    Lock lock (*_data->_streamData);
+    
+    //
+    // special handling for random tiles
+    //
+    
+    vector<int> dx_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    vector<int> dy_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    vector<int> lx_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    vector<int> ly_list(_data->lineOrder==RANDOM_Y ? numAllTiles : 1);
+    
+    if(_data->lineOrder==RANDOM_Y)
+    {
+        in.getTileOrder(&dx_list[0],&dy_list[0],&lx_list[0],&ly_list[0]);
+        _data->nextTileToWrite.dx=dx_list[0];
+        _data->nextTileToWrite.dy=dy_list[0];
+        _data->nextTileToWrite.lx=lx_list[0];
+        _data->nextTileToWrite.ly=ly_list[0];
+    }
+    
+
+    vector<char> data(4096);
+    for (int i = 0; i < numAllTiles; ++i)
+    {
+
+        int dx = _data->nextTileToWrite.dx;
+        int dy = _data->nextTileToWrite.dy;
+        int lx = _data->nextTileToWrite.lx;
+        int ly = _data->nextTileToWrite.ly;
+
+        Int64 dataSize = data.size();
+
+        in.rawTileData (dx, dy, lx, ly, &data[0], dataSize);
+        if(dataSize>data.size())
+        {
+            data.resize(dataSize);
+            in.rawTileData (dx, dy, lx, ly, &data[0], dataSize);
+        }
+        Int64 sampleCountTableSize = *(Int64 *)(&data[0] + 16);
+        Int64 pixelDataSize = *(Int64 *)(&data[0] + 24);
+        Int64 unpackedPixelDataSize = *(Int64 *)(&data[0] + 32);
+        char * sampleCountTable = &data[0]+40;
+        char * pixelData = sampleCountTable + sampleCountTableSize;
+        
+        writeTileData (_data, dx, dy, lx, ly, pixelData, pixelDataSize,unpackedPixelDataSize,sampleCountTable,sampleCountTableSize);
+        
+        
+        if(_data->lineOrder==RANDOM_Y)
+        {
+            if(i<numAllTiles-1)
+            {
+              _data->nextTileToWrite.dx=dx_list[i+1];
+              _data->nextTileToWrite.dy=dy_list[i+1];
+              _data->nextTileToWrite.lx=lx_list[i+1];
+              _data->nextTileToWrite.ly=ly_list[i+1];
+            }
+        }else{   
+          _data->nextTileToWrite = _data->nextTileCoord (_data->nextTileToWrite);
+        }
+        
+    }
+}
+
+
+void
+DeepTiledOutputFile::copyPixels (DeepTiledInputPart &in)
+{
+  copyPixels(*in.file);
+}
+
+
+unsigned int
+DeepTiledOutputFile::tileXSize () const
+{
+    return _data->tileDesc.xSize;
+}
+
+
+unsigned int
+DeepTiledOutputFile::tileYSize () const
+{
+    return _data->tileDesc.ySize;
+}
+
+
+LevelMode
+DeepTiledOutputFile::levelMode () const
+{
+    return _data->tileDesc.mode;
+}
+
+
+LevelRoundingMode
+DeepTiledOutputFile::levelRoundingMode () const
+{
+    return _data->tileDesc.roundingMode;
+}
+
+
+int
+DeepTiledOutputFile::numLevels () const
+{
+    if (levelMode() == RIPMAP_LEVELS)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
+                              "file \"" << fileName() << "\" "
+                              "(numLevels() is not defined for RIPMAPs).");
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledOutputFile::numXLevels () const
+{
+    return _data->numXLevels;
+}
+
+
+int
+DeepTiledOutputFile::numYLevels () const
+{
+    return _data->numYLevels;
+}
+
+
+bool
+DeepTiledOutputFile::isValidLevel (int lx, int ly) const
+{
+    if (lx < 0 || ly < 0)
+        return false;
+
+    if (levelMode() == MIPMAP_LEVELS && lx != ly)
+        return false;
+
+    if (lx >= numXLevels() || ly >= numYLevels())
+        return false;
+
+    return true;
+}
+
+
+int
+DeepTiledOutputFile::levelWidth (int lx) const
+{
+    try
+    {
+        int retVal = levelSize (_data->minX, _data->maxX, lx,
+                                _data->tileDesc.roundingMode);
+
+        return retVal;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelWidth() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+int
+DeepTiledOutputFile::levelHeight (int ly) const
+{
+    try
+    {
+        return levelSize (_data->minY, _data->maxY, ly,
+                          _data->tileDesc.roundingMode);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling levelHeight() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+int
+DeepTiledOutputFile::numXTiles (int lx) const
+{
+    if (lx < 0 || lx >= _data->numXLevels)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+                              "file \"" << _data->_streamData->os->fileName() << "\" "
+                              "(Argument is not in valid range).");
+
+    return _data->numXTiles[lx];
+}
+
+
+int
+DeepTiledOutputFile::numYTiles (int ly) const
+{
+   if (ly < 0 || ly >= _data->numYLevels)
+        THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+                              "file \"" << _data->_streamData->os->fileName() << "\" "
+                              "(Argument is not in valid range).");
+
+    return _data->numYTiles[ly];
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForLevel (int l) const
+{
+    return dataWindowForLevel (l, l);
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForLevel (int lx, int ly) const
+{
+    try
+    {
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForTile (int dx, int dy, int l) const
+{
+    return dataWindowForTile (dx, dy, l, l);
+}
+
+
+Box2i
+DeepTiledOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    try
+    {
+        if (!isValidTile (dx, dy, lx, ly))
+            throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
+
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                dx, dy,
+                lx, ly);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+bool
+DeepTiledOutputFile::isValidTile (int dx, int dy, int lx, int ly) const
+{
+    return ((lx < _data->numXLevels && lx >= 0) &&
+            (ly < _data->numYLevels && ly >= 0) &&
+            (dx < _data->numXTiles[lx] && dx >= 0) &&
+            (dy < _data->numYTiles[ly] && dy >= 0));
+}
+
+
+void
+DeepTiledOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    Lock lock (*_data->_streamData);
+
+    if (_data->previewPosition <= 0)
+        THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
+                              "File \"" << fileName() << "\" does not "
+                              "contain a preview image.");
+
+    //
+    // Store the new pixels in the header's preview image attribute.
+    //
+
+    PreviewImageAttribute &pia =
+        _data->header.typedAttribute <PreviewImageAttribute> ("preview");
+
+    PreviewImage &pi = pia.value();
+    PreviewRgba *pixels = pi.pixels();
+    int numPixels = pi.width() * pi.height();
+
+    for (int i = 0; i < numPixels; ++i)
+        pixels[i] = newPixels[i];
+
+    //
+    // Save the current file position, jump to the position in
+    // the file where the preview image starts, store the new
+    // preview image, and jump back to the saved file position.
+    //
+
+    Int64 savedPosition = _data->_streamData->os->tellp();
+
+    try
+    {
+        _data->_streamData->os->seekp (_data->previewPosition);
+        pia.writeValueTo (*_data->_streamData->os, _data->version);
+        _data->_streamData->os->seekp (savedPosition);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        REPLACE_EXC (e, "Cannot update preview image pixels for "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
+    }
+}
+
+
+void
+DeepTiledOutputFile::breakTile
+    (int dx, int dy,
+     int lx, int ly,
+     int offset,
+     int length,
+     char c)
+{
+    Lock lock (*_data->_streamData);
+
+    Int64 position = _data->tileOffsets (dx, dy, lx, ly);
+
+    if (!position)
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot overwrite tile "
+               "(" << dx << ", " << dy << ", " << lx << "," << ly << "). "
+               "The tile has not yet been stored in "
+               "file \"" << fileName() << "\".");
+
+    _data->_streamData->currentPosition = 0;
+    _data->_streamData->os->seekp (position + offset);
+
+    for (int i = 0; i < length; ++i)
+        _data->_streamData->os->write (&c, 1);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledOutputFile.h b/3rdparty/openexr/IlmImf/ImfDeepTiledOutputFile.h
new file mode 100644 (file)
index 0000000..fa76a69
--- /dev/null
@@ -0,0 +1,506 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_DEEP_TILED_OUTPUT_FILE_H
+#define INCLUDED_IMF_DEEP_TILED_OUTPUT_FILE_H
+
+//-----------------------------------------------------------------------------
+//
+//      class DeepTiledOutputFile
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImathBox.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class DeepTiledOutputFile : public GenericOutputFile
+{
+  public:
+
+    //-------------------------------------------------------------------
+    // A constructor that opens the file with the specified name, and
+    // writes the file header.  The file header is also copied into the
+    // TiledOutputFile object, and can later be accessed via the header()
+    // method.
+    //
+    // Destroying TiledOutputFile constructed with this constructor
+    // automatically closes the corresponding files.
+    //
+    // The header must contain a TileDescriptionAttribute called "tiles".
+    //
+    // The x and y subsampling factors for all image channels must be 1;
+    // subsampling is not supported.
+    //
+    // Tiles can be written to the file in arbitrary order.  The line
+    // order attribute can be used to cause the tiles to be sorted in
+    // the file.  When the file is read later, reading the tiles in the
+    // same order as they are in the file tends to be significantly
+    // faster than reading the tiles in random order (see writeTile,
+    // below).
+    //-------------------------------------------------------------------
+
+    IMF_EXPORT
+    DeepTiledOutputFile (const char fileName[],
+                         const Header &header,
+                         int numThreads = globalThreadCount ());
+
+
+    // ----------------------------------------------------------------
+    // A constructor that attaches the new TiledOutputFile object to
+    // a file that has already been opened.  Destroying TiledOutputFile
+    // objects constructed with this constructor does not automatically
+    // close the corresponding files.
+    // ----------------------------------------------------------------
+
+    IMF_EXPORT
+    DeepTiledOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                         const Header &header,
+                         int numThreads = globalThreadCount ());
+
+
+    //-----------------------------------------------------
+    // Destructor
+    //
+    // Destroying a TiledOutputFile object before all tiles
+    // have been written results in an incomplete file.
+    //-----------------------------------------------------
+
+    IMF_EXPORT
+    virtual ~DeepTiledOutputFile ();
+
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledOutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writeTile() is
+    // called.  The current frame buffer can be changed
+    // after each call to writeTile().
+    //-------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------
+    // Utility functions:
+    //-------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    unsigned int        tileXSize () const;
+    IMF_EXPORT
+    unsigned int        tileYSize () const;
+    IMF_EXPORT
+    LevelMode           levelMode () const;
+    IMF_EXPORT
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with MIPMAP_LEVELS
+    // files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    //--------------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numLevels () const;
+    IMF_EXPORT
+    int                 numXLevels () const;
+    IMF_EXPORT
+    int                 numYLevels () const;
+    IMF_EXPORT
+    bool                isValidLevel (int lx, int ly) const;
+
+
+    //---------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    int                 levelWidth  (int lx) const;
+    IMF_EXPORT
+    int                 levelHeight (int ly) const;
+
+
+    //----------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //----------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numXTiles (int lx = 0) const;
+    IMF_EXPORT
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a level with
+    // level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                           int l = 0) const;
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                           int lx, int ly) const;
+
+    //------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writeTile(dx, dy, lx, ly) writes the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly) to
+    // the file.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx) - 1]
+    //   dy must lie in the interval [0, numYTiles(ly) - 1]
+    //
+    //   lx must lie in the interval [0, numXLevels() - 1]
+    //   ly must lie in the inverval [0, numYLevels() - 1]
+    //
+    // writeTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVEL files.  It calls
+    // writeTile(dx, dy, level, level).
+    //
+    // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // writing multiple tiles at once.  If multi-threading is used
+    // multiple tiles are written concurrently.  The tile coordinates,
+    // dx1, dx2 and dy1, dy2, specify inclusive ranges of tile
+    // coordinates.  It is valid for dx1 < dx2 or dy1 < dy2; the
+    // tiles are always written in the order specified by the line
+    // order attribute.  Hence, it is not possible to specify an
+    // "invalid" or empty tile range.
+    //
+    // Pixels that are outside the pixel coordinate range for the tile's
+    // level, are never accessed by writeTile().
+    //
+    // Each tile in the file must be written exactly once.
+    //
+    // The file's line order attribute determines the order of the tiles
+    // in the file:
+    //
+    //   INCREASING_Y   In the file, the tiles for each level are stored
+    //                  in a contiguous block.  The levels are ordered
+    //                  like this:
+    //
+    //                      (0, 0)   (1, 0)   ... (nx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (nx-1, 1)
+    //                       ...
+    //                      (0,ny-1) (1,ny-1) ... (nx-1,ny-1)
+    //
+    //                  where nx = numXLevels(), and ny = numYLevels().
+    //                  In an individual level, (lx, ly), the tiles
+    //                  are stored in the following order:
+    //
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                       ...
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //
+    //                  where tx = numXTiles(lx),
+    //                  and   ty = numYTiles(ly).
+    //
+    //   DECREASING_Y   As for INCREASING_Y, the tiles for each level
+    //                  are stored in a contiguous block.  The levels
+    //                  are ordered the same way as for INCREASING_Y,
+    //                  but within an individual level, the tiles
+    //                  are stored in this order:
+    //
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //                       ...
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //
+    //
+    //   RANDOM_Y       The order of the calls to writeTile() determines
+    //                  the order of the tiles in the file.
+    //
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                writeTile  (int dx, int dy, int l = 0);
+    IMF_EXPORT
+    void                writeTile  (int dx, int dy, int lx, int ly);
+
+    IMF_EXPORT
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                    int lx, int ly);
+
+    IMF_EXPORT
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                    int l = 0);
+
+
+    //------------------------------------------------------------------
+    // Shortcut to copy all pixels from a TiledInputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the TiledInputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder", "channels", and "tiles" attributes must be the same.
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                copyPixels (DeepTiledInputFile &in);
+    IMF_EXPORT
+    void                copyPixels (DeepTiledInputPart &in);
+
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few tiles at a time,
+    // while the image is being generated.  Since the preview image
+    // is an attribute in the file's header, it gets stored in the
+    // file as soon as the file is opened, but we may not know what
+    // the preview image should look like until we have written the
+    // last tile of the main image.
+    //
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+
+    //-------------------------------------------------------------
+    // Break a tile -- for testing and debugging only:
+    //
+    // breakTile(dx,dy,lx,ly,p,n,c) introduces an error into the
+    // output file by writing n copies of character c, starting
+    // p bytes from the beginning of the tile with tile coordinates
+    // (dx, dy) and level number (lx, ly).
+    //
+    // Warning: Calling this function usually results in a broken
+    // image file.  The file or parts of it may not be readable,
+    // or the file may contain bad data.
+    //
+    //-------------------------------------------------------------
+
+    IMF_EXPORT
+    void                breakTile  (int dx, int dy,
+                                    int lx, int ly,
+                                    int offset,
+                                    int length,
+                                    char c);
+    struct Data;
+
+  private:
+
+    // ----------------------------------------------------------------
+    // A constructor attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    // ----------------------------------------------------------------
+    DeepTiledOutputFile (const OutputPartData* part);
+
+    DeepTiledOutputFile (const DeepTiledOutputFile &);              // not implemented
+    DeepTiledOutputFile & operator = (const DeepTiledOutputFile &); // not implemented
+
+    void                initialize (const Header &header);
+
+    bool                isValidTile (int dx, int dy,
+                                     int lx, int ly) const;
+
+    size_t              bytesPerLineForTile (int dx, int dy,
+                                             int lx, int ly) const;
+
+    Data *              _data;
+
+
+    friend class MultiPartOutputFile;
+
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledOutputPart.cpp b/3rdparty/openexr/IlmImf/ImfDeepTiledOutputPart.cpp
new file mode 100644 (file)
index 0000000..7239c01
--- /dev/null
@@ -0,0 +1,250 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfDeepTiledOutputPart.h"
+#include "ImfMultiPartOutputFile.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+DeepTiledOutputPart::DeepTiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<DeepTiledOutputFile>(partNumber);
+}
+
+const char *
+DeepTiledOutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+
+const Header &
+DeepTiledOutputPart::header () const
+{
+    return file->header();
+}
+
+
+void
+DeepTiledOutputPart::setFrameBuffer (const DeepFrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+
+const DeepFrameBuffer &
+DeepTiledOutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+
+unsigned int
+DeepTiledOutputPart::tileXSize () const
+{
+    return file->tileXSize();
+}
+
+
+unsigned int
+DeepTiledOutputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+
+LevelMode
+DeepTiledOutputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+
+LevelRoundingMode
+DeepTiledOutputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+
+int
+DeepTiledOutputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+
+int
+DeepTiledOutputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+
+int
+DeepTiledOutputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+
+bool
+DeepTiledOutputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+
+int
+DeepTiledOutputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+
+int
+DeepTiledOutputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+
+int
+DeepTiledOutputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+
+int
+DeepTiledOutputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForTile (int dx, int dy,
+                                        int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+
+IMATH_NAMESPACE::Box2i
+DeepTiledOutputPart::dataWindowForTile (int dx, int dy,
+                                        int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledOutputPart::writeTile  (int dx, int dy, int l)
+{
+    file->writeTile(dx, dy, l);
+}
+
+
+void
+DeepTiledOutputPart::writeTile  (int dx, int dy, int lx, int ly)
+{
+    file->writeTile(dx, dy, lx, ly);
+}
+
+
+void
+DeepTiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int lx, int ly)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+
+void
+DeepTiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                 int l)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, l);
+}
+
+
+void
+DeepTiledOutputPart::copyPixels (DeepTiledInputFile &in)
+{
+    file->copyPixels(in);
+}
+
+
+void
+DeepTiledOutputPart::copyPixels (DeepTiledInputPart &in)
+{
+    file->copyPixels(in);
+}
+
+
+void
+DeepTiledOutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+
+void
+DeepTiledOutputPart::breakTile  (int dx, int dy,
+                                 int lx, int ly,
+                                 int offset,
+                                 int length,
+                                 char c)
+{
+    file->breakTile(dx, dy, lx, ly, offset, length, c);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDeepTiledOutputPart.h b/3rdparty/openexr/IlmImf/ImfDeepTiledOutputPart.h
new file mode 100644 (file)
index 0000000..8b43656
--- /dev/null
@@ -0,0 +1,423 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFDEEPTILEDOUTPUTPART_H_
+#define IMFDEEPTILEDOUTPUTPART_H_
+
+#include "ImfForward.h"
+#include "ImfDeepTiledInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class DeepTiledOutputPart
+{
+  public:
+
+    IMF_EXPORT
+    DeepTiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+    //------------------------
+    // Access to the file name
+    //------------------------
+
+    IMF_EXPORT
+    const char *        fileName () const;
+
+
+    //--------------------------
+    // Access to the file header
+    //--------------------------
+
+    IMF_EXPORT
+    const Header &      header () const;
+
+
+    //-------------------------------------------------------
+    // Set the current frame buffer -- copies the FrameBuffer
+    // object into the TiledOutputFile object.
+    //
+    // The current frame buffer is the source of the pixel
+    // data written to the file.  The current frame buffer
+    // must be set at least once before writeTile() is
+    // called.  The current frame buffer can be changed
+    // after each call to writeTile().
+    //-------------------------------------------------------
+
+    IMF_EXPORT
+    void                setFrameBuffer (const DeepFrameBuffer &frameBuffer);
+
+
+    //-----------------------------------
+    // Access to the current frame buffer
+    //-----------------------------------
+
+    IMF_EXPORT
+    const DeepFrameBuffer & frameBuffer () const;
+
+
+    //-------------------
+    // Utility functions:
+    //-------------------
+
+    //---------------------------------------------------------
+    // Multiresolution mode and tile size:
+    // The following functions return the xSize, ySize and mode
+    // fields of the file header's TileDescriptionAttribute.
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    unsigned int        tileXSize () const;
+    IMF_EXPORT
+    unsigned int        tileYSize () const;
+    IMF_EXPORT
+    LevelMode           levelMode () const;
+    IMF_EXPORT
+    LevelRoundingMode   levelRoundingMode () const;
+
+
+    //--------------------------------------------------------------------
+    // Number of levels:
+    //
+    // numXLevels() returns the file's number of levels in x direction.
+    //
+    //  if levelMode() == ONE_LEVEL:
+    //      return value is: 1
+    //
+    //  if levelMode() == MIPMAP_LEVELS:
+    //      return value is: rfunc (log (max (w, h)) / log (2)) + 1
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (w) / log (2)) + 1
+    //
+    //  where
+    //      w is the width of the image's data window,  max.x - min.x + 1,
+    //      y is the height of the image's data window, max.y - min.y + 1,
+    //      and rfunc(x) is either floor(x), or ceil(x), depending on
+    //      whether levelRoundingMode() returns ROUND_DOWN or ROUND_UP.
+    //
+    // numYLevels() returns the file's number of levels in y direction.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      return value is: rfunc (log (h) / log (2)) + 1
+    //
+    //
+    // numLevels() is a convenience function for use with MIPMAP_LEVELS
+    // files.
+    //
+    //  if levelMode() == ONE_LEVEL or levelMode() == MIPMAP_LEVELS:
+    //      return value is the same as for numXLevels()
+    //
+    //  if levelMode() == RIPMAP_LEVELS:
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
+    //
+    // isValidLevel(lx, ly) returns true if the file contains
+    // a level with level number (lx, ly), false if not.
+    //
+    //--------------------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numLevels () const;
+    IMF_EXPORT
+    int                 numXLevels () const;
+    IMF_EXPORT
+    int                 numYLevels () const;
+    IMF_EXPORT
+    bool                isValidLevel (int lx, int ly) const;
+
+
+    //---------------------------------------------------------
+    // Dimensions of a level:
+    //
+    // levelWidth(lx) returns the width of a level with level
+    // number (lx, *), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (w / pow (2, lx)))
+    //
+    //
+    // levelHeight(ly) returns the height of a level with level
+    // number (*, ly), where * is any number.
+    //
+    //  return value is:
+    //      max (1, rfunc (h / pow (2, ly)))
+    //
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    int                 levelWidth  (int lx) const;
+    IMF_EXPORT
+    int                 levelHeight (int ly) const;
+
+
+    //----------------------------------------------------------
+    // Number of tiles:
+    //
+    // numXTiles(lx) returns the number of tiles in x direction
+    // that cover a level with level number (lx, *), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelWidth(lx) + tileXSize() - 1) / tileXSize()
+    //
+    //
+    // numYTiles(ly) returns the number of tiles in y direction
+    // that cover a level with level number (*, ly), where * is
+    // any number.
+    //
+    //  return value is:
+    //      (levelHeight(ly) + tileXSize() - 1) / tileXSize()
+    //
+    //----------------------------------------------------------
+
+    IMF_EXPORT
+    int                 numXTiles (int lx = 0) const;
+    IMF_EXPORT
+    int                 numYTiles (int ly = 0) const;
+
+
+    //---------------------------------------------------------
+    // Level pixel ranges:
+    //
+    // dataWindowForLevel(lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a level with
+    // level number (lx, ly)
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x, dataWindow.min.y)
+    //
+    //  and max value:
+    //      (dataWindow.min.x + levelWidth(lx) - 1,
+    //       dataWindow.min.y + levelHeight(ly) - 1)
+    //
+    // dataWindowForLevel(level) is a convenience function used
+    // for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForLevel(level, level).
+    //
+    //---------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+
+
+    //-------------------------------------------------------------------
+    // Tile pixel ranges:
+    //
+    // dataWindowForTile(dx, dy, lx, ly) returns a 2-dimensional
+    // region of valid pixel coordinates for a tile with tile coordinates
+    // (dx,dy) and level number (lx, ly).
+    //
+    //  return value is a Box2i with min value:
+    //      (dataWindow.min.x + dx * tileXSize(),
+    //       dataWindow.min.y + dy * tileYSize())
+    //
+    //  and max value:
+    //      (dataWindow.min.x + (dx + 1) * tileXSize() - 1,
+    //       dataWindow.min.y + (dy + 1) * tileYSize() - 1)
+    //
+    // dataWindowForTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVELS files.  It returns
+    // dataWindowForTile(dx, dy, level, level).
+    //
+    //-------------------------------------------------------------------
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                         int l = 0) const;
+
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                         int lx, int ly) const;
+
+    //------------------------------------------------------------------
+    // Write pixel data:
+    //
+    // writeTile(dx, dy, lx, ly) writes the tile with tile
+    // coordinates (dx, dy), and level number (lx, ly) to
+    // the file.
+    //
+    //   dx must lie in the interval [0, numXTiles(lx) - 1]
+    //   dy must lie in the interval [0, numYTiles(ly) - 1]
+    //
+    //   lx must lie in the interval [0, numXLevels() - 1]
+    //   ly must lie in the inverval [0, numYLevels() - 1]
+    //
+    // writeTile(dx, dy, level) is a convenience function
+    // used for ONE_LEVEL and MIPMAP_LEVEL files.  It calls
+    // writeTile(dx, dy, level, level).
+    //
+    // The two writeTiles(dx1, dx2, dy1, dy2, ...) functions allow
+    // writing multiple tiles at once.  If multi-threading is used
+    // multiple tiles are written concurrently.  The tile coordinates,
+    // dx1, dx2 and dy1, dy2, specify inclusive ranges of tile
+    // coordinates.  It is valid for dx1 < dx2 or dy1 < dy2; the
+    // tiles are always written in the order specified by the line
+    // order attribute.  Hence, it is not possible to specify an
+    // "invalid" or empty tile range.
+    //
+    // Pixels that are outside the pixel coordinate range for the tile's
+    // level, are never accessed by writeTile().
+    //
+    // Each tile in the file must be written exactly once.
+    //
+    // The file's line order attribute determines the order of the tiles
+    // in the file:
+    //
+    //   INCREASING_Y   In the file, the tiles for each level are stored
+    //                  in a contiguous block.  The levels are ordered
+    //                  like this:
+    //
+    //                      (0, 0)   (1, 0)   ... (nx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (nx-1, 1)
+    //                       ...
+    //                      (0,ny-1) (1,ny-1) ... (nx-1,ny-1)
+    //
+    //                  where nx = numXLevels(), and ny = numYLevels().
+    //                  In an individual level, (lx, ly), the tiles
+    //                  are stored in the following order:
+    //
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                       ...
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //
+    //                  where tx = numXTiles(lx),
+    //                  and   ty = numYTiles(ly).
+    //
+    //   DECREASING_Y   As for INCREASING_Y, the tiles for each level
+    //                  are stored in a contiguous block.  The levels
+    //                  are ordered the same way as for INCREASING_Y,
+    //                  but within an individual level, the tiles
+    //                  are stored in this order:
+    //
+    //                      (0,ty-1) (1,ty-1) ... (tx-1,ty-1)
+    //                       ...
+    //                      (0, 1)   (1, 1)   ... (tx-1, 1)
+    //                      (0, 0)   (1, 0)   ... (tx-1, 0)
+    //
+    //
+    //   RANDOM_Y       The order of the calls to writeTile() determines
+    //                  the order of the tiles in the file.
+    //
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                writeTile  (int dx, int dy, int l = 0);
+    IMF_EXPORT
+    void                writeTile  (int dx, int dy, int lx, int ly);
+
+    IMF_EXPORT
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                  int lx, int ly);
+
+    IMF_EXPORT
+    void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                  int l = 0);
+
+
+    //------------------------------------------------------------------
+    // Shortcut to copy all pixels from a TiledInputFile into this file,
+    // without uncompressing and then recompressing the pixel data.
+    // This file's header must be compatible with the TiledInputFile's
+    // header:  The two header's "dataWindow", "compression",
+    // "lineOrder", "channels", and "tiles" attributes must be the same.
+    //------------------------------------------------------------------
+
+    IMF_EXPORT
+    void                copyPixels (DeepTiledInputFile &in);
+    IMF_EXPORT
+    void                copyPixels (DeepTiledInputPart &in);
+    
+
+
+
+    //--------------------------------------------------------------
+    // Updating the preview image:
+    //
+    // updatePreviewImage() supplies a new set of pixels for the
+    // preview image attribute in the file's header.  If the header
+    // does not contain a preview image, updatePreviewImage() throws
+    // an IEX_NAMESPACE::LogicExc.
+    //
+    // Note: updatePreviewImage() is necessary because images are
+    // often stored in a file incrementally, a few tiles at a time,
+    // while the image is being generated.  Since the preview image
+    // is an attribute in the file's header, it gets stored in the
+    // file as soon as the file is opened, but we may not know what
+    // the preview image should look like until we have written the
+    // last tile of the main image.
+    //
+    //--------------------------------------------------------------
+
+    IMF_EXPORT
+    void                updatePreviewImage (const PreviewRgba newPixels[]);
+
+
+    //-------------------------------------------------------------
+    // Break a tile -- for testing and debugging only:
+    //
+    // breakTile(dx,dy,lx,ly,p,n,c) introduces an error into the
+    // output file by writing n copies of character c, starting
+    // p bytes from the beginning of the tile with tile coordinates
+    // (dx, dy) and level number (lx, ly).
+    //
+    // Warning: Calling this function usually results in a broken
+    // image file.  The file or parts of it may not be readable,
+    // or the file may contain bad data.
+    //
+    //-------------------------------------------------------------
+
+    IMF_EXPORT
+    void                breakTile  (int dx, int dy,
+                                  int lx, int ly,
+                                  int offset,
+                                  int length,
+                                  char c);
+
+  private:
+    DeepTiledOutputFile* file;
+    
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFDEEPTILEDOUTPUTPART_H_ */
index 706acde..cbeabe3 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,7 +43,7 @@
 #include <ImfDoubleAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 template <>
@@ -54,4 +54,4 @@ DoubleAttribute::staticTypeName ()
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 2208c9b..d9a88a8 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
+#include "ImfExport.h"
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<double> DoubleAttribute;
-template <> const char *DoubleAttribute::staticTypeName ();
+template <> IMF_EXPORT const char *DoubleAttribute::staticTypeName ();
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfDoubleAttribute.cpp>
-#endif
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfDwaCompressor.cpp b/3rdparty/openexr/IlmImf/ImfDwaCompressor.cpp
new file mode 100644 (file)
index 0000000..7665730
--- /dev/null
@@ -0,0 +1,3439 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+//---------------------------------------------------
+//
+// class DwaCompressor -- Store lossy RGB data by quantizing
+//                          DCT components.
+//
+// First, we try and figure out what compression strategy to take
+// based in channel name. For RGB channels, we want a lossy method
+// described below. But, if we have alpha, we should do something
+// different (and probably using RLE). If we have depth, or velocity,
+// or something else, just fall back to ZIP. The rules for deciding 
+// which strategy to use are setup in initializeDefaultChannelRules().
+// When writing a file, the relevant rules needed to decode are written
+// into the start of the data block, making a self-contained file. 
+// If initializeDefaultChannelRules() doesn't quite suite your naming
+// conventions, you can adjust the rules without breaking decoder
+// compatability.
+//
+// If we're going to lossy compress R, G, or B channels, it's easier
+// to toss bits in a more perceptual uniform space. One could argue
+// at length as to what constitutes perceptually uniform, expecially 
+// when storing either scene/input/focal plane referred and output referred
+// data. 
+//
+// We'll compromise. For values <= 1, we use a traditional power function
+// (without any of that straight-line business at the bottom). For values > 1,
+// we want something more like a log function, since power functions blow
+// up. At 1, we want a smooth blend between the functions. So, we use a 
+// piecewise function that does just that - see dwaLookups.cpp for 
+// a little more detail.
+//
+// Also, if we find that we have R, G, and B channels from the same layer,
+// we can get a bit more compression efficiency by transforming to a Y'CbCr
+// space. We use the 709 transform, but with Cb,Cr = 0 for an input of 
+// (0, 0, 0), instead of the traditional Cb,Cr = .5. Shifting the zero point
+// makes no sense with large range data. Transforms are done to from 
+// the perceptual space data, not the linear-light space data (R'G'B' ->
+// (Y'CbCr, not RGB -> YCbCr).
+//
+// Next, we forward DCT the data. This is done with a floating
+// point DCT, as we don't really have control over the src range. The 
+// resulting values are dropped to half-float precision. 
+//
+// Now, we need to quantize. Quantization departs from the usual way 
+// of dividing and rounding. Instead, we start with some floating 
+// point "base-error" value. From this, we can derive quantization 
+// error for each DCT component. Take the standard JPEG quantization
+// tables and normalize them by the smallest value. Then, multiply
+// the normalized quant tables by our base-error value. This gives
+// a range of errors for each DCT component.
+//
+// For each DCT component, we want to find a quantized value that 
+// is within +- the per-component error. Pick the quantized value
+// that has the fewest bits set in its' binary representation. 
+// Brute-forcing the search would make for extremly inefficient 
+// compression. Fortunatly, we can precompute a table to assist 
+// with this search. 
+//
+// For each 16-bit float value, there are at most 15 other values with
+// fewer bits set. We can precompute these values in a compact form, since
+// many source values have far fewer that 15 possible quantized values. 
+// Now, instead of searching the entire range +- the component error,
+// we can just search at most 15 quantization candidates. The search can
+// be accelerated a bit more by sorting the candidates by the 
+// number of bits set, in increasing order. Then, the search can stop
+// once a candidate is found w/i the per-component quantization 
+// error range.
+//
+// The quantization strategy has the side-benefit that there is no
+// de-quantization step upon decode, so we don't bother recording
+// the quantization table.
+//
+// Ok. So we now have quantized values. Time for entropy coding. We
+// can use either static Huffman or zlib/DEFLATE. The static Huffman
+// is more efficient at compacting data, but can have a greater 
+// overhead, especially for smaller tile/strip sizes. 
+//
+// There is some additional fun, like ZIP compressing the DC components
+// instead of Huffman/zlib, which helps make things slightly smaller.
+//
+// Compression level is controlled by setting an int/float/double attribute
+// on the header named "dwaCompressionLevel". This is a thinly veiled name for 
+// the "base-error" value mentioned above. The "base-error" is just
+// dwaCompressionLevel / 100000. The default value of 45.0 is generally 
+// pretty good at generating "visually lossless" values at reasonable
+// data rates. Setting dwaCompressionLevel to 0 should result in no additional
+// quantization at the quantization stage (though there may be 
+// quantization in practice at the CSC/DCT steps). But if you really
+// want lossless compression, there are pleanty of other choices 
+// of compressors ;)
+//
+// When dealing with FLOAT source buffers, we first quantize the source
+// to HALF and continue down as we would for HALF source.
+//
+//---------------------------------------------------
+
+
+#include "ImfDwaCompressor.h"
+#include "ImfDwaCompressorSimd.h"
+
+#include "ImfChannelList.h"
+#include "ImfStandardAttributes.h"
+#include "ImfHeader.h"
+#include "ImfHuf.h"
+#include "ImfInt64.h"
+#include "ImfIntAttribute.h"
+#include "ImfIO.h"
+#include "ImfMisc.h"
+#include "ImfNamespace.h"
+#include "ImfRle.h"
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include "ImfXdr.h"
+#include "ImfZip.h"
+
+#include "ImathFun.h"
+#include "ImathBox.h"
+#include "ImathVec.h"
+#include "half.h"
+#include "halfLimits.h"
+
+#include "dwaLookups.h"
+
+#include <vector>
+#include <string>
+#include <cctype>
+#include <cassert>
+#include <algorithm>
+
+// Windows specific addition to prevent the indirect import of the redefined min/max macros
+#if defined _WIN32 || defined _WIN64
+       #ifdef NOMINMAX
+               #undef NOMINMAX
+       #endif
+       #define NOMINMAX
+#endif
+#include <zlib.h>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+namespace {
+
+    //
+    // Function pointer to dispatch to an approprate 
+    // convertFloatToHalf64_* impl, based on runtime cpu checking.
+    // Should be initialized in DwaCompressor::initializeFuncs()
+    //
+
+    void (*convertFloatToHalf64)(unsigned short*, float*) =
+        convertFloatToHalf64_scalar;
+
+    // 
+    // Function pointer for dispatching a fromHalfZigZag_ impl
+    //
+    
+    void (*fromHalfZigZag)(unsigned short*, float*) =
+        fromHalfZigZag_scalar;
+
+    //
+    // Dispatch the inverse DCT on an 8x8 block, where the last
+    // n rows can be all zeros. The n=0 case converts the full block.
+    //
+    void (*dctInverse8x8_0)(float*) = dctInverse8x8_scalar<0>;
+    void (*dctInverse8x8_1)(float*) = dctInverse8x8_scalar<1>;
+    void (*dctInverse8x8_2)(float*) = dctInverse8x8_scalar<2>;
+    void (*dctInverse8x8_3)(float*) = dctInverse8x8_scalar<3>;
+    void (*dctInverse8x8_4)(float*) = dctInverse8x8_scalar<4>;
+    void (*dctInverse8x8_5)(float*) = dctInverse8x8_scalar<5>;
+    void (*dctInverse8x8_6)(float*) = dctInverse8x8_scalar<6>;
+    void (*dctInverse8x8_7)(float*) = dctInverse8x8_scalar<7>;
+    
+} // namespace
+
+
+struct DwaCompressor::ChannelData
+{
+    std::string         name;
+    CompressorScheme    compression;  
+    int                 xSampling;
+    int                 ySampling;
+    PixelType           type;
+    bool                pLinear;
+
+    int                 width;
+    int                 height;
+
+    //
+    // Incoming and outgoing data is scanline interleaved, and it's much
+    // easier to operate on contiguous data.  Assuming the planare unc
+    // buffer is to hold RLE data, we need to rearrange to make bytes
+    // adjacent.
+    //
+
+    char               *planarUncBuffer;
+    char               *planarUncBufferEnd;
+
+    char               *planarUncRle[4];
+    char               *planarUncRleEnd[4];
+
+    PixelType           planarUncType;
+    int                 planarUncSize;
+};
+
+
+struct DwaCompressor::CscChannelSet
+{
+    int idx[3];
+};
+
+
+struct DwaCompressor::Classifier
+{
+    Classifier (std::string suffix,
+                CompressorScheme scheme,
+                PixelType type,
+                int cscIdx,
+                bool caseInsensitive):
+        _suffix(suffix),
+        _scheme(scheme),
+        _type(type),
+        _cscIdx(cscIdx),
+        _caseInsensitive(caseInsensitive)
+    {
+        if (caseInsensitive) 
+            std::transform(_suffix.begin(), _suffix.end(), _suffix.begin(), tolower);
+    }
+
+    Classifier (const char *&ptr, int size)
+    {
+        if (size <= 0) 
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                " (truncated rule).");
+            
+        {
+            char suffix[Name::SIZE];
+            memset (suffix, 0, Name::SIZE);
+            Xdr::read<CharPtrIO> (ptr, std::min(size, Name::SIZE-1), suffix);
+            _suffix = std::string(suffix);
+        }
+
+        if (size < _suffix.length() + 1 + 2*Xdr::size<char>()) 
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                " (truncated rule).");
+
+        char value;
+        Xdr::read<CharPtrIO> (ptr, value);
+
+        _cscIdx = (int)(value >> 4) - 1;
+        if (_cscIdx < -1 || _cscIdx >= 3) 
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                " (corrupt cscIdx rule).");
+
+        _scheme = (CompressorScheme)((value >> 2) & 3);
+        if (_scheme < 0 || _scheme >= NUM_COMPRESSOR_SCHEMES) 
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                " (corrupt scheme rule).");
+
+        _caseInsensitive = (value & 1 ? true : false);
+
+        Xdr::read<CharPtrIO> (ptr, value);
+        if (value < 0 || value >= NUM_PIXELTYPES) 
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                " (corrupt rule).");
+        _type = (PixelType)value;
+    }
+
+    bool match (const std::string &suffix, const PixelType type) const
+    {
+        if (_type != type) return false;
+
+        if (_caseInsensitive) 
+        {
+            std::string tmp(suffix);
+            std::transform(tmp.begin(), tmp.end(), tmp.begin(), tolower);
+            return tmp == _suffix;
+        }
+
+        return suffix == _suffix;
+    }
+
+    size_t size () const 
+    {
+        // string length + \0
+        size_t sizeBytes = _suffix.length() + 1;
+
+        // 1 byte for scheme / cscIdx / caseInsensitive, and 1 byte for type
+        sizeBytes += 2 * Xdr::size<char>();
+
+        return sizeBytes;
+    }
+
+    void write (char *&ptr) const
+    {
+        Xdr::write<CharPtrIO> (ptr, _suffix.c_str());
+
+        // Encode _cscIdx (-1-3) in the upper 4 bits,
+        //        _scheme (0-2)  in the next 2 bits
+        //        _caseInsen     in the bottom bit
+        unsigned char value = 0;
+        value |= ((unsigned char)(_cscIdx+1)      & 15) << 4;
+        value |= ((unsigned char)_scheme          &  3) << 2;
+        value |=  (unsigned char)_caseInsensitive &  1;
+
+        Xdr::write<CharPtrIO> (ptr, value);
+        Xdr::write<CharPtrIO> (ptr, (unsigned char)_type);
+    }
+
+    std::string      _suffix;
+    CompressorScheme _scheme;
+    PixelType        _type;
+    int              _cscIdx;
+    bool             _caseInsensitive;
+};
+
+
+//
+// Base class for the LOSSY_DCT decoder classes
+//
+
+class DwaCompressor::LossyDctDecoderBase
+{
+  public:
+
+    LossyDctDecoderBase
+        (char *packedAc,
+         char *packedDc,
+         const unsigned short *toLinear,
+         int width,
+         int height);
+
+    virtual ~LossyDctDecoderBase ();
+
+    void execute();
+
+    //
+    // These return number of items, not bytes. Each item
+    // is an unsigned short
+    //
+
+    int numAcValuesEncoded() const { return _packedAcCount; }
+    int numDcValuesEncoded() const { return _packedDcCount; }
+
+  protected:
+
+    //
+    // Un-RLE the packed AC components into 
+    // a half buffer. The half block should 
+    // be the full 8x8 block (in zig-zag order
+    // still), not the first AC component. 
+    //
+    // currAcComp is advanced as bytes are decoded.
+    //
+    // This returns the index of the last non-zero
+    // value in the buffer - with the index into zig zag
+    // order data. If we return 0, we have DC only data.
+    // 
+
+    int unRleAc (unsigned short *&currAcComp,
+                 unsigned short  *halfZigBlock); 
+
+
+    //
+    // if NATIVE and XDR are really the same values, we can
+    // skip some processing and speed things along
+    //
+
+    bool                  _isNativeXdr;
+
+
+    //
+    // Counts of how many items have been packed into the
+    // AC and DC buffers
+    //
+
+    int                   _packedAcCount;
+    int                   _packedDcCount;
+
+
+    //
+    // AC and DC buffers to pack
+    //
+
+    char                 *_packedAc;
+    char                 *_packedDc;
+
+
+    // 
+    // half -> half LUT to transform from nonlinear to linear
+    //
+
+    const unsigned short *_toLinear;
+
+
+    //
+    // image dimensions
+    //
+
+    int                   _width;
+    int                   _height;
+
+
+    //
+    // Pointers to the start of each scanlines, to be filled on decode
+    // Generally, these will be filled by the subclasses.
+    //
+
+    std::vector< std::vector<char *> > _rowPtrs;
+
+
+    // 
+    // The type of each data that _rowPtrs[i] is referring. Layout
+    // is in the same order as _rowPtrs[].
+    //
+
+    std::vector<PixelType>             _type;
+    std::vector<SimdAlignedBuffer64f>  _dctData;
+};
+
+
+//
+// Used to decode a single channel of LOSSY_DCT data.
+//
+
+class DwaCompressor::LossyDctDecoder: public LossyDctDecoderBase
+{
+  public:
+
+    //
+    // toLinear is a half-float LUT to convert the encoded values 
+    // back to linear light. If you want to skip this step, pass
+    // in NULL here.
+    //
+
+    LossyDctDecoder
+        (std::vector<char *> &rowPtrs,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toLinear,
+         int width,
+         int height,
+         PixelType type)
+    :
+        LossyDctDecoderBase(packedAc, packedDc, toLinear, width, height)
+    {
+        _rowPtrs.push_back(rowPtrs);
+        _type.push_back(type);
+    }
+
+    virtual ~LossyDctDecoder () {}
+};
+
+
+//
+// Used to decode 3 channels of LOSSY_DCT data that
+// are grouped together and color space converted.
+//
+
+class DwaCompressor::LossyDctDecoderCsc: public LossyDctDecoderBase
+{
+  public:
+
+    //
+    // toLinear is a half-float LUT to convert the encoded values 
+    // back to linear light. If you want to skip this step, pass
+    // in NULL here.
+    //
+
+    LossyDctDecoderCsc
+        (std::vector<char *> &rowPtrsR,
+         std::vector<char *> &rowPtrsG,
+         std::vector<char *> &rowPtrsB,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toLinear,
+         int width,
+         int height,
+         PixelType typeR,
+         PixelType typeG,
+         PixelType typeB)
+    :
+        LossyDctDecoderBase(packedAc, packedDc, toLinear, width, height)
+    {
+        _rowPtrs.push_back(rowPtrsR);
+        _rowPtrs.push_back(rowPtrsG);
+        _rowPtrs.push_back(rowPtrsB);
+        _type.push_back(typeR);
+        _type.push_back(typeG);
+        _type.push_back(typeB);
+    }
+
+    virtual ~LossyDctDecoderCsc () {}
+};
+
+
+// 
+// Base class for encoding using the lossy DCT scheme
+//
+
+class DwaCompressor::LossyDctEncoderBase
+{
+  public:
+
+    LossyDctEncoderBase
+        (float quantBaseError,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toNonlinear,
+         int width,
+         int height);
+
+    virtual ~LossyDctEncoderBase ();
+
+    void execute ();
+
+    //
+    // These return number of items, not bytes. Each item
+    // is an unsigned short
+    //
+
+    int     numAcValuesEncoded () const {return _numAcComp;}
+    int     numDcValuesEncoded () const {return _numDcComp;}
+
+  protected:
+
+    void    toZigZag (half *dst, half *src);
+    int     countSetBits (unsigned short src);
+    half    quantize (half src, float errorTolerance);
+    void    rleAc (half *block, unsigned short *&acPtr);
+
+    float                      _quantBaseError;
+
+    int                        _width,
+                               _height;
+    const unsigned short      *_toNonlinear;
+
+    int                        _numAcComp,
+                               _numDcComp;
+
+    std::vector< std::vector<const char *> > _rowPtrs;
+    std::vector<PixelType>                   _type;
+    std::vector<SimdAlignedBuffer64f>        _dctData;
+
+
+    //
+    // Pointers to the buffers where AC and DC
+    // DCT components should be packed for 
+    // lossless compression downstream
+    //
+
+    char                      *_packedAc;
+    char                      *_packedDc;
+
+
+    //
+    // Our "quantization tables" - the example JPEG tables, 
+    // normalized so that the smallest value in each is 1.0.
+    // This gives us a relationship between error in DCT 
+    // components
+    //
+
+    float                      _quantTableY[64];
+    float                      _quantTableCbCr[64];
+};
+
+
+
+//
+// Single channel lossy DCT encoder
+//
+
+class DwaCompressor::LossyDctEncoder: public LossyDctEncoderBase
+{
+  public:
+
+    LossyDctEncoder
+        (float quantBaseError,
+         std::vector<const char *> &rowPtrs,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toNonlinear,
+         int width,
+         int height,
+         PixelType type)
+    :
+        LossyDctEncoderBase
+            (quantBaseError, packedAc, packedDc, toNonlinear, width, height)
+    {
+        _rowPtrs.push_back(rowPtrs);
+        _type.push_back(type);
+    }
+
+    virtual ~LossyDctEncoder () {}
+};
+    
+
+//
+// RGB channel lossy DCT encoder
+//
+
+class DwaCompressor::LossyDctEncoderCsc: public LossyDctEncoderBase
+{
+  public:
+
+    LossyDctEncoderCsc
+        (float quantBaseError,
+         std::vector<const char *> &rowPtrsR,
+         std::vector<const char *> &rowPtrsG,
+         std::vector<const char *> &rowPtrsB,
+         char *packedAc,
+         char *packedDc,
+         const unsigned short *toNonlinear,
+         int width,
+         int height,
+         PixelType typeR,
+         PixelType typeG,
+         PixelType typeB)
+    :
+        LossyDctEncoderBase
+            (quantBaseError, packedAc, packedDc, toNonlinear, width, height)
+    {
+        _type.push_back(typeR);
+        _type.push_back(typeG);
+        _type.push_back(typeB);
+
+        _rowPtrs.push_back(rowPtrsR);
+        _rowPtrs.push_back(rowPtrsG);
+        _rowPtrs.push_back(rowPtrsB);
+    }
+
+    virtual ~LossyDctEncoderCsc () {}
+};
+
+
+// ==============================================================
+//
+//                     LossyDctDecoderBase
+//
+// --------------------------------------------------------------
+
+DwaCompressor::LossyDctDecoderBase::LossyDctDecoderBase
+    (char *packedAc,
+     char *packedDc,
+     const unsigned short *toLinear,
+     int width,
+     int height)
+:
+    _isNativeXdr(false),
+    _packedAcCount(0),
+    _packedDcCount(0),
+    _packedAc(packedAc),
+    _packedDc(packedDc),
+    _toLinear(toLinear),
+    _width(width),
+    _height(height)
+{
+    if (_toLinear == 0)
+        _toLinear = get_dwaCompressorNoOp();
+
+    _isNativeXdr = GLOBAL_SYSTEM_LITTLE_ENDIAN;
+}
+
+
+DwaCompressor::LossyDctDecoderBase::~LossyDctDecoderBase () {}
+
+
+void
+DwaCompressor::LossyDctDecoderBase::execute ()
+{
+    int numComp        = _rowPtrs.size();
+    int lastNonZero    = 0;
+    int numBlocksX     = (int) ceil ((float)_width  / 8.0f);
+    int numBlocksY     = (int) ceil ((float)_height / 8.0f);
+    int leftoverX      = _width  - (numBlocksX-1) * 8;
+    int leftoverY      = _height - (numBlocksY-1) * 8;
+
+    int numFullBlocksX = (int)floor ((float)_width / 8.0f);
+
+    unsigned short tmpShortNative = 0;
+    unsigned short tmpShortXdr    = 0;
+    const char *tmpConstCharPtr   = 0;
+
+    unsigned short                    *currAcComp = (unsigned short *)_packedAc;
+    std::vector<unsigned short *>      currDcComp (_rowPtrs.size());
+    std::vector<SimdAlignedBuffer64us> halfZigBlock (_rowPtrs.size());
+
+    if (_type.size() != _rowPtrs.size())
+        throw IEX_NAMESPACE::BaseExc ("Row pointers and types mismatch in count");
+
+    if ((_rowPtrs.size() != 3) && (_rowPtrs.size() != 1))
+        throw IEX_NAMESPACE::NoImplExc ("Only 1 and 3 channel encoding is supported");
+
+    _dctData.resize(numComp);
+
+    //
+    // Allocate a temp aligned buffer to hold a rows worth of full 
+    // 8x8 half-float blocks
+    //
+
+    unsigned char *rowBlockHandle = new unsigned char
+        [numComp * numBlocksX * 64 * sizeof(unsigned short) + _SSE_ALIGNMENT];
+
+    unsigned short *rowBlock[3];
+
+    rowBlock[0] = (unsigned short*)rowBlockHandle;
+
+    for (int i = 0; i < _SSE_ALIGNMENT; ++i)
+    {
+        if (((size_t)(rowBlockHandle + i) & _SSE_ALIGNMENT_MASK) == 0)
+            rowBlock[0] = (unsigned short *)(rowBlockHandle + i);
+    }
+
+    for (int comp = 1; comp < numComp; ++comp)
+        rowBlock[comp] = rowBlock[comp - 1] + numBlocksX * 64;
+    //
+    // Pack DC components together by common plane, so we can get 
+    // a little more out of differencing them. We'll always have 
+    // one component per block, so we can computed offsets.
+    //
+
+    currDcComp[0] = (unsigned short *)_packedDc;
+
+    for (unsigned int comp = 1; comp < numComp; ++comp)
+        currDcComp[comp] = currDcComp[comp - 1] + numBlocksX * numBlocksY;
+
+    for (int blocky = 0; blocky < numBlocksY; ++blocky)
+    {
+        int maxY = 8;
+
+        if (blocky == numBlocksY-1)
+            maxY = leftoverY;
+
+        int maxX = 8;
+
+        for (int blockx = 0; blockx < numBlocksX; ++blockx)
+        {
+            if (blockx == numBlocksX-1)
+                maxX = leftoverX;
+
+            //
+            // If we can detect that the block is constant values
+            // (all components only have DC values, and all AC is 0),
+            // we can do everything only on 1 value, instead of all
+            // 64. 
+            //
+            // This won't really help for regular images, but it is
+            // meant more for layers with large swaths of black 
+            //
+
+            bool blockIsConstant = true;
+
+            for (unsigned int comp = 0; comp < numComp; ++comp)
+            {
+
+                //
+                // DC component is stored separately
+                //
+
+                #ifdef IMF_HAVE_SSE2
+                    {
+                        __m128i *dst = (__m128i*)halfZigBlock[comp]._buffer;
+
+                        dst[7] = _mm_setzero_si128();
+                        dst[6] = _mm_setzero_si128();
+                        dst[5] = _mm_setzero_si128();
+                        dst[4] = _mm_setzero_si128();
+                        dst[3] = _mm_setzero_si128();
+                        dst[2] = _mm_setzero_si128();
+                        dst[1] = _mm_setzero_si128();
+                        dst[0] = _mm_insert_epi16
+                            (_mm_setzero_si128(), *currDcComp[comp]++, 0);
+                    }
+                #else  /* IMF_HAVE_SSE2 */
+
+                    memset (halfZigBlock[comp]._buffer, 0, 64 * 2);
+                    halfZigBlock[comp]._buffer[0] = *currDcComp[comp]++;
+
+                #endif /* IMF_HAVE_SSE2 */
+
+                _packedDcCount++;
+                
+                //
+                // UnRLE the AC. This will modify currAcComp
+                //
+
+                lastNonZero = unRleAc (currAcComp, halfZigBlock[comp]._buffer);
+
+                //
+                // Convert from XDR to NATIVE
+                //
+
+                if (!_isNativeXdr)
+                {
+                    for (int i = 0; i < 64; ++i)
+                    {
+                        tmpShortXdr      = halfZigBlock[comp]._buffer[i];
+                        tmpConstCharPtr  = (const char *)&tmpShortXdr;
+
+                        Xdr::read<CharPtrIO> (tmpConstCharPtr, tmpShortNative);
+
+                        halfZigBlock[comp]._buffer[i] = tmpShortNative;
+                    }
+                }
+
+                if (lastNonZero == 0)
+                {
+                    //
+                    // DC only case - AC components are all 0   
+                    //
+
+                    half h;
+
+                    h.setBits (halfZigBlock[comp]._buffer[0]);
+                    _dctData[comp]._buffer[0] = (float)h;
+
+                    dctInverse8x8DcOnly (_dctData[comp]._buffer);
+                }
+                else
+                {
+                    //
+                    // We have some AC components that are non-zero. 
+                    // Can't use the 'constant block' optimization
+                    //
+
+                    blockIsConstant = false;
+
+                    //
+                    // Un-Zig zag 
+                    //
+
+                    (*fromHalfZigZag)
+                        (halfZigBlock[comp]._buffer, _dctData[comp]._buffer);
+
+                    //
+                    // Zig-Zag indices in normal layout are as follows:
+                    //
+                    // 0   1   5   6   14  15  27  28
+                    // 2   4   7   13  16  26  29  42
+                    // 3   8   12  17  25  30  41  43
+                    // 9   11  18  24  31  40  44  53
+                    // 10  19  23  32  39  45  52  54
+                    // 20  22  33  38  46  51  55  60
+                    // 21  34  37  47  50  56  59  61
+                    // 35  36  48  49  57  58  62  63
+                    //
+                    // If lastNonZero is less than the first item on
+                    // each row, we know that the whole row is zero and 
+                    // can be skipped in the row-oriented part of the
+                    // iDCT. 
+                    //
+                    // The unrolled logic here is:
+                    //
+                    //    if lastNonZero < rowStartIdx[i],
+                    //    zeroedRows = rowsEmpty[i]
+                    //
+                    // where:
+                    //
+                    //    const int rowStartIdx[] = {2, 3, 9, 10, 20, 21, 35};
+                    //    const int rowsEmpty[]   = {7, 6, 5,  4,  3,  2,  1};
+                    //
+
+                    if (lastNonZero < 2)
+                        dctInverse8x8_7(_dctData[comp]._buffer);
+                    else if (lastNonZero < 3)
+                        dctInverse8x8_6(_dctData[comp]._buffer);
+                    else if (lastNonZero < 9)
+                        dctInverse8x8_5(_dctData[comp]._buffer);
+                    else if (lastNonZero < 10)
+                        dctInverse8x8_4(_dctData[comp]._buffer);
+                    else if (lastNonZero < 20)
+                        dctInverse8x8_3(_dctData[comp]._buffer);
+                    else if (lastNonZero < 21)
+                        dctInverse8x8_2(_dctData[comp]._buffer);
+                    else if (lastNonZero < 35)
+                        dctInverse8x8_1(_dctData[comp]._buffer);
+                    else
+                        dctInverse8x8_0(_dctData[comp]._buffer);
+                }
+            }
+
+            //
+            // Perform the CSC
+            //
+
+            if (numComp == 3)
+            {
+                if (!blockIsConstant)
+                {
+                    csc709Inverse64 (_dctData[0]._buffer, 
+                                     _dctData[1]._buffer, 
+                                     _dctData[2]._buffer);
+
+                }
+                else
+                {
+                    csc709Inverse (_dctData[0]._buffer[0], 
+                                   _dctData[1]._buffer[0], 
+                                   _dctData[2]._buffer[0]);
+                }
+            }
+
+            //
+            // Float -> Half conversion. 
+            //
+            // If the block has a constant value, just convert the first pixel.
+            //
+
+            for (unsigned int comp = 0; comp < numComp; ++comp)
+            {
+                if (!blockIsConstant)
+                {
+                    (*convertFloatToHalf64)
+                        (&rowBlock[comp][blockx*64], _dctData[comp]._buffer);
+                }
+                else
+                {
+                    #ifdef IMF_HAVE_SSE2
+
+                        __m128i *dst = (__m128i*)&rowBlock[comp][blockx*64];
+
+                        dst[0] = _mm_set1_epi16
+                            (((half)_dctData[comp]._buffer[0]).bits());
+
+                        dst[1] = dst[0];
+                        dst[2] = dst[0];
+                        dst[3] = dst[0];
+                        dst[4] = dst[0];
+                        dst[5] = dst[0];
+                        dst[6] = dst[0];
+                        dst[7] = dst[0];
+
+                    #else  /* IMF_HAVE_SSE2 */
+
+                        unsigned short *dst = &rowBlock[comp][blockx*64];
+
+                        dst[0] = ((half)_dctData[comp]._buffer[0]).bits();
+
+                        for (int i = 1; i < 64; ++i)
+                        {
+                            dst[i] = dst[0];
+                        }
+
+                    #endif /* IMF_HAVE_SSE2 */
+                } // blockIsConstant
+            } // comp
+        } // blockx
+
+        //
+        // At this point, we have half-float nonlinear value blocked
+        // in rowBlock[][]. We need to unblock the data, transfer
+        // back to linear, and write the results in the _rowPtrs[].
+        //
+        // There is a fast-path for aligned rows, which helps
+        // things a little. Since this fast path is only valid
+        // for full 8-element wide blocks, the partial x blocks
+        // are broken into a separate loop below.
+        //
+        // At the moment, the fast path requires:
+        //   * sse support
+        //   * aligned row pointers
+        //   * full 8-element wide blocks
+        //
+
+        for (int comp = 0; comp < numComp; ++comp)
+        {
+            //
+            // Test if we can use the fast path
+            //
+
+        #ifdef IMF_HAVE_SSE2
+
+            bool fastPath = true;
+
+            for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
+            {
+                if ((size_t)_rowPtrs[comp][y] & _SSE_ALIGNMENT_MASK)
+                    fastPath = false;
+            }
+
+            if (fastPath)
+            {
+                //
+                // Handle all the full X blocks, in a fast path with sse2 and
+                // aligned row pointers
+                //
+
+                for (int y=8*blocky; y<8*blocky+maxY; ++y)
+                {
+                    __m128i *dst = (__m128i *)_rowPtrs[comp][y];
+                    __m128i *src = (__m128i *)&rowBlock[comp][(y & 0x7) * 8];
+
+
+                    for (int blockx = 0; blockx < numFullBlocksX; ++blockx)
+                    {
+                        //
+                        // These may need some twiddling.
+                        // Run with multiples of 8
+                        //
+
+                        _mm_prefetch ((char *)(src + 16), _MM_HINT_NTA); 
+
+                        unsigned short i0  = _mm_extract_epi16 (*src, 0);
+                        unsigned short i1  = _mm_extract_epi16 (*src, 1);
+                        unsigned short i2  = _mm_extract_epi16 (*src, 2);
+                        unsigned short i3  = _mm_extract_epi16 (*src, 3);
+
+                        unsigned short i4  = _mm_extract_epi16 (*src, 4);
+                        unsigned short i5  = _mm_extract_epi16 (*src, 5);
+                        unsigned short i6  = _mm_extract_epi16 (*src, 6);
+                        unsigned short i7  = _mm_extract_epi16 (*src, 7);
+
+                        i0 = _toLinear[i0];
+                        i1 = _toLinear[i1];
+                        i2 = _toLinear[i2];
+                        i3 = _toLinear[i3];
+
+                        i4 = _toLinear[i4];
+                        i5 = _toLinear[i5];
+                        i6 = _toLinear[i6];
+                        i7 = _toLinear[i7];
+
+                        *dst = _mm_insert_epi16 (_mm_setzero_si128(), i0, 0);
+                        *dst = _mm_insert_epi16 (*dst, i1, 1);
+                        *dst = _mm_insert_epi16 (*dst, i2, 2);
+                        *dst = _mm_insert_epi16 (*dst, i3, 3);
+
+                        *dst = _mm_insert_epi16 (*dst, i4, 4);
+                        *dst = _mm_insert_epi16 (*dst, i5, 5);
+                        *dst = _mm_insert_epi16 (*dst, i6, 6);
+                        *dst = _mm_insert_epi16 (*dst, i7, 7);
+
+                        src += 8;
+                        dst++;
+                    }
+                }
+            }
+            else
+            {
+
+        #endif /* IMF_HAVE_SSE2 */
+
+                //
+                // Basic scalar kinda slow path for handling the full X blocks
+                //
+
+                for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
+                {
+                    unsigned short *dst = (unsigned short *)_rowPtrs[comp][y];
+
+                    for (int blockx = 0; blockx < numFullBlocksX; ++blockx)
+                    {
+                        unsigned short *src =
+                            &rowBlock[comp][blockx * 64 + ((y & 0x7) * 8)];
+
+                        dst[0] = _toLinear[src[0]];
+                        dst[1] = _toLinear[src[1]];
+                        dst[2] = _toLinear[src[2]];
+                        dst[3] = _toLinear[src[3]];
+
+                        dst[4] = _toLinear[src[4]];
+                        dst[5] = _toLinear[src[5]];
+                        dst[6] = _toLinear[src[6]];
+                        dst[7] = _toLinear[src[7]];
+
+                        dst += 8;
+                    }
+                }
+
+        #ifdef IMF_HAVE_SSE2
+
+            }
+
+        #endif /* IMF_HAVE_SSE2 */
+
+            //
+            // If we have partial X blocks, deal with all those now
+            // Since this should be minimal work, there currently
+            // is only one path that should work for everyone.
+            //
+
+            if (numFullBlocksX != numBlocksX)
+            {
+                for (int y = 8 * blocky; y < 8 * blocky + maxY; ++y)
+                {
+                    unsigned short *src = (unsigned short *)
+                        &rowBlock[comp][numFullBlocksX * 64 + ((y & 0x7) * 8)];
+
+                    unsigned short *dst = (unsigned short *)_rowPtrs[comp][y];
+
+                    dst += 8 * numFullBlocksX;
+
+                    for (int x = 0; x < maxX; ++x)
+                    {
+                        *dst++ = _toLinear[*src++];
+                    }
+                }
+            }
+        } // comp
+    } // blocky
+
+    //
+    // Walk over all the channels that are of type FLOAT.
+    // Convert from HALF XDR back to FLOAT XDR.
+    //
+
+    for (unsigned int chan = 0; chan < numComp; ++chan)
+    {
+
+        if (_type[chan] != FLOAT)
+            continue;
+
+        std::vector<unsigned short> halfXdr (_width);
+
+        for (int y=0; y<_height; ++y)
+        {
+            char *floatXdrPtr = _rowPtrs[chan][y];
+
+            memcpy(&halfXdr[0], floatXdrPtr, _width*sizeof(unsigned short));
+
+            const char *halfXdrPtr = (const char *)(&halfXdr[0]);
+
+            for (int x=0; x<_width; ++x)
+            {
+                half tmpHalf;
+
+                Xdr::read<CharPtrIO> (halfXdrPtr, tmpHalf);
+                Xdr::write<CharPtrIO> (floatXdrPtr, (float)tmpHalf);
+
+                // 
+                // Xdr::write and Xdr::read will advance the ptrs
+                //
+            }
+        }
+    }
+
+    delete[] rowBlockHandle;
+}
+
+
+//
+// Un-RLE the packed AC components into 
+// a half buffer. The half block should 
+// be the full 8x8 block (in zig-zag order
+// still), not the first AC component. 
+//
+// currAcComp is advanced as bytes are decoded.
+//
+// This returns the index of the last non-zero
+// value in the buffer - with the index into zig zag
+// order data. If we return 0, we have DC only data.
+// 
+// This is assuminging that halfZigBlock is zero'ed
+// prior to calling
+//
+
+int 
+DwaCompressor::LossyDctDecoderBase::unRleAc
+    (unsigned short *&currAcComp,
+     unsigned short  *halfZigBlock) 
+{
+    //
+    // Un-RLE the RLE'd blocks. If we find an item whose
+    // high byte is 0xff, then insert the number of 0's
+    // as indicated by the low byte.
+    //
+    // Otherwise, just copy the number verbaitm.
+    //
+
+    int lastNonZero          = 0;
+    int dctComp              = 1; 
+
+    //
+    // Start with a zero'ed block, so we don't have to
+    // write when we hit a run symbol
+    //
+
+    while (dctComp < 64)
+    {
+        if (*currAcComp == 0xff00)
+        {
+            // 
+            // End of block
+            //
+
+            dctComp = 64;
+
+        }
+        else if ((*currAcComp) >> 8 == 0xff)
+        {
+            //
+            // Run detected! Insert 0's.
+            //
+            // Since the block has been zeroed, just advance the ptr
+            // 
+
+            dctComp += (*currAcComp) & 0xff; 
+        }
+        else
+        {
+            // 
+            // Not a run, just copy over the value
+            //
+
+            lastNonZero = dctComp;
+            halfZigBlock[dctComp] = *currAcComp;
+
+            dctComp++;
+        }
+
+        _packedAcCount++;
+        currAcComp++;
+    }
+
+    return lastNonZero;
+}
+
+
+// ==============================================================
+//
+//                     LossyDctEncoderBase
+//
+// --------------------------------------------------------------
+
+DwaCompressor::LossyDctEncoderBase::LossyDctEncoderBase
+    (float quantBaseError,
+     char *packedAc,
+     char *packedDc,
+     const unsigned short *toNonlinear,
+     int width,
+     int height)
+:
+    _quantBaseError(quantBaseError),
+    _width(width),
+    _height(height),
+    _toNonlinear(toNonlinear),
+    _numAcComp(0),
+    _numDcComp(0),
+    _packedAc(packedAc),
+    _packedDc(packedDc)
+{
+    //
+    // Here, we take the generic JPEG quantization tables and
+    // normalize them by the smallest component in each table.
+    // This gives us a relationship amongst the DCT components,
+    // in terms of how sensitive each component is to
+    // error.
+    //
+    // A higher normalized value means we can quantize more,
+    // and a small normalized value means we can quantize less.
+    //
+    // Eventually, we will want an acceptable quantization
+    // error range for each component. We find this by
+    // multiplying some user-specified level (_quantBaseError)
+    // by the normalized table (_quantTableY, _quantTableCbCr) to
+    // find the acceptable quantization error range.
+    //
+    // The quantization table is not needed for decoding, and
+    // is not transmitted. So, if you want to get really fancy,
+    // you could derive some content-dependent quantization
+    // table, and the decoder would not need to be changed. But,
+    // for now, we'll just use statice quantization tables.
+    //
+
+    int jpegQuantTableY[] =
+    {
+        16,  11,  10,  16,   24,   40,   51,   61,
+        12,  12,  14,  19,   26,   58,   60,   55,
+        14,  13,  16,  24,   40,   57,   69,   56,
+        14,  17,  22,  29,   51,   87,   80,   62,
+        18,  22,  37,  56,   68,  109,  103,   77,
+        24,  35,  55,  64,   81,  104,  113,   92,
+        49,  64,  78,  87,  103,  121,  120,  101,
+        72,  92,  95,  98,  112,  100,  103,   99
+    };
+
+    int jpegQuantTableYMin = 10;
+
+    int jpegQuantTableCbCr[] =
+    {
+        17,  18,  24,  47,  99,  99,  99,  99,
+        18,  21,  26,  66,  99,  99,  99,  99,
+        24,  26,  56,  99,  99,  99,  99,  99,
+        47,  66,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99,
+        99,  99,  99,  99,  99,  99,  99,  99
+    };
+
+    int jpegQuantTableCbCrMin = 17;
+
+    for (int idx = 0; idx < 64; ++idx)
+    {
+        _quantTableY[idx] = static_cast<float> (jpegQuantTableY[idx]) /
+                            static_cast<float> (jpegQuantTableYMin);
+
+        _quantTableCbCr[idx] = static_cast<float> (jpegQuantTableCbCr[idx]) /
+                               static_cast<float> (jpegQuantTableCbCrMin);
+    }
+    
+    if (_quantBaseError < 0)
+        quantBaseError = 0;
+}
+
+
+DwaCompressor::LossyDctEncoderBase::~LossyDctEncoderBase () 
+{
+}
+
+
+//
+// Given three channels of source data, encoding by first applying
+// a color space conversion to a YCbCr space.  Otherwise, if we only
+// have one channel, just encode it as is. 
+//
+// Other numbers of channels are somewhat unexpected at this point,
+// and will throw an exception.
+//
+
+void
+DwaCompressor::LossyDctEncoderBase::execute ()
+{
+    int  numBlocksX   = (int)ceil ((float)_width / 8.0f);
+    int  numBlocksY   = (int)ceil ((float)_height/ 8.0f);
+
+    half halfZigCoef[64]; 
+    half halfCoef[64];
+
+    std::vector<unsigned short *> currDcComp (_rowPtrs.size());
+    unsigned short               *currAcComp = (unsigned short *)_packedAc;
+
+    _dctData.resize (_rowPtrs.size());
+    _numAcComp = 0;
+    _numDcComp = 0;
+    assert (_type.size() == _rowPtrs.size());
+    assert ((_rowPtrs.size() == 3) || (_rowPtrs.size() == 1));
+
+    // 
+    // Allocate a temp half buffer to quantize into for
+    // any FLOAT source channels.
+    //
+
+    int tmpHalfBufferElements = 0;
+
+    for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+        if (_type[chan] == FLOAT)
+            tmpHalfBufferElements += _width * _height;
+
+    std::vector<unsigned short> tmpHalfBuffer (tmpHalfBufferElements);
+
+    char *tmpHalfBufferPtr = 0;
+
+    if (tmpHalfBufferElements)
+        tmpHalfBufferPtr = (char *)&tmpHalfBuffer[0];
+
+    //
+    // Run over all the float scanlines, quantizing, 
+    // and re-assigning _rowPtr[y]. We need to translate
+    // FLOAT XDR to HALF XDR.
+    //
+
+    for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+    {
+        if (_type[chan] != FLOAT)
+            continue;
+    
+        for (int y = 0; y < _height; ++y)
+        {
+            float       src = 0;
+            const char *srcXdr = _rowPtrs[chan][y];
+            char       *dstXdr = tmpHalfBufferPtr;
+           
+            for (int x = 0; x < _width; ++x)
+            {
+
+                Xdr::read<CharPtrIO> (srcXdr, src);
+
+                //
+                // Clamp to half ranges, instead of just casting. This
+                // avoids introducing Infs which end up getting zeroed later
+                //
+                src = std::max (
+                    std::min ((float) std::numeric_limits<half>::max(), src),
+                              (float)-std::numeric_limits<half>::max());
+
+                Xdr::write<CharPtrIO> (dstXdr, ((half)src).bits());
+
+                //
+                // Xdr::read and Xdr::write will advance the ptr
+                //
+            }
+
+            _rowPtrs[chan][y] = (const char *)tmpHalfBufferPtr;
+            tmpHalfBufferPtr += _width * sizeof (unsigned short);
+        }
+    }
+
+    //
+    // Pack DC components together by common plane, so we can get 
+    // a little more out of differencing them. We'll always have 
+    // one component per block, so we can computed offsets.
+    //
+
+    currDcComp[0] = (unsigned short *)_packedDc;
+
+    for (unsigned int chan = 1; chan < _rowPtrs.size(); ++chan)
+        currDcComp[chan] = currDcComp[chan-1] + numBlocksX * numBlocksY;
+
+    for (int blocky = 0; blocky < numBlocksY; ++blocky)
+    {
+        for (int blockx = 0; blockx < numBlocksX; ++blockx)
+        {
+            half           h;
+            unsigned short tmpShortXdr, tmpShortNative;
+            char          *tmpCharPtr;
+
+            for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+            {
+                //
+                // Break the source into 8x8 blocks. If we don't
+                // fit at the edges, mirror.
+                //
+                // Also, convert from linear to nonlinear representation.
+                // Our source is assumed to be XDR, and we need to convert
+                // to NATIVE prior to converting to float.
+                //
+                // If we're converting linear -> nonlinear, assume that the
+                // XDR -> NATIVE conversion is built into the lookup. Otherwise,
+                // we'll need to explicitly do it.
+                //
+
+                for (int y = 0; y < 8; ++y)
+                {
+                    for (int x = 0; x < 8; ++x)
+                    {
+                        int vx = 8 * blockx + x;
+                        int vy = 8 * blocky + y;
+
+                        if (vx >= _width)
+                            vx = _width - (vx - (_width - 1));
+                        
+                        if (vx < 0) vx = _width-1;
+
+                        if (vy >=_height)
+                            vy = _height - (vy - (_height - 1));
+
+                        if (vy < 0) vy = _height-1;
+                    
+                        tmpShortXdr =
+                            ((const unsigned short *)(_rowPtrs[chan])[vy])[vx];
+
+                        if (_toNonlinear)
+                        {
+                            h.setBits (_toNonlinear[tmpShortXdr]);
+                        }
+                        else
+                        {
+                            const char *tmpConstCharPtr =
+                                (const char *)(&tmpShortXdr);
+
+                            Xdr::read<CharPtrIO>
+                                (tmpConstCharPtr, tmpShortNative);
+
+                            h.setBits(tmpShortNative);
+                        }
+
+                        _dctData[chan]._buffer[y * 8 + x] = (float)h;
+                    } // x
+                } // y
+            } // chan
+
+            //
+            // Color space conversion
+            //
+
+            if (_rowPtrs.size() == 3)
+            {
+                csc709Forward64 (_dctData[0]._buffer, 
+                                 _dctData[1]._buffer, 
+                                 _dctData[2]._buffer);
+            }
+
+            for (unsigned int chan = 0; chan < _rowPtrs.size(); ++chan)
+            {
+                //
+                // Forward DCT
+                //
+
+                dctForward8x8(_dctData[chan]._buffer);
+
+                //
+                // Quantize to half, and zigzag
+                //
+
+                if (chan == 0)
+                {
+                    for (int i = 0; i < 64; ++i)
+                    {
+                        halfCoef[i] =
+                            quantize ((half)_dctData[chan]._buffer[i],
+                                      _quantBaseError*_quantTableY[i]);
+                    }
+                }
+                else
+                {
+                    for (int i = 0; i < 64; ++i)
+                    {
+                        halfCoef[i] =
+                            quantize ((half)_dctData[chan]._buffer[i],
+                                      _quantBaseError*_quantTableCbCr[i]);
+                    }
+                }
+
+                toZigZag (halfZigCoef, halfCoef);
+                
+                //
+                // Convert from NATIVE back to XDR, before we write out
+                //
+
+                for (int i = 0; i < 64; ++i)
+                {
+                    tmpCharPtr = (char *)&tmpShortXdr;
+                    Xdr::write<CharPtrIO>(tmpCharPtr, halfZigCoef[i].bits());
+                    halfZigCoef[i].setBits(tmpShortXdr);
+                }
+
+                //
+                // Save the DC component separately, to be compressed on
+                // its own.
+                //
+
+                *currDcComp[chan]++ = halfZigCoef[0].bits();
+                _numDcComp++;
+                
+                //
+                // Then RLE the AC components (which will record the count
+                // of the resulting number of items)
+                //
+
+                rleAc (halfZigCoef, currAcComp);
+            } // chan
+        } // blockx
+    } // blocky              
+}
+
+
+// 
+// Reorder from zig-zag order to normal ordering
+//
+
+void 
+DwaCompressor::LossyDctEncoderBase::toZigZag (half *dst, half *src) 
+{
+    const int remap[] =
+    {
+         0, 
+         1,  8,
+        16,  9,  2,
+         3, 10, 17, 24,
+        32, 25, 18, 11, 4,
+         5, 12, 19, 26, 33, 40,
+        48, 41, 34, 27, 20, 13, 6,
+         7, 14, 21, 28, 35, 42, 49, 56,
+            57, 50, 43, 36, 29, 22, 15,
+                23, 30, 37, 44, 51, 58,
+                    59, 52, 45, 38, 31,
+                        39, 46, 53, 60,
+                            61, 54, 47,
+                                55, 62,
+                                    63
+    };
+
+    for (int i=0; i<64; ++i)
+        dst[i] = src[remap[i]];
+}
+
+
+//
+// Precomputing the bit count runs faster than using
+// the builtin instruction, at least in one case..
+//
+// Precomputing 8-bits is no slower than 16-bits,
+// and saves a fair bit of overhead..
+//
+
+int
+DwaCompressor::LossyDctEncoderBase::countSetBits (unsigned short src)
+{
+    static const unsigned short numBitsSet[256] =
+    {
+        0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+        4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+    };
+
+    return numBitsSet[src & 0xff] + numBitsSet[src >> 8];
+}
+
+
+//
+// Take a DCT coefficient, as well as an acceptable error. Search
+// nearby values within the error tolerance, that have fewer 
+// bits set.
+//
+// The list of candidates has been pre-computed and sorted 
+// in order of increasing numbers of bits set. This way, we
+// can stop searching as soon as we find a candidate that
+// is within the error tolerance.
+//
+
+half
+DwaCompressor::LossyDctEncoderBase::quantize (half src, float errorTolerance)
+{
+    half            tmp;
+    float           srcFloat      = (float)src;
+    int             numSetBits    = countSetBits(src.bits());
+    const unsigned short *closest = get_dwaClosest(src.bits());
+
+    for (int targetNumSetBits = numSetBits - 1;
+         targetNumSetBits >= 0;
+         --targetNumSetBits)
+    {
+        tmp.setBits (*closest);
+
+        if (fabs ((float)tmp - srcFloat) < errorTolerance)
+            return tmp;
+
+        closest++;
+    }
+
+    return src;
+}
+
+
+//
+// RLE the zig-zag of the AC components + copy over 
+// into another tmp buffer
+//
+// Try to do a simple RLE scheme to reduce run's of 0's. This
+// differs from the jpeg EOB case, since EOB just indicates that
+// the rest of the block is zero. In our case, we have lots of
+// NaN symbols, which shouldn't be allowed to occur in DCT 
+// coefficents - so we'll use them for encoding runs.
+//
+// If the high byte is 0xff, then we have a run of 0's, of length
+// given by the low byte. For example, 0xff03 would be a run
+// of 3 0's, starting at the current location.
+//
+// block is our block of 64 coefficients
+// acPtr a pointer to back the RLE'd values into.
+//
+// This will advance the counter, _numAcComp.
+//
+
+void
+DwaCompressor::LossyDctEncoderBase::rleAc
+    (half *block,
+     unsigned short *&acPtr)
+{
+    int dctComp              = 1; 
+    unsigned short rleSymbol = 0x0;
+
+    while (dctComp < 64)
+    {
+        int runLen = 1;
+    
+        //
+        // If we don't have a 0, output verbatim
+        //
+
+        if (block[dctComp].bits() != rleSymbol)
+        {
+            *acPtr++ =  block[dctComp].bits();
+            _numAcComp++;
+
+            dctComp += runLen;
+            continue;
+        }
+
+        //
+        // We're sitting on a 0, so see how big the run is.
+        //
+
+        while ((dctComp+runLen < 64) && 
+               (block[dctComp+runLen].bits() == rleSymbol))
+        {
+            runLen++;
+        }
+
+        //
+        // If the run len is too small, just output verbatim
+        // otherwise output our run token
+        //
+        // Originally, we wouldn't have a separate symbol for
+        // "end of block". But in some experimentation, it looks
+        // like using 0xff00 for "end of block" can save a bit
+        // of space. 
+        //
+
+        if (runLen == 1)
+        {
+            runLen           = 1;
+            *acPtr++ = block[dctComp].bits();
+            _numAcComp++;
+
+            //
+            // Using 0xff00 for "end of block"
+            //
+        }
+        else if (runLen + dctComp == 64)
+        {
+            //
+            // Signal EOB
+            //
+
+            *acPtr++ = 0xff00;
+            _numAcComp++;
+        }
+        else
+        {
+            // 
+            // Signal normal run
+            //
+
+            *acPtr++   = 0xff00 | runLen;
+            _numAcComp++;
+        }
+
+        //
+        // Advance by runLen
+        //
+
+        dctComp += runLen;
+    }
+}
+
+
+// ==============================================================
+//
+//                     DwaCompressor
+//
+// --------------------------------------------------------------
+
+// 
+// DwaCompressor()
+//
+
+DwaCompressor::DwaCompressor
+    (const Header &hdr,
+     int maxScanLineSize,
+     int numScanLines,
+     AcCompression acCompression)
+:
+    Compressor(hdr),
+    _acCompression(acCompression),
+    _maxScanLineSize(maxScanLineSize),
+    _numScanLines(numScanLines),
+    _channels(hdr.channels()),
+    _packedAcBuffer(0),
+    _packedAcBufferSize(0),
+    _packedDcBuffer(0),
+    _packedDcBufferSize(0),
+    _rleBuffer(0),
+    _rleBufferSize(0),
+    _outBuffer(0),
+    _outBufferSize(0),
+    _zip(0),
+    _dwaCompressionLevel(45.0)
+{
+    _min[0] = hdr.dataWindow().min.x;
+    _min[1] = hdr.dataWindow().min.y;
+    _max[0] = hdr.dataWindow().max.x;
+    _max[1] = hdr.dataWindow().max.y;
+
+    for (int i=0; i < NUM_COMPRESSOR_SCHEMES; ++i) 
+    {
+        _planarUncBuffer[i] = 0;
+        _planarUncBufferSize[i] = 0;
+    }
+    
+    //
+    // Check the header for a quality attribute
+    //
+
+    if (hasDwaCompressionLevel (hdr))
+        _dwaCompressionLevel = dwaCompressionLevel (hdr);
+}
+
+
+DwaCompressor::~DwaCompressor()
+{
+    delete[] _packedAcBuffer;
+    delete[] _packedDcBuffer;
+    delete[] _rleBuffer;
+    delete[] _outBuffer;
+    delete _zip;
+
+    for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
+        delete[] _planarUncBuffer[i];
+}
+
+
+int
+DwaCompressor::numScanLines() const
+{
+    return _numScanLines;
+}
+
+
+OPENEXR_IMF_NAMESPACE::Compressor::Format 
+DwaCompressor::format() const
+{
+    if (GLOBAL_SYSTEM_LITTLE_ENDIAN)
+        return NATIVE;
+    else
+        return XDR;
+}
+
+
+int
+DwaCompressor::compress
+    (const char *inPtr,
+     int inSize,
+     int minY,
+     const char *&outPtr)
+{
+    return compress
+        (inPtr,
+         inSize, 
+         IMATH_NAMESPACE::Box2i (IMATH_NAMESPACE::V2i (_min[0], minY),
+                                 IMATH_NAMESPACE::V2i (_max[0], minY + numScanLines() - 1)),
+         outPtr);
+}
+
+
+int
+DwaCompressor::compressTile
+    (const char             *inPtr,
+     int                    inSize,
+     IMATH_NAMESPACE::Box2i range,
+     const char             *&outPtr)
+{
+    return compress (inPtr, inSize, range, outPtr);
+}
+
+
+int 
+DwaCompressor::compress
+    (const char             *inPtr,
+     int                    inSize,
+     IMATH_NAMESPACE::Box2i range,
+     const char             *&outPtr)
+{
+    const char *inDataPtr   = inPtr;
+    char       *packedAcEnd = 0;
+    char       *packedDcEnd = 0; 
+    int         fileVersion = 2;   // Starting with 2, we write the channel
+                                   // classification rules into the file
+
+    if (fileVersion < 2) 
+        initializeLegacyChannelRules();
+    else 
+        initializeDefaultChannelRules();
+
+    size_t outBufferSize = 0;
+    initializeBuffers(outBufferSize);
+
+    unsigned short          channelRuleSize = 0;
+    std::vector<Classifier> channelRules;
+    if (fileVersion >= 2) 
+    {
+        relevantChannelRules(channelRules);
+
+        channelRuleSize = Xdr::size<unsigned short>();
+        for (size_t i = 0; i < channelRules.size(); ++i) 
+            channelRuleSize += channelRules[i].size();
+    }
+
+    //
+    // Remember to allocate _outBuffer, if we haven't done so already.
+    //
+
+    outBufferSize += channelRuleSize;
+    if (outBufferSize > _outBufferSize) 
+    {
+        _outBufferSize = outBufferSize;
+        if (_outBuffer != 0)
+            delete[] _outBuffer;       
+        _outBuffer = new char[outBufferSize];
+    }
+
+    char *outDataPtr = &_outBuffer[NUM_SIZES_SINGLE * sizeof(OPENEXR_IMF_NAMESPACE::Int64) +
+                                   channelRuleSize];
+
+    //
+    // We might not be dealing with any color data, in which
+    // case the AC buffer size will be 0, and deferencing
+    // a vector will not be a good thing to do.
+    //
+
+    if (_packedAcBuffer)
+        packedAcEnd = _packedAcBuffer;
+
+    if (_packedDcBuffer)
+        packedDcEnd = _packedDcBuffer;
+
+    #define OBIDX(x) (Int64 *)&_outBuffer[x * sizeof (Int64)]
+
+    Int64 *version                 = OBIDX (VERSION);
+    Int64 *unknownUncompressedSize = OBIDX (UNKNOWN_UNCOMPRESSED_SIZE);
+    Int64 *unknownCompressedSize   = OBIDX (UNKNOWN_COMPRESSED_SIZE);
+    Int64 *acCompressedSize        = OBIDX (AC_COMPRESSED_SIZE);
+    Int64 *dcCompressedSize        = OBIDX (DC_COMPRESSED_SIZE);
+    Int64 *rleCompressedSize       = OBIDX (RLE_COMPRESSED_SIZE);
+    Int64 *rleUncompressedSize     = OBIDX (RLE_UNCOMPRESSED_SIZE);
+    Int64 *rleRawSize              = OBIDX (RLE_RAW_SIZE);
+
+    Int64 *totalAcUncompressedCount = OBIDX (AC_UNCOMPRESSED_COUNT);
+    Int64 *totalDcUncompressedCount = OBIDX (DC_UNCOMPRESSED_COUNT);
+
+    Int64 *acCompression            = OBIDX (AC_COMPRESSION);
+
+    int minX   = range.min.x;
+    int maxX   = std::min(range.max.x, _max[0]);
+    int minY   = range.min.y;
+    int maxY   = std::min(range.max.y, _max[1]);
+
+    //
+    // Zero all the numbers in the chunk header
+    //
+
+    memset (_outBuffer, 0, NUM_SIZES_SINGLE * sizeof (Int64));
+
+    //
+    // Setup the AC compression strategy and the version in the data block,
+    // then write the relevant channel classification rules if needed
+    //
+    *version       = fileVersion;  
+    *acCompression = _acCompression;
+
+    setupChannelData (minX, minY, maxX, maxY);
+
+    if (fileVersion >= 2) 
+    {
+        char *writePtr = &_outBuffer[NUM_SIZES_SINGLE * sizeof(OPENEXR_IMF_NAMESPACE::Int64)];
+        Xdr::write<CharPtrIO> (writePtr, channelRuleSize);
+        
+        for (size_t i = 0; i < channelRules.size(); ++i) 
+            channelRules[i].write(writePtr);
+    }
+
+    //
+    // Determine the start of each row in the input buffer
+    // Channels are interleaved by scanline
+    //
+
+    std::vector<bool> encodedChannels (_channelData.size());
+    std::vector< std::vector<const char *> > rowPtrs (_channelData.size());
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        encodedChannels[chan] = false;
+
+    inDataPtr =  inPtr;
+
+    for (int y = minY; y <= maxY; ++y)
+    {
+        for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        {
+
+            ChannelData *cd = &_channelData[chan];
+
+            if (IMATH_NAMESPACE::modp(y, cd->ySampling) != 0)
+                continue;
+
+            rowPtrs[chan].push_back(inDataPtr);
+            inDataPtr += cd->width * OPENEXR_IMF_NAMESPACE::pixelTypeSize(cd->type);
+        }
+    }
+
+    inDataPtr = inPtr;
+
+    // 
+    // Make a pass over all our CSC sets and try to encode them first
+    // 
+
+    for (unsigned int csc = 0; csc < _cscSets.size(); ++csc)
+    {
+
+        LossyDctEncoderCsc encoder
+            (_dwaCompressionLevel / 100000.f,
+             rowPtrs[_cscSets[csc].idx[0]],
+             rowPtrs[_cscSets[csc].idx[1]],
+             rowPtrs[_cscSets[csc].idx[2]],
+             packedAcEnd,
+             packedDcEnd,
+             get_dwaCompressorToNonlinear(),
+             _channelData[_cscSets[csc].idx[0]].width,
+             _channelData[_cscSets[csc].idx[0]].height,
+             _channelData[_cscSets[csc].idx[0]].type,
+             _channelData[_cscSets[csc].idx[1]].type,
+             _channelData[_cscSets[csc].idx[2]].type);
+
+        encoder.execute();
+
+        *totalAcUncompressedCount  += encoder.numAcValuesEncoded();
+        *totalDcUncompressedCount  += encoder.numDcValuesEncoded();
+
+        packedAcEnd += encoder.numAcValuesEncoded() * sizeof(unsigned short);
+        packedDcEnd += encoder.numDcValuesEncoded() * sizeof(unsigned short);
+
+        encodedChannels[_cscSets[csc].idx[0]] = true;
+        encodedChannels[_cscSets[csc].idx[1]] = true;
+        encodedChannels[_cscSets[csc].idx[2]] = true;
+    }
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        ChannelData *cd = &_channelData[chan];
+
+        if (encodedChannels[chan])
+            continue;
+
+        switch (cd->compression)
+        {
+          case LOSSY_DCT:
+
+            //
+            // For LOSSY_DCT, treat this just like the CSC'd case,
+            // but only operate on one channel
+            //
+
+            {
+                const unsigned short *nonlinearLut = 0;
+
+                if (!cd->pLinear)
+                    nonlinearLut = get_dwaCompressorToNonlinear(); 
+
+                LossyDctEncoder encoder
+                    (_dwaCompressionLevel / 100000.f,
+                     rowPtrs[chan],
+                     packedAcEnd,
+                     packedDcEnd,
+                     nonlinearLut,
+                     cd->width,
+                     cd->height,
+                     cd->type);
+
+                encoder.execute();
+
+                *totalAcUncompressedCount  += encoder.numAcValuesEncoded();
+                *totalDcUncompressedCount  += encoder.numDcValuesEncoded();
+
+                packedAcEnd +=
+                    encoder.numAcValuesEncoded() * sizeof (unsigned short);
+
+                packedDcEnd +=
+                    encoder.numDcValuesEncoded() * sizeof (unsigned short);
+            }
+
+            break;
+
+          case RLE:
+
+            //
+            // For RLE, bash the bytes up so that the first bytes of each
+            // pixel are contingous, as are the second bytes, and so on.
+            //
+
+            for (unsigned int y = 0; y < rowPtrs[chan].size(); ++y)
+            {
+                const char *row = rowPtrs[chan][y];
+
+                for (int x = 0; x < cd->width; ++x)
+                {
+                    for (int byte = 0;
+                         byte < OPENEXR_IMF_NAMESPACE::pixelTypeSize (cd->type);
+                         ++byte)
+                    {
+                            
+                        *cd->planarUncRleEnd[byte]++ = *row++;
+                    }
+                }
+
+                *rleRawSize += cd->width * OPENEXR_IMF_NAMESPACE::pixelTypeSize(cd->type);
+            }
+
+            break;
+
+          case UNKNOWN:
+           
+            //
+            // Otherwise, just copy data over verbatim
+            //
+
+            {
+                int scanlineSize = cd->width * OPENEXR_IMF_NAMESPACE::pixelTypeSize(cd->type);
+
+                for (unsigned int y = 0; y < rowPtrs[chan].size(); ++y)
+                {
+                    memcpy (cd->planarUncBufferEnd,
+                            rowPtrs[chan][y],
+                            scanlineSize);
+    
+                    cd->planarUncBufferEnd += scanlineSize;
+                }
+
+                *unknownUncompressedSize += cd->planarUncSize;
+            }
+
+            break;
+
+          default:
+
+            assert (false);
+        }
+
+        encodedChannels[chan] = true;
+    }
+
+    //
+    // Pack the Unknown data into the output buffer first. Instead of
+    // just copying it uncompressed, try zlib compression at least.
+    //
+
+    if (*unknownUncompressedSize > 0)
+    {
+        uLongf inSize  = (uLongf)(*unknownUncompressedSize);
+        uLongf outSize = compressBound (inSize);
+
+        if (Z_OK != ::compress2 ((Bytef *)outDataPtr,
+                                 &outSize,
+                                 (const Bytef *)_planarUncBuffer[UNKNOWN],
+                                 inSize,
+                                 9))
+        {
+            throw IEX_NAMESPACE::BaseExc ("Data compression (zlib) failed.");
+        }
+
+        outDataPtr += outSize;
+        *unknownCompressedSize = outSize;
+    }
+
+    //
+    // Now, pack all the Lossy DCT coefficients into our output
+    // buffer, with Huffman encoding.
+    //
+    // Also, record the compressed size and the number of 
+    // uncompressed componentns we have.
+    //
+
+    if (*totalAcUncompressedCount > 0)
+    { 
+        switch (_acCompression)
+        {
+          case STATIC_HUFFMAN:
+
+            *acCompressedSize = (int)
+                hufCompress((unsigned short *)_packedAcBuffer,
+                            (int)*totalAcUncompressedCount,
+                            outDataPtr);                
+            break;
+
+          case DEFLATE:
+
+            {
+                uLongf destLen = compressBound (
+                    (*totalAcUncompressedCount) * sizeof (unsigned short));
+
+                if (Z_OK != ::compress2
+                                ((Bytef *)outDataPtr,
+                                 &destLen,
+                                 (Bytef *)_packedAcBuffer, 
+                                 (uLong)(*totalAcUncompressedCount
+                                                * sizeof (unsigned short)),
+                                 9))
+                {
+                    throw IEX_NAMESPACE::InputExc ("Data compression (zlib) failed.");
+                }
+
+                *acCompressedSize = destLen;        
+            }
+
+            break;
+
+          default:
+            
+            assert (false);
+        }
+
+        outDataPtr += *acCompressedSize;
+    }
+
+    // 
+    // Handle the DC components separately
+    //
+
+    if (*totalDcUncompressedCount > 0)
+    {
+        *dcCompressedSize = _zip->compress
+            (_packedDcBuffer,
+             (int)(*totalDcUncompressedCount) * sizeof (unsigned short),
+             outDataPtr);
+
+        outDataPtr += *dcCompressedSize;
+    }
+
+    // 
+    // If we have RLE data, first RLE encode it and set the uncompressed
+    // size. Then, deflate the results and set the compressed size.
+    //    
+
+    if (*rleRawSize > 0)
+    {
+        *rleUncompressedSize = rleCompress
+            ((int)(*rleRawSize),
+             _planarUncBuffer[RLE],
+             (signed char *)_rleBuffer);
+
+        uLongf dstLen = compressBound ((uLongf)*rleUncompressedSize);
+
+        if (Z_OK != ::compress2
+                        ((Bytef *)outDataPtr, 
+                         &dstLen, 
+                         (Bytef *)_rleBuffer, 
+                         (uLong)(*rleUncompressedSize),
+                         9))
+        {
+            throw IEX_NAMESPACE::BaseExc ("Error compressing RLE'd data.");
+        }
+        
+       *rleCompressedSize = dstLen;
+        outDataPtr       += *rleCompressedSize;
+    }
+
+    // 
+    // Flip the counters to XDR format
+    //         
+
+    for (int i = 0; i < NUM_SIZES_SINGLE; ++i)
+    {
+        Int64  src = *(((Int64 *)_outBuffer) + i);
+        char  *dst = (char *)(((Int64 *)_outBuffer) + i);
+
+        Xdr::write<CharPtrIO> (dst, src);
+    }
+
+    //
+    // We're done - compute the number of bytes we packed
+    //
+
+    outPtr = _outBuffer;
+
+    return static_cast<int>(outDataPtr - _outBuffer + 1);
+}
+
+
+int
+DwaCompressor::uncompress
+    (const char *inPtr,
+     int inSize,
+     int minY,
+     const char *&outPtr)
+{
+    return uncompress (inPtr,
+                       inSize,
+                       IMATH_NAMESPACE::Box2i (IMATH_NAMESPACE::V2i (_min[0], minY),
+                       IMATH_NAMESPACE::V2i (_max[0], minY + numScanLines() - 1)),
+                       outPtr);
+}
+
+
+int 
+DwaCompressor::uncompressTile
+    (const char *inPtr,
+     int inSize,
+     IMATH_NAMESPACE::Box2i range,
+     const char *&outPtr)
+{
+    return uncompress (inPtr, inSize, range, outPtr);
+}
+
+
+int 
+DwaCompressor::uncompress
+    (const char *inPtr,
+     int inSize,
+     IMATH_NAMESPACE::Box2i range,
+     const char *&outPtr)
+{
+    int minX = range.min.x;
+    int maxX = std::min (range.max.x, _max[0]);
+    int minY = range.min.y;
+    int maxY = std::min (range.max.y, _max[1]);
+
+    int headerSize = NUM_SIZES_SINGLE*sizeof(Int64);
+    if (inSize < headerSize) 
+    {
+        throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                            "(truncated header).");
+    }
+
+    // 
+    // Flip the counters from XDR to NATIVE
+    //
+
+    for (int i = 0; i < NUM_SIZES_SINGLE; ++i)
+    {
+        Int64      *dst =  (((Int64 *)inPtr) + i);
+        const char *src = (char *)(((Int64 *)inPtr) + i);
+
+        Xdr::read<CharPtrIO> (src, *dst);
+    }
+
+    //
+    // Unwind all the counter info
+    //
+
+    const Int64 *inPtr64 = (const Int64*) inPtr;
+
+    Int64 version                  = *(inPtr64 + VERSION);
+    Int64 unknownUncompressedSize  = *(inPtr64 + UNKNOWN_UNCOMPRESSED_SIZE);
+    Int64 unknownCompressedSize    = *(inPtr64 + UNKNOWN_COMPRESSED_SIZE);
+    Int64 acCompressedSize         = *(inPtr64 + AC_COMPRESSED_SIZE);
+    Int64 dcCompressedSize         = *(inPtr64 + DC_COMPRESSED_SIZE);
+    Int64 rleCompressedSize        = *(inPtr64 + RLE_COMPRESSED_SIZE);
+    Int64 rleUncompressedSize      = *(inPtr64 + RLE_UNCOMPRESSED_SIZE);
+    Int64 rleRawSize               = *(inPtr64 + RLE_RAW_SIZE);
+    Int64 totalAcUncompressedCount = *(inPtr64 + AC_UNCOMPRESSED_COUNT); 
+    Int64 totalDcUncompressedCount = *(inPtr64 + DC_UNCOMPRESSED_COUNT); 
+
+    Int64 acCompression            = *(inPtr64 + AC_COMPRESSION); 
+
+    Int64 compressedSize           = unknownCompressedSize + 
+                                     acCompressedSize +
+                                     dcCompressedSize +
+                                     rleCompressedSize;
+
+    const char *dataPtr            = inPtr + NUM_SIZES_SINGLE * sizeof(Int64);
+
+    /* Both the sum and individual sizes are checked in case of overflow. */
+    if (inSize < (headerSize + compressedSize) ||
+        inSize < unknownCompressedSize ||
+        inSize < acCompressedSize ||
+        inSize < dcCompressedSize ||
+        inSize < rleCompressedSize)
+    {
+        throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                            "(truncated file).");
+    }
+
+    if ((SInt64)unknownUncompressedSize < 0  ||
+        (SInt64)unknownCompressedSize < 0    ||
+        (SInt64)acCompressedSize < 0         ||
+        (SInt64)dcCompressedSize < 0         ||
+        (SInt64)rleCompressedSize < 0        ||
+        (SInt64)rleUncompressedSize < 0      ||
+        (SInt64)rleRawSize < 0               ||
+        (SInt64)totalAcUncompressedCount < 0 ||
+        (SInt64)totalDcUncompressedCount < 0)
+    {
+        throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                            " (corrupt header).");
+    }
+
+    if (version < 2) 
+        initializeLegacyChannelRules();
+    else
+    {
+        unsigned short ruleSize = 0;
+        Xdr::read<CharPtrIO>(dataPtr, ruleSize);
+
+        if (ruleSize < 0) 
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                " (corrupt header file).");
+
+        headerSize += ruleSize;
+        if (inSize < headerSize + compressedSize)
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                " (truncated file).");
+
+        _channelRules.clear();
+        ruleSize -= Xdr::size<unsigned short> ();
+        while (ruleSize > 0) 
+        {
+            Classifier rule(dataPtr, ruleSize);
+            
+            _channelRules.push_back(rule);
+            ruleSize -= rule.size();
+        }
+    }
+
+
+    size_t outBufferSize = 0;
+    initializeBuffers(outBufferSize);
+
+    //
+    // Allocate _outBuffer, if we haven't done so already
+    //
+
+    if (_maxScanLineSize * numScanLines() > _outBufferSize) 
+    {
+        _outBufferSize = _maxScanLineSize * numScanLines();
+        if (_outBuffer != 0)
+            delete[] _outBuffer;
+        _outBuffer = new char[_maxScanLineSize * numScanLines()];
+    }
+
+
+    char *outBufferEnd = _outBuffer;
+
+       
+    //
+    // Find the start of the RLE packed AC components and
+    // the DC components for each channel. This will be handy   
+    // if you want to decode the channels in parallel later on.
+    //
+
+    char *packedAcBufferEnd = 0; 
+
+    if (_packedAcBuffer)
+        packedAcBufferEnd = _packedAcBuffer;
+
+    char *packedDcBufferEnd = 0;
+
+    if (_packedDcBuffer)
+        packedDcBufferEnd = _packedDcBuffer;
+
+    //
+    // UNKNOWN data is packed first, followed by the 
+    // Huffman-compressed AC, then the DC values, 
+    // and then the zlib compressed RLE data.
+    //
+    
+    const char *compressedUnknownBuf = dataPtr;
+
+    const char *compressedAcBuf      = compressedUnknownBuf + 
+                                  static_cast<ptrdiff_t>(unknownCompressedSize);
+    const char *compressedDcBuf      = compressedAcBuf +
+                                  static_cast<ptrdiff_t>(acCompressedSize);
+    const char *compressedRleBuf     = compressedDcBuf + 
+                                  static_cast<ptrdiff_t>(dcCompressedSize);
+
+    // 
+    // Sanity check that the version is something we expect. Right now, 
+    // we can decode version 0, 1, and 2. v1 adds 'end of block' symbols
+    // to the AC RLE. v2 adds channel classification rules at the 
+    // start of the data block.
+    //
+
+    if (version > 2)
+        throw IEX_NAMESPACE::InputExc ("Invalid version of compressed data block");    
+
+    setupChannelData(minX, minY, maxX, maxY);
+
+    // 
+    // Uncompress the UNKNOWN data into _planarUncBuffer[UNKNOWN]
+    //
+
+    if (unknownCompressedSize > 0)
+    {
+        if (unknownUncompressedSize > _planarUncBufferSize[UNKNOWN]) 
+        {
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+
+        uLongf outSize = (uLongf)unknownUncompressedSize;
+
+        if (Z_OK != ::uncompress
+                        ((Bytef *)_planarUncBuffer[UNKNOWN],
+                         &outSize,
+                         (Bytef *)compressedUnknownBuf,
+                         (uLong)unknownCompressedSize))
+        {
+            throw IEX_NAMESPACE::BaseExc("Error uncompressing UNKNOWN data.");
+        }
+    }
+
+    // 
+    // Uncompress the AC data into _packedAcBuffer
+    //
+
+    if (acCompressedSize > 0)
+    {
+        if (totalAcUncompressedCount*sizeof(unsigned short) > _packedAcBufferSize)
+        {
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+
+        //
+        // Don't trust the user to get it right, look in the file.
+        //
+
+        switch (acCompression)
+        {
+          case STATIC_HUFFMAN:
+
+            hufUncompress
+                (compressedAcBuf, 
+                 (int)acCompressedSize, 
+                 (unsigned short *)_packedAcBuffer, 
+                 (int)totalAcUncompressedCount); 
+
+            break;
+
+          case DEFLATE:
+            {
+                uLongf destLen =
+                    (int)(totalAcUncompressedCount) * sizeof (unsigned short);
+
+                if (Z_OK != ::uncompress
+                                ((Bytef *)_packedAcBuffer,
+                                 &destLen,
+                                 (Bytef *)compressedAcBuf,
+                                 (uLong)acCompressedSize))
+                {
+                    throw IEX_NAMESPACE::InputExc ("Data decompression (zlib) failed.");
+                }
+
+                if (totalAcUncompressedCount * sizeof (unsigned short) !=
+                                destLen)
+                {
+                    throw IEX_NAMESPACE::InputExc ("AC data corrupt.");     
+                }
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::NoImplExc ("Unknown AC Compression");
+            break;
+        }
+    }
+
+    //
+    // Uncompress the DC data into _packedDcBuffer
+    //
+
+    if (dcCompressedSize > 0)
+    {
+        if (totalDcUncompressedCount*sizeof(unsigned short) > _packedDcBufferSize)
+        {
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+
+        if (_zip->uncompress
+                    (compressedDcBuf, (int)dcCompressedSize, _packedDcBuffer)
+            != (int)totalDcUncompressedCount * sizeof (unsigned short))
+        {
+            throw IEX_NAMESPACE::BaseExc("DC data corrupt.");
+        }
+    }
+
+    //
+    // Uncompress the RLE data into _rleBuffer, then unRLE the results
+    // into _planarUncBuffer[RLE]
+    //
+
+    if (rleRawSize > 0)
+    {
+        if (rleUncompressedSize > _rleBufferSize ||
+            rleRawSize > _planarUncBufferSize[RLE])
+        {
+            throw IEX_NAMESPACE::InputExc("Error uncompressing DWA data"
+                                "(corrupt header).");
+        }
+        uLongf dstLen = (uLongf)rleUncompressedSize;
+
+        if (Z_OK != ::uncompress
+                        ((Bytef *)_rleBuffer,
+                         &dstLen,
+                         (Bytef *)compressedRleBuf,
+                         (uLong)rleCompressedSize))
+        {
+            throw IEX_NAMESPACE::BaseExc("Error uncompressing RLE data.");
+        }
+
+        if (dstLen != rleUncompressedSize)
+            throw IEX_NAMESPACE::BaseExc("RLE data corrupted");
+
+        if (rleUncompress
+                ((int)rleUncompressedSize, 
+                 (int)rleRawSize,
+                 (signed char *)_rleBuffer,
+                 _planarUncBuffer[RLE]) != rleRawSize)
+        {        
+            throw IEX_NAMESPACE::BaseExc("RLE data corrupted");
+        }
+    }
+
+    //
+    // Determine the start of each row in the output buffer
+    //
+
+    std::vector<bool> decodedChannels (_channelData.size());
+    std::vector< std::vector<char *> > rowPtrs (_channelData.size());
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        decodedChannels[chan] = false;
+
+    outBufferEnd = _outBuffer;
+
+    for (int y = minY; y <= maxY; ++y)
+    {
+        for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+        {
+            ChannelData *cd = &_channelData[chan];
+
+            if (IMATH_NAMESPACE::modp (y, cd->ySampling) != 0)
+                continue;
+
+            rowPtrs[chan].push_back (outBufferEnd);
+            outBufferEnd += cd->width * OPENEXR_IMF_NAMESPACE::pixelTypeSize (cd->type);
+        }
+    }
+
+    //
+    // Setup to decode each block of 3 channels that need to
+    // be handled together
+    //
+
+    for (unsigned int csc = 0; csc < _cscSets.size(); ++csc)
+    {
+        int rChan = _cscSets[csc].idx[0];    
+        int gChan = _cscSets[csc].idx[1];    
+        int bChan = _cscSets[csc].idx[2];    
+
+
+        LossyDctDecoderCsc decoder
+            (rowPtrs[rChan],
+             rowPtrs[gChan],
+             rowPtrs[bChan],
+             packedAcBufferEnd,
+             packedDcBufferEnd,
+             get_dwaCompressorToLinear(),
+             _channelData[rChan].width,
+             _channelData[rChan].height,
+             _channelData[rChan].type,
+             _channelData[gChan].type,
+             _channelData[bChan].type);
+
+        decoder.execute();
+
+        packedAcBufferEnd +=
+            decoder.numAcValuesEncoded() * sizeof (unsigned short);
+
+        packedDcBufferEnd +=
+            decoder.numDcValuesEncoded() * sizeof (unsigned short);
+
+        decodedChannels[rChan] = true;
+        decodedChannels[gChan] = true;
+        decodedChannels[bChan] = true;
+    }
+
+    //
+    // Setup to handle the remaining channels by themselves
+    //
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        if (decodedChannels[chan])
+            continue;
+
+        ChannelData *cd = &_channelData[chan];
+        int pixelSize = OPENEXR_IMF_NAMESPACE::pixelTypeSize (cd->type);
+
+        switch (cd->compression)
+        {
+          case LOSSY_DCT:
+
+            //
+            // Setup a single-channel lossy DCT decoder pointing
+            // at the output buffer
+            //
+
+            {
+                const unsigned short *linearLut = 0;
+
+                if (!cd->pLinear)
+                    linearLut = get_dwaCompressorToLinear();
+
+                LossyDctDecoder decoder
+                    (rowPtrs[chan],
+                     packedAcBufferEnd,
+                     packedDcBufferEnd,
+                     linearLut,
+                     cd->width,
+                     cd->height,
+                     cd->type);
+
+                decoder.execute();   
+
+                packedAcBufferEnd += 
+                    decoder.numAcValuesEncoded() * sizeof (unsigned short);
+
+                packedDcBufferEnd += 
+                    decoder.numDcValuesEncoded() * sizeof (unsigned short);
+            }
+
+            break;
+
+          case RLE:
+
+            //
+            // For the RLE case, the data has been un-RLE'd into
+            // planarUncRleEnd[], but is still split out by bytes.
+            // We need to rearrange the bytes back into the correct
+            // order in the output buffer;
+            //
+
+            {
+                int row = 0;
+
+                for (int y = minY; y <= maxY; ++y)
+                {
+                    if (IMATH_NAMESPACE::modp (y, cd->ySampling) != 0)
+                        continue;
+
+                    char *dst = rowPtrs[chan][row];
+
+                    if (pixelSize == 2)
+                    {
+                        interleaveByte2 (dst, 
+                                         cd->planarUncRleEnd[0],
+                                         cd->planarUncRleEnd[1],
+                                         cd->width);
+                                            
+                        cd->planarUncRleEnd[0] += cd->width;
+                        cd->planarUncRleEnd[1] += cd->width;
+                    }
+                    else
+                    {
+                        for (int x = 0; x < cd->width; ++x)
+                        {
+                            for (int byte = 0; byte < pixelSize; ++byte)
+                            {
+                               *dst++ = *cd->planarUncRleEnd[byte]++;
+                            }
+                        }
+                    }
+
+                    row++;
+                }
+            }
+
+            break;
+
+          case UNKNOWN:
+
+            //
+            // In the UNKNOWN case, data is already in planarUncBufferEnd
+            // and just needs to copied over to the output buffer
+            //
+
+            {
+                int row             = 0;
+                int dstScanlineSize = cd->width * OPENEXR_IMF_NAMESPACE::pixelTypeSize (cd->type);
+
+                for (int y = minY; y <= maxY; ++y)
+                {
+                    if (IMATH_NAMESPACE::modp (y, cd->ySampling) != 0)
+                        continue;
+
+                    memcpy (rowPtrs[chan][row],
+                            cd->planarUncBufferEnd,
+                            dstScanlineSize);
+
+                    cd->planarUncBufferEnd += dstScanlineSize;
+                    row++;
+                }
+            }
+
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::NoImplExc ("Unhandled compression scheme case");
+            break;
+        }
+
+        decodedChannels[chan] = true;
+    }
+
+    //
+    // Return a ptr to _outBuffer
+    //
+
+    outPtr = _outBuffer;
+    return (int)(outBufferEnd - _outBuffer);
+}
+
+
+// static
+void
+DwaCompressor::initializeFuncs()
+{
+    convertFloatToHalf64 = convertFloatToHalf64_scalar;
+    fromHalfZigZag       = fromHalfZigZag_scalar;
+
+    CpuId cpuId;
+
+    //
+    // Setup HALF <-> FLOAT conversion implementations
+    //
+
+    if (cpuId.avx && cpuId.f16c)
+    {
+        convertFloatToHalf64 = convertFloatToHalf64_f16c;
+        fromHalfZigZag       = fromHalfZigZag_f16c;
+    } 
+
+    //
+    // Setup inverse DCT implementations
+    //
+
+    dctInverse8x8_0 = dctInverse8x8_scalar<0>;
+    dctInverse8x8_1 = dctInverse8x8_scalar<1>;
+    dctInverse8x8_2 = dctInverse8x8_scalar<2>;
+    dctInverse8x8_3 = dctInverse8x8_scalar<3>;
+    dctInverse8x8_4 = dctInverse8x8_scalar<4>;
+    dctInverse8x8_5 = dctInverse8x8_scalar<5>;
+    dctInverse8x8_6 = dctInverse8x8_scalar<6>;
+    dctInverse8x8_7 = dctInverse8x8_scalar<7>;
+
+    if (cpuId.avx) 
+    {
+        dctInverse8x8_0 = dctInverse8x8_avx<0>;
+        dctInverse8x8_1 = dctInverse8x8_avx<1>;
+        dctInverse8x8_2 = dctInverse8x8_avx<2>;
+        dctInverse8x8_3 = dctInverse8x8_avx<3>;
+        dctInverse8x8_4 = dctInverse8x8_avx<4>;
+        dctInverse8x8_5 = dctInverse8x8_avx<5>;
+        dctInverse8x8_6 = dctInverse8x8_avx<6>;
+        dctInverse8x8_7 = dctInverse8x8_avx<7>;
+    } 
+    else if (cpuId.sse2) 
+    {
+        dctInverse8x8_0 = dctInverse8x8_sse2<0>;
+        dctInverse8x8_1 = dctInverse8x8_sse2<1>;
+        dctInverse8x8_2 = dctInverse8x8_sse2<2>;
+        dctInverse8x8_3 = dctInverse8x8_sse2<3>;
+        dctInverse8x8_4 = dctInverse8x8_sse2<4>;
+        dctInverse8x8_5 = dctInverse8x8_sse2<5>;
+        dctInverse8x8_6 = dctInverse8x8_sse2<6>;
+        dctInverse8x8_7 = dctInverse8x8_sse2<7>;
+    }
+}
+
+
+//
+// Handle channel classification and buffer allocation once we know
+// how to classify channels
+//
+
+void
+DwaCompressor::initializeBuffers (size_t &outBufferSize)
+{
+    classifyChannels (_channels, _channelData, _cscSets);
+
+    //
+    // _outBuffer needs to be big enough to hold all our 
+    // compressed data - which could vary depending on what sort
+    // of channels we have. 
+    //
+
+    int maxOutBufferSize  = 0;
+    int numLossyDctChans  = 0;
+    int unknownBufferSize = 0;
+    int rleBufferSize     = 0;
+
+    int maxLossyDctAcSize = (int)ceil ((float)numScanLines() / 8.0f) * 
+                            (int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) *
+                            63 * sizeof (unsigned short);
+
+    int maxLossyDctDcSize = (int)ceil ((float)numScanLines() / 8.0f) * 
+                            (int)ceil ((float)(_max[0] - _min[0] + 1) / 8.0f) *
+                            sizeof (unsigned short);
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        switch (_channelData[chan].compression)
+        {
+          case LOSSY_DCT:
+
+            //
+            // This is the size of the number of packed
+            // components, plus the requirements for
+            // maximum Huffman encoding size (for STATIC_HUFFMAN)
+            // or for zlib compression (for DEFLATE)
+            //
+
+            maxOutBufferSize += std::max(
+                            (int)(2 * maxLossyDctAcSize + 65536),
+                            (int)compressBound (maxLossyDctAcSize) );
+            numLossyDctChans++;
+            break;
+
+          case RLE:
+            {
+                //
+                // RLE, if gone horribly wrong, could double the size
+                // of the source data.
+                //
+
+                int rleAmount = 2 * numScanLines() * (_max[0] - _min[0] + 1) *
+                                OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type);
+
+                rleBufferSize += rleAmount;
+            }
+            break;
+
+
+          case UNKNOWN:
+
+            unknownBufferSize += numScanLines() * (_max[0] - _min[0] + 1) *
+                                 OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type);
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::NoImplExc ("Unhandled compression scheme case");
+            break;
+        }
+    }
+
+    //
+    // Also, since the results of the RLE are packed into 
+    // the output buffer, we need the extra room there. But
+    // we're going to zlib compress() the data we pack, 
+    // which could take slightly more space
+    //
+
+    maxOutBufferSize += (int)compressBound ((uLongf)rleBufferSize);
+    
+    //
+    // And the same goes for the UNKNOWN data
+    //
+
+    maxOutBufferSize += (int)compressBound ((uLongf)unknownBufferSize);
+
+    //
+    // Allocate a zip/deflate compressor big enought to hold the DC data
+    // and include it's compressed results in the size requirements
+    // for our output buffer
+    //
+
+    if (_zip == 0) 
+        _zip = new Zip (maxLossyDctDcSize * numLossyDctChans);
+    else if (_zip->maxRawSize() < maxLossyDctDcSize * numLossyDctChans)
+    {
+        delete _zip;
+        _zip = new Zip (maxLossyDctDcSize * numLossyDctChans);
+    }
+
+
+    maxOutBufferSize += _zip->maxCompressedSize();
+
+    //
+    // We also need to reserve space at the head of the buffer to 
+    // write out the size of our various packed and compressed data.
+    //
+
+    maxOutBufferSize += NUM_SIZES_SINGLE * sizeof (Int64); 
+                    
+
+    //
+    // Later, we're going to hijack outBuffer for the result of
+    // both encoding and decoding. So it needs to be big enough
+    // to hold either a buffers' worth of uncompressed or
+    // compressed data
+    //
+    // For encoding, we'll need _outBuffer to hold maxOutBufferSize bytes,
+    // but for decoding, we only need it to be maxScanLineSize*numScanLines.
+    // Cache the max size for now, and alloc the buffer when we either
+    // encode or decode.
+    //
+
+    outBufferSize = maxOutBufferSize;
+
+
+    //
+    // _packedAcBuffer holds the quantized DCT coefficients prior
+    // to Huffman encoding
+    //
+
+    if (maxLossyDctAcSize * numLossyDctChans > _packedAcBufferSize)
+    {
+        _packedAcBufferSize = maxLossyDctAcSize * numLossyDctChans;
+        if (_packedAcBuffer != 0) 
+            delete[] _packedAcBuffer;
+        _packedAcBuffer = new char[_packedAcBufferSize];
+    }
+
+    //
+    // _packedDcBuffer holds one quantized DCT coef per 8x8 block
+    //
+
+    if (maxLossyDctDcSize * numLossyDctChans > _packedDcBufferSize)
+    {
+        _packedDcBufferSize = maxLossyDctDcSize * numLossyDctChans;
+        if (_packedDcBuffer != 0) 
+            delete[] _packedDcBuffer;
+        _packedDcBuffer     = new char[_packedDcBufferSize];
+    }
+
+    if (rleBufferSize > _rleBufferSize) 
+    {
+        _rleBufferSize = rleBufferSize;
+        if (_rleBuffer != 0) 
+            delete[] _rleBuffer;
+        _rleBuffer = new char[rleBufferSize];
+    }
+
+    // 
+    // The planar uncompressed buffer will hold float data for LOSSY_DCT
+    // compressed values, and whatever the native type is for other
+    // channels. We're going to use this to hold data in a planar
+    // format, as opposed to the native interleaved format we take
+    // into compress() and give back from uncompress().
+    //
+    // This also makes it easier to compress the UNKNOWN and RLE data
+    // all in one swoop (for each compression scheme).
+    //
+
+    int planarUncBufferSize[NUM_COMPRESSOR_SCHEMES];
+    for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
+        planarUncBufferSize[i] = 0;
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        switch (_channelData[chan].compression)
+        {
+          case LOSSY_DCT:
+            break;
+
+          case RLE:
+            planarUncBufferSize[RLE] +=
+                     numScanLines() * (_max[0] - _min[0] + 1) *
+                     OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type);
+            break;
+
+          case UNKNOWN: 
+            planarUncBufferSize[UNKNOWN] +=
+                     numScanLines() * (_max[0] - _min[0] + 1) *
+                     OPENEXR_IMF_NAMESPACE::pixelTypeSize (_channelData[chan].type);
+            break;
+
+          default:
+            throw IEX_NAMESPACE::NoImplExc ("Unhandled compression scheme case");
+            break;
+        }
+    }
+
+    //
+    // UNKNOWN data is going to be zlib compressed, which needs 
+    // a little extra headroom
+    //
+
+    if (planarUncBufferSize[UNKNOWN] > 0)
+    {
+        planarUncBufferSize[UNKNOWN] = 
+            compressBound ((uLongf)planarUncBufferSize[UNKNOWN]);
+    }
+
+    for (int i = 0; i < NUM_COMPRESSOR_SCHEMES; ++i)
+    {
+        if (planarUncBufferSize[i] > _planarUncBufferSize[i]) 
+        {
+            _planarUncBufferSize[i] = planarUncBufferSize[i];
+            if (_planarUncBuffer[i] != 0) 
+                delete[] _planarUncBuffer[i];
+            _planarUncBuffer[i] = new char[planarUncBufferSize[i]];
+        }
+    }
+}
+
+
+//
+// Setup channel classification rules to use when writing files
+//
+
+void
+DwaCompressor::initializeDefaultChannelRules ()
+{
+    _channelRules.clear();
+
+    _channelRules.push_back (Classifier ("R",     LOSSY_DCT, HALF,   0, false));
+    _channelRules.push_back (Classifier ("R",     LOSSY_DCT, FLOAT,  0, false));
+    _channelRules.push_back (Classifier ("G",     LOSSY_DCT, HALF,   1, false));
+    _channelRules.push_back (Classifier ("G",     LOSSY_DCT, FLOAT,  1, false));
+    _channelRules.push_back (Classifier ("B",     LOSSY_DCT, HALF,   2, false));
+    _channelRules.push_back (Classifier ("B",     LOSSY_DCT, FLOAT,  2, false));
+
+    _channelRules.push_back (Classifier ("Y",     LOSSY_DCT, HALF,  -1, false));
+    _channelRules.push_back (Classifier ("Y",     LOSSY_DCT, FLOAT, -1, false));
+    _channelRules.push_back (Classifier ("BY",    LOSSY_DCT, HALF,  -1, false));
+    _channelRules.push_back (Classifier ("BY",    LOSSY_DCT, FLOAT, -1, false));
+    _channelRules.push_back (Classifier ("RY",    LOSSY_DCT, HALF,  -1, false));
+    _channelRules.push_back (Classifier ("RY",    LOSSY_DCT, FLOAT, -1, false));
+
+    _channelRules.push_back (Classifier ("A",     RLE,       UINT,  -1, false));
+    _channelRules.push_back (Classifier ("A",     RLE,       HALF,  -1, false));
+    _channelRules.push_back (Classifier ("A",     RLE,       FLOAT, -1, false));
+}
+
+
+//
+// Setup channel classification rules when reading files with VERSION < 2
+//
+
+void
+DwaCompressor::initializeLegacyChannelRules ()
+{
+    _channelRules.clear();
+
+    _channelRules.push_back (Classifier ("r",     LOSSY_DCT, HALF,   0, true));
+    _channelRules.push_back (Classifier ("r",     LOSSY_DCT, FLOAT,  0, true));
+    _channelRules.push_back (Classifier ("red",   LOSSY_DCT, HALF,   0, true));
+    _channelRules.push_back (Classifier ("red",   LOSSY_DCT, FLOAT,  0, true));
+    _channelRules.push_back (Classifier ("g",     LOSSY_DCT, HALF,   1, true));
+    _channelRules.push_back (Classifier ("g",     LOSSY_DCT, FLOAT,  1, true));
+    _channelRules.push_back (Classifier ("grn",   LOSSY_DCT, HALF,   1, true));
+    _channelRules.push_back (Classifier ("grn",   LOSSY_DCT, FLOAT,  1, true));
+    _channelRules.push_back (Classifier ("green", LOSSY_DCT, HALF,   1, true));
+    _channelRules.push_back (Classifier ("green", LOSSY_DCT, FLOAT,  1, true));
+    _channelRules.push_back (Classifier ("b",     LOSSY_DCT, HALF,   2, true));
+    _channelRules.push_back (Classifier ("b",     LOSSY_DCT, FLOAT,  2, true));
+    _channelRules.push_back (Classifier ("blu",   LOSSY_DCT, HALF,   2, true));
+    _channelRules.push_back (Classifier ("blu",   LOSSY_DCT, FLOAT,  2, true));
+    _channelRules.push_back (Classifier ("blue",  LOSSY_DCT, HALF,   2, true));
+    _channelRules.push_back (Classifier ("blue",  LOSSY_DCT, FLOAT,  2, true));
+
+    _channelRules.push_back (Classifier ("y",     LOSSY_DCT, HALF,  -1, true));
+    _channelRules.push_back (Classifier ("y",     LOSSY_DCT, FLOAT, -1, true));
+    _channelRules.push_back (Classifier ("by",    LOSSY_DCT, HALF,  -1, true));
+    _channelRules.push_back (Classifier ("by",    LOSSY_DCT, FLOAT, -1, true));
+    _channelRules.push_back (Classifier ("ry",    LOSSY_DCT, HALF,  -1, true));
+    _channelRules.push_back (Classifier ("ry",    LOSSY_DCT, FLOAT, -1, true));
+    _channelRules.push_back (Classifier ("a",     RLE,       UINT,  -1, true));
+    _channelRules.push_back (Classifier ("a",     RLE,       HALF,  -1, true));
+    _channelRules.push_back (Classifier ("a",     RLE,       FLOAT, -1, true));
+}
+
+
+// 
+// Given a set of rules and ChannelData, figure out which rules apply
+//
+
+void
+DwaCompressor::relevantChannelRules (std::vector<Classifier> &rules) const 
+{
+    rules.clear();
+
+    std::vector<std::string> suffixes;
+    
+    for (size_t cd = 0; cd < _channelData.size(); ++cd) 
+    {
+        std::string suffix  = _channelData[cd].name;
+        size_t      lastDot = suffix.find_last_of ('.');
+
+        if (lastDot != std::string::npos)
+            suffix = suffix.substr (lastDot+1, std::string::npos);
+
+        suffixes.push_back(suffix);
+    }
+
+    
+    for (size_t i = 0; i < _channelRules.size(); ++i) 
+    {
+        for (size_t cd = 0; cd < _channelData.size(); ++cd) 
+        {
+            if (_channelRules[i].match (suffixes[cd], _channelData[cd].type ))
+            {
+                rules.push_back (_channelRules[i]);
+                break;
+            }
+        }       
+    }
+}
+
+
+//
+// Take our initial list of channels, and cache the contents.
+//
+// Determine approprate compression schemes for each channel,
+// and figure out which sets should potentially be CSC'ed 
+// prior to lossy compression.
+//
+
+void
+DwaCompressor::classifyChannels
+    (ChannelList channels,
+     std::vector<ChannelData> &chanData,
+     std::vector<CscChannelSet> &cscData)
+{
+    //
+    // prefixMap used to map channel name prefixes to 
+    // potential CSC-able sets of channels.
+    //
+
+    std::map<std::string, DwaCompressor::CscChannelSet> prefixMap;
+    std::vector<DwaCompressor::CscChannelSet>           tmpCscSet;
+
+    unsigned int numChan = 0;
+
+    for (ChannelList::Iterator c = channels.begin(); c != channels.end(); ++c)
+        numChan++;
+    
+    if (numChan)
+        chanData.resize (numChan);
+
+    //
+    // Cache the relevant data from the channel structs.
+    //
+
+    unsigned int offset = 0;
+
+    for (ChannelList::Iterator c = channels.begin(); c != channels.end(); ++c)
+    {
+        chanData[offset].name        = std::string (c.name());
+        chanData[offset].compression = UNKNOWN;
+        chanData[offset].xSampling   = c.channel().xSampling;
+        chanData[offset].ySampling   = c.channel().ySampling;
+        chanData[offset].type        = c.channel().type;
+        chanData[offset].pLinear     = c.channel().pLinear;
+
+        offset++;
+    }
+
+    //
+    // Try and figure out which channels should be
+    // compressed by which means.
+    //
+
+    for (offset = 0; offset<numChan; ++offset)
+    {
+        std::string prefix  = "";
+        std::string suffix  = chanData[offset].name;
+        size_t      lastDot = suffix.find_last_of ('.');
+
+        if (lastDot != std::string::npos)
+        {
+            prefix = suffix.substr (0,         lastDot);
+            suffix = suffix.substr (lastDot+1, std::string::npos);
+        } 
+
+        //
+        // Make sure we have an entry in our CSC set map 
+        //
+
+        std::map<std::string, DwaCompressor::CscChannelSet>::iterator 
+            theSet = prefixMap.find (prefix);
+
+        if (theSet == prefixMap.end())
+        {
+            DwaCompressor::CscChannelSet tmpSet;
+
+            tmpSet.idx[0] = 
+            tmpSet.idx[1] = 
+            tmpSet.idx[2] = -1;
+
+            prefixMap[prefix] = tmpSet;
+        }
+
+        // 
+        // Check the suffix against the list of classifications
+        // we defined previously. If the _cscIdx is not negative,
+        // it indicates that we should be part of a CSC group.
+        //
+
+        for (std::vector<Classifier>::iterator i = _channelRules.begin();
+             i != _channelRules.end();
+             ++i)
+        {
+            if ( i->match(suffix, chanData[offset].type) )
+            {
+                chanData[offset].compression = i->_scheme;
+
+                if ( i->_cscIdx >= 0)
+                    prefixMap[prefix].idx[i->_cscIdx] = offset;
+            }
+        }
+    }
+
+    //
+    // Finally, try and find RGB sets of channels which 
+    // can be CSC'ed to a Y'CbCr space prior to loss, for
+    // better compression.
+    //
+    // Walk over our set of candidates, and see who has
+    // all three channels defined (and has common sampling
+    // patterns, etc).
+    //
+
+    for (std::map<std::string, DwaCompressor::CscChannelSet>::iterator 
+         theItem = prefixMap.begin(); theItem != prefixMap.end();
+         ++theItem)
+    {
+        int red = (*theItem).second.idx[0];
+        int grn = (*theItem).second.idx[1];
+        int blu = (*theItem).second.idx[2];
+
+        if ((red < 0) || (grn < 0) || (blu < 0))
+            continue;
+
+        if ((chanData[red].xSampling != chanData[grn].xSampling) ||
+            (chanData[red].xSampling != chanData[blu].xSampling) ||
+            (chanData[grn].xSampling != chanData[blu].xSampling) ||
+            (chanData[red].ySampling != chanData[grn].ySampling) ||
+            (chanData[red].ySampling != chanData[blu].ySampling) ||
+            (chanData[grn].ySampling != chanData[blu].ySampling))
+        {
+            continue;
+        }
+        
+        tmpCscSet.push_back ((*theItem).second);
+    }
+    
+    size_t numCsc = tmpCscSet.size();
+
+    if (numCsc)
+        cscData.resize(numCsc);
+
+    for (offset = 0; offset < numCsc; ++offset)
+        cscData[offset] = tmpCscSet[offset];
+}
+
+
+
+//
+// Setup some buffer pointers, determine channel sizes, things
+// like that.
+//
+
+void
+DwaCompressor::setupChannelData (int minX, int minY, int maxX, int maxY)
+{
+    char *planarUncBuffer[NUM_COMPRESSOR_SCHEMES];
+
+    for (int i=0; i<NUM_COMPRESSOR_SCHEMES; ++i)
+    {
+        planarUncBuffer[i] = 0;
+
+        if (_planarUncBuffer[i])
+            planarUncBuffer[i] =  _planarUncBuffer[i];
+    }
+
+    for (unsigned int chan = 0; chan < _channelData.size(); ++chan)
+    {
+        ChannelData *cd = &_channelData[chan];
+
+        cd->width  = OPENEXR_IMF_NAMESPACE::numSamples (cd->xSampling, minX, maxX);
+        cd->height = OPENEXR_IMF_NAMESPACE::numSamples (cd->ySampling, minY, maxY);
+                                
+        cd->planarUncSize =
+            cd->width * cd->height * OPENEXR_IMF_NAMESPACE::pixelTypeSize (cd->type);
+                                  
+        cd->planarUncBuffer    = planarUncBuffer[cd->compression];
+        cd->planarUncBufferEnd = cd->planarUncBuffer;
+
+        cd->planarUncRle[0]    = cd->planarUncBuffer;
+        cd->planarUncRleEnd[0] = cd->planarUncRle[0];
+
+        for (int byte = 1; byte < OPENEXR_IMF_NAMESPACE::pixelTypeSize(cd->type); ++byte)
+        {
+            cd->planarUncRle[byte] = 
+                         cd->planarUncRle[byte-1] + cd->width * cd->height;
+
+            cd->planarUncRleEnd[byte] =
+                         cd->planarUncRle[byte];
+        }
+
+        cd->planarUncType = cd->type;
+
+        if (cd->compression == LOSSY_DCT)
+        {
+            cd->planarUncType = FLOAT;
+        }
+        else
+        {
+            planarUncBuffer[cd->compression] +=
+                cd->width * cd->height * OPENEXR_IMF_NAMESPACE::pixelTypeSize (cd->planarUncType);
+        }
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfDwaCompressor.h b/3rdparty/openexr/IlmImf/ImfDwaCompressor.h
new file mode 100644 (file)
index 0000000..421490e
--- /dev/null
@@ -0,0 +1,219 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_DWA_COMRESSOR_H
+#define INCLUDED_IMF_DWA_COMRESSOR_H
+
+//------------------------------------------------------------------------------
+//
+// class DwaCompressor -- Store lossy RGB data by quantizing DCT components.
+//
+//------------------------------------------------------------------------------
+
+#include <vector>
+#include <half.h>
+
+#include "ImfInt64.h"
+#include "ImfZip.h"
+#include "ImfChannelList.h"
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class DwaCompressor: public Compressor
+{
+  public:
+
+    enum AcCompression 
+    {
+        STATIC_HUFFMAN,
+        DEFLATE,
+    };
+
+
+    IMF_EXPORT
+    DwaCompressor (const Header &hdr, 
+                   int           maxScanLineSize,
+                   int           numScanLines,    // ideally is a multiple of 8
+                   AcCompression acCompression);
+
+    IMF_EXPORT
+    virtual ~DwaCompressor ();
+
+    IMF_EXPORT
+    virtual int numScanLines () const;
+
+    IMF_EXPORT
+    virtual OPENEXR_IMF_NAMESPACE::Compressor::Format format () const;
+
+    IMF_EXPORT
+    virtual int compress (const char *inPtr,
+                          int         inSize,
+                          int         minY,
+                          const char *&outPtr);
+
+    IMF_EXPORT
+    virtual int compressTile (const char              *inPtr,
+                              int                     inSize,
+                              IMATH_NAMESPACE::Box2i  range,
+                              const char              *&outPtr);
+
+    IMF_EXPORT
+    virtual int uncompress (const char *inPtr,
+                            int         inSize,
+                            int         minY,
+                            const char *&outPtr);
+
+    IMF_EXPORT
+    virtual int uncompressTile (const char             *inPtr,
+                                int                    inSize,
+                                IMATH_NAMESPACE::Box2i range,
+                                const char             *&outPtr);
+
+    IMF_EXPORT
+    static void initializeFuncs ();
+
+  private:
+
+    struct ChannelData;
+    struct CscChannelSet;
+    struct Classifier;
+    
+    class LossyDctDecoderBase;
+    class LossyDctDecoder;
+    class LossyDctDecoderCsc;
+
+    class LossyDctEncoderBase;
+    class LossyDctEncoder;
+    class LossyDctEncoderCsc;
+
+    enum CompressorScheme 
+    {
+        UNKNOWN = 0,
+        LOSSY_DCT,
+        RLE,
+        
+        NUM_COMPRESSOR_SCHEMES
+    };
+
+    //
+    // Per-chunk compressed data sizes, one value per chunk
+    //
+
+    enum DataSizesSingle 
+    {
+        VERSION = 0,                  // Version number:
+                                      //   0: classic
+                                      //   1: adds "end of block" to the AC RLE
+
+        UNKNOWN_UNCOMPRESSED_SIZE,    // Size of leftover data, uncompressed.
+        UNKNOWN_COMPRESSED_SIZE,      // Size of leftover data, zlib compressed.
+
+        AC_COMPRESSED_SIZE,           // AC RLE + Huffman size
+        DC_COMPRESSED_SIZE,           // DC + Deflate size
+        RLE_COMPRESSED_SIZE,          // RLE + Deflate data size
+        RLE_UNCOMPRESSED_SIZE,        // RLE'd data size 
+        RLE_RAW_SIZE,                 // Un-RLE'd data size
+
+        AC_UNCOMPRESSED_COUNT,        // AC RLE number of elements
+        DC_UNCOMPRESSED_COUNT,        // DC number of elements
+
+        AC_COMPRESSION,               // AC compression strategy
+        NUM_SIZES_SINGLE
+    };
+
+    AcCompression     _acCompression;
+
+    int               _maxScanLineSize;
+    int               _numScanLines;
+    int               _min[2], _max[2];
+
+    ChannelList                _channels;
+    std::vector<ChannelData>   _channelData;
+    std::vector<CscChannelSet> _cscSets;
+    std::vector<Classifier>    _channelRules;
+
+    char             *_packedAcBuffer;
+    size_t            _packedAcBufferSize;
+    char             *_packedDcBuffer;
+    size_t            _packedDcBufferSize;
+    char             *_rleBuffer;
+    size_t            _rleBufferSize;
+    char             *_outBuffer;
+    size_t            _outBufferSize;
+    char             *_planarUncBuffer[NUM_COMPRESSOR_SCHEMES];
+    size_t            _planarUncBufferSize[NUM_COMPRESSOR_SCHEMES];
+
+    Zip              *_zip;
+    float             _dwaCompressionLevel;
+
+    int compress (const char              *inPtr,
+                  int                     inSize,
+                  IMATH_NAMESPACE::Box2i  range,
+                  const char              *&outPtr);
+
+    int uncompress (const char             *inPtr,
+                    int                    inSize,
+                    IMATH_NAMESPACE::Box2i range,
+                    const char             *&outPtr);
+
+    void initializeBuffers (size_t&);
+    void initializeDefaultChannelRules ();
+    void initializeLegacyChannelRules ();
+
+    void relevantChannelRules( std::vector<Classifier> &) const;
+
+    //
+    // Populate our cached version of the channel data with
+    // data from the real channel list. We want to 
+    // copy over attributes, determine compression schemes
+    // releveant for the channel type, and find sets of
+    // channels to be compressed from Y'CbCr data instead 
+    // of R'G'B'.
+    //
+
+    void classifyChannels (ChannelList                  channels,
+                           std::vector<ChannelData>    &chanData, 
+                           std::vector<CscChannelSet>  &cscData);
+
+    // 
+    // Compute various buffer pointers for each channel
+    //
+
+    void setupChannelData (int minX, int minY, int maxX, int maxY);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif 
diff --git a/3rdparty/openexr/IlmImf/ImfDwaCompressorSimd.h b/3rdparty/openexr/IlmImf/ImfDwaCompressorSimd.h
new file mode 100644 (file)
index 0000000..c14ae7a
--- /dev/null
@@ -0,0 +1,2172 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMF_DWACOMPRESSORSIMD_H_HAS_BEEN_INCLUDED
+#define IMF_DWACOMPRESSORSIMD_H_HAS_BEEN_INCLUDED
+
+//
+// Various SSE accelerated functions, used by Imf::DwaCompressor. 
+// These have been separated into a separate .h file, as the fast
+// paths are done with template specialization.
+//
+// Unless otherwise noted, all pointers are assumed to be 32-byte 
+// aligned. Unaligned pointers may risk seg-faulting.
+//
+
+#include "ImfNamespace.h"
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include "OpenEXRConfig.h"
+
+#include <half.h>
+#include <assert.h>
+
+#include <algorithm>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+#define _SSE_ALIGNMENT        32
+#define _SSE_ALIGNMENT_MASK 0x0F
+#define _AVX_ALIGNMENT_MASK 0x1F
+
+//
+// Test if we should enable GCC inline asm paths for AVX
+//
+
+#ifdef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX 
+
+    #define IMF_HAVE_GCC_INLINEASM
+
+    #ifdef __LP64__
+        #define IMF_HAVE_GCC_INLINEASM_64
+    #endif /* __LP64__ */
+
+#endif /* OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX */
+
+//
+// A simple 64-element array, aligned properly for SIMD access. 
+//
+
+template <class T>
+class SimdAlignedBuffer64
+{
+    public:
+
+        SimdAlignedBuffer64(): _buffer (0), _handle (0)           
+        {
+            alloc();
+        }
+
+        SimdAlignedBuffer64(const SimdAlignedBuffer64 &rhs): _handle(0)
+        {
+            alloc();
+            memcpy (_buffer, rhs._buffer, 64 * sizeof (T));
+        }
+
+        SimdAlignedBuffer64 &operator=(const SimdAlignedBuffer64 &rhs)
+        {
+            memcpy (_buffer, rhs._buffer, 64 * sizeof (T));
+            return *this;
+        }
+
+#if __cplusplus >= 201103L
+        SimdAlignedBuffer64(SimdAlignedBuffer64 &&rhs) noexcept
+            : _handle(rhs._handle), _buffer(rhs._buffer)
+        {
+            rhs._handle = nullptr;
+            rhs._buffer = nullptr;
+        }
+
+        SimdAlignedBuffer64 &operator=(SimdAlignedBuffer64 &&rhs) noexcept
+        {
+            std::swap(_handle, rhs._handle);
+            std::swap(_buffer, rhs._buffer);
+            return *this;
+        }
+#endif
+        ~SimdAlignedBuffer64 ()
+        {
+            if (_handle)
+                EXRFreeAligned (_handle);
+            _handle = 0;
+            _buffer = 0;
+        }
+
+        void alloc()
+        {
+            //
+            // Try EXRAllocAligned first - but it might fallback to
+            // unaligned allocs. If so, overalloc.
+            //
+
+            _handle = (char *) EXRAllocAligned
+                (64 * sizeof(T), _SSE_ALIGNMENT);
+
+            if (((size_t)_handle & (_SSE_ALIGNMENT - 1)) == 0)
+            {
+                _buffer = (T *)_handle;
+                return;
+            }
+
+            EXRFreeAligned(_handle);
+            _handle = (char *) EXRAllocAligned
+                (64 * sizeof(T) + _SSE_ALIGNMENT, _SSE_ALIGNMENT);
+
+            char *aligned = _handle;
+
+            while ((size_t)aligned & (_SSE_ALIGNMENT - 1))
+                aligned++;
+
+            _buffer = (T *)aligned;    
+        }
+
+        T     *_buffer;
+
+    private:
+
+        char  *_handle;
+};
+
+typedef SimdAlignedBuffer64<float>          SimdAlignedBuffer64f;
+typedef SimdAlignedBuffer64<unsigned short> SimdAlignedBuffer64us;
+
+namespace {
+
+//
+// Color space conversion, Inverse 709 CSC, Y'CbCr -> R'G'B'
+//
+
+void
+csc709Inverse (float &comp0, float &comp1, float &comp2)
+{
+    float src[3];
+
+    src[0] = comp0;
+    src[1] = comp1;
+    src[2] = comp2;
+
+    comp0 = src[0]                    + 1.5747f * src[2];
+    comp1 = src[0] - 0.1873f * src[1] - 0.4682f * src[2];
+    comp2 = src[0] + 1.8556f * src[1];
+}
+
+#ifndef IMF_HAVE_SSE2
+
+
+//
+// Scalar color space conversion, based on 709 primiary chromaticies.
+// No scaling or offsets, just the matrix
+//
+
+void
+csc709Inverse64 (float *comp0, float *comp1, float *comp2)
+{
+    for (int i = 0; i < 64; ++i)
+        csc709Inverse (comp0[i], comp1[i], comp2[i]);
+}
+
+#else /* IMF_HAVE_SSE2 */
+
+//
+// SSE2 color space conversion
+//
+
+void
+csc709Inverse64 (float *comp0, float *comp1, float *comp2)
+{
+    __m128 c0 = { 1.5747f,  1.5747f,  1.5747f,  1.5747f};
+    __m128 c1 = { 1.8556f,  1.8556f,  1.8556f,  1.8556f};
+    __m128 c2 = {-0.1873f, -0.1873f, -0.1873f, -0.1873f};
+    __m128 c3 = {-0.4682f, -0.4682f, -0.4682f, -0.4682f}; 
+
+    __m128 *r = (__m128 *)comp0;
+    __m128 *g = (__m128 *)comp1;
+    __m128 *b = (__m128 *)comp2;
+    __m128 src[3];
+
+    #define CSC_INVERSE_709_SSE2_LOOP(i)                       \
+            src[0] = r[i];                                     \
+            src[1] = g[i];                                     \
+            src[2] = b[i];                                     \
+                                                               \
+            r[i] = _mm_add_ps (r[i], _mm_mul_ps (src[2], c0)); \
+                                                               \
+            g[i]   = _mm_mul_ps (g[i], c2);                    \
+            src[2] = _mm_mul_ps (src[2], c3);                  \
+            g[i]   = _mm_add_ps (g[i], src[0]);                \
+            g[i]   = _mm_add_ps (g[i], src[2]);                \
+                                                               \
+            b[i] = _mm_mul_ps (c1,   src[1]);                  \
+            b[i] = _mm_add_ps (b[i], src[0]);
+
+    CSC_INVERSE_709_SSE2_LOOP (0)
+    CSC_INVERSE_709_SSE2_LOOP (1)
+    CSC_INVERSE_709_SSE2_LOOP (2)
+    CSC_INVERSE_709_SSE2_LOOP (3)
+
+    CSC_INVERSE_709_SSE2_LOOP (4)
+    CSC_INVERSE_709_SSE2_LOOP (5)
+    CSC_INVERSE_709_SSE2_LOOP (6)
+    CSC_INVERSE_709_SSE2_LOOP (7)
+
+    CSC_INVERSE_709_SSE2_LOOP (8)
+    CSC_INVERSE_709_SSE2_LOOP (9)
+    CSC_INVERSE_709_SSE2_LOOP (10)
+    CSC_INVERSE_709_SSE2_LOOP (11)
+
+    CSC_INVERSE_709_SSE2_LOOP (12)
+    CSC_INVERSE_709_SSE2_LOOP (13)
+    CSC_INVERSE_709_SSE2_LOOP (14)
+    CSC_INVERSE_709_SSE2_LOOP (15)
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+
+//
+// Color space conversion, Forward 709 CSC, R'G'B' -> Y'CbCr
+//
+// Simple FPU color space conversion. Based on the 709
+// primary chromaticies, with no scaling or offsets.
+//
+
+void
+csc709Forward64 (float *comp0, float *comp1, float *comp2)
+{
+    float src[3];
+
+    for (int i = 0; i<64; ++i)
+    {
+        src[0] = comp0[i];    
+        src[1] = comp1[i]; 
+        src[2] = comp2[i];     
+
+        comp0[i] =  0.2126f * src[0] + 0.7152f * src[1] + 0.0722f * src[2];
+        comp1[i] = -0.1146f * src[0] - 0.3854f * src[1] + 0.5000f * src[2];
+        comp2[i] =  0.5000f * src[0] - 0.4542f * src[1] - 0.0458f * src[2];
+    }
+}
+
+
+//
+// Byte interleaving of 2 byte arrays:
+//    src0 = AAAA 
+//    src1 = BBBB
+//    dst  = ABABABAB
+//
+// numBytes is the size of each of the source buffers
+//
+
+#ifndef IMF_HAVE_SSE2 
+
+// 
+// Scalar default implementation 
+//
+
+void
+interleaveByte2 (char *dst, char *src0, char *src1, int numBytes)
+{
+    for (int x = 0; x < numBytes; ++x)
+    {
+        dst[2 * x]     = src0[x];
+        dst[2 * x + 1] = src1[x];
+    }
+}
+
+#else  /* IMF_HAVE_SSE2 */
+
+// 
+// SSE2 byte interleaving
+//
+
+void
+interleaveByte2 (char *dst, char *src0, char *src1, int numBytes)
+{
+    int dstAlignment  = (size_t)dst  % 16;
+    int src0Alignment = (size_t)src0 % 16;
+    int src1Alignment = (size_t)src1 % 16;
+
+    __m128i *dst_epi8  = (__m128i*)dst;
+    __m128i *src0_epi8 = (__m128i*)src0;
+    __m128i *src1_epi8 = (__m128i*)src1;
+    int sseWidth  =  numBytes / 16;
+
+    if ((!dstAlignment) && (!src0Alignment) && (!src1Alignment))
+    {
+        __m128i tmp0, tmp1;
+
+        //
+        // Aligned loads and stores
+        //
+
+        for (int x = 0; x < sseWidth; ++x)
+        {
+            tmp0 = src0_epi8[x];
+            tmp1 = src1_epi8[x];
+
+            _mm_stream_si128 (&dst_epi8[2 * x],
+                              _mm_unpacklo_epi8 (tmp0, tmp1));
+
+            _mm_stream_si128 (&dst_epi8[2 * x + 1],
+                              _mm_unpackhi_epi8 (tmp0, tmp1));
+        }
+
+        //
+        // Then do run the leftovers one at a time
+        //
+
+        for (int x = 16 * sseWidth; x < numBytes; ++x)
+        {
+            dst[2 * x]     = src0[x];
+            dst[2 * x + 1] = src1[x];
+        }
+    }
+    else if ((!dstAlignment) && (src0Alignment == 8) && (src1Alignment == 8))
+    {
+        //
+        // Aligned stores, but catch up a few values so we can 
+        // use aligned loads
+        //
+    
+        for (int x = 0; x < std::min (numBytes, 8); ++x)
+        {
+            dst[2 * x]     = src0[x];
+            dst[2 * x + 1] = src1[x];
+        }
+
+        if (numBytes > 8) 
+        {
+            dst_epi8  = (__m128i*)&dst[16];
+            src0_epi8 = (__m128i*)&src0[8];
+            src1_epi8 = (__m128i*)&src1[8];
+            sseWidth  =  (numBytes - 8) / 16;
+
+            for (int x=0; x<sseWidth; ++x)
+            {
+                _mm_stream_si128 (&dst_epi8[2 * x],
+                                  _mm_unpacklo_epi8 (src0_epi8[x], src1_epi8[x]));
+
+                _mm_stream_si128 (&dst_epi8[2 * x + 1],
+                                  _mm_unpackhi_epi8 (src0_epi8[x], src1_epi8[x]));
+            }
+
+            //
+            // Then do run the leftovers one at a time
+            //
+
+            for (int x = 16 * sseWidth + 8; x < numBytes; ++x)
+            {
+                dst[2 * x]     = src0[x];
+                dst[2 * x + 1] = src1[x];
+            }
+        }
+    }
+    else
+    {
+        //
+        // Unaligned everything
+        //
+
+        for (int x = 0; x < sseWidth; ++x)
+        {
+            __m128i tmpSrc0_epi8 = _mm_loadu_si128 (&src0_epi8[x]);
+            __m128i tmpSrc1_epi8 = _mm_loadu_si128 (&src1_epi8[x]);
+
+            _mm_storeu_si128 (&dst_epi8[2 * x],
+                              _mm_unpacklo_epi8 (tmpSrc0_epi8, tmpSrc1_epi8));
+
+            _mm_storeu_si128 (&dst_epi8[2 * x + 1],
+                              _mm_unpackhi_epi8 (tmpSrc0_epi8, tmpSrc1_epi8));
+        }
+
+        //
+        // Then do run the leftovers one at a time
+        //
+
+        for (int x = 16 * sseWidth; x < numBytes; ++x)
+        {
+            dst[2 * x]     = src0[x];
+            dst[2 * x + 1] = src1[x];
+        }
+    }
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+
+//
+// Float -> half float conversion
+//
+// To enable F16C based conversion, we can't rely on compile-time
+// detection, hence the multiple defined versions. Pick one based
+// on runtime cpuid detection.
+//
+
+//
+// Default boring conversion
+//
+
+void 
+convertFloatToHalf64_scalar (unsigned short *dst, float *src)
+{
+    for (int i=0; i<64; ++i)
+        dst[i] = ((half)src[i]).bits();
+}
+
+
+//
+// F16C conversion - Assumes aligned src and dst
+//
+
+void
+convertFloatToHalf64_f16c (unsigned short *dst, float *src)
+{
+    //
+    // Ordinarly, I'd avoid using inline asm and prefer intrinsics. 
+    // However, in order to get the intrinsics, we need to tell 
+    // the compiler to generate VEX instructions.
+    //
+    // (On the GCC side, -mf16c goes ahead and activates -mavc,
+    //  resulting in VEX code. Without -mf16c, no intrinsics..)
+    //
+    // Now, it's quite likely that we'll find ourselves in situations
+    // where we want to build *without* VEX, in order to maintain
+    // maximum compatability. But to get there with intrinsics,
+    // we'd need to break out code into a separate file. Bleh.
+    // I'll take the asm.
+    //
+
+    #if defined IMF_HAVE_GCC_INLINEASM
+        __asm__
+           ("vmovaps       (%0),     %%ymm0         \n"
+            "vmovaps   0x20(%0),     %%ymm1         \n"
+            "vmovaps   0x40(%0),     %%ymm2         \n"
+            "vmovaps   0x60(%0),     %%ymm3         \n"
+            "vcvtps2ph $0,           %%ymm0, %%xmm0 \n"
+            "vcvtps2ph $0,           %%ymm1, %%xmm1 \n"
+            "vcvtps2ph $0,           %%ymm2, %%xmm2 \n"
+            "vcvtps2ph $0,           %%ymm3, %%xmm3 \n"
+            "vmovdqa   %%xmm0,       0x00(%1)       \n"
+            "vmovdqa   %%xmm1,       0x10(%1)       \n"
+            "vmovdqa   %%xmm2,       0x20(%1)       \n"
+            "vmovdqa   %%xmm3,       0x30(%1)       \n"
+            "vmovaps   0x80(%0),     %%ymm0         \n"
+            "vmovaps   0xa0(%0),     %%ymm1         \n"
+            "vmovaps   0xc0(%0),     %%ymm2         \n"
+            "vmovaps   0xe0(%0),     %%ymm3         \n"
+            "vcvtps2ph $0,           %%ymm0, %%xmm0 \n"
+            "vcvtps2ph $0,           %%ymm1, %%xmm1 \n"
+            "vcvtps2ph $0,           %%ymm2, %%xmm2 \n"
+            "vcvtps2ph $0,           %%ymm3, %%xmm3 \n"
+            "vmovdqa   %%xmm0,       0x40(%1)       \n"
+            "vmovdqa   %%xmm1,       0x50(%1)       \n"
+            "vmovdqa   %%xmm2,       0x60(%1)       \n"
+            "vmovdqa   %%xmm3,       0x70(%1)       \n"
+        #ifndef __AVX__
+            "vzeroupper                             \n"
+        #endif /* __AVX__ */
+            : /* Output  */                
+            : /* Input   */ "r"(src), "r"(dst)
+        #ifndef __AVX__
+            : /* Clobber */ "%xmm0", "%xmm1", "%xmm2", "%xmm3", "memory"
+        #else
+            : /* Clobber */ "%ymm0", "%ymm1", "%ymm2", "%ymm3", "memory"
+        #endif /* __AVX__ */
+           );
+    #else
+        convertFloatToHalf64_scalar (dst, src);
+    #endif /* IMF_HAVE_GCC_INLINEASM */
+}
+
+
+//
+// Convert an 8x8 block of HALF from zig-zag order to
+// FLOAT in normal order. The order we want is:
+//
+//          src                           dst 
+//  0  1  2  3  4  5  6  7       0  1  5  6 14 15 27 28
+//  8  9 10 11 12 13 14 15       2  4  7 13 16 26 29 42
+// 16 17 18 19 20 21 22 23       3  8 12 17 25 30 41 43
+// 24 25 26 27 28 29 30 31       9 11 18 24 31 40 44 53  
+// 32 33 34 35 36 37 38 39      10 19 23 32 39 45 52 54
+// 40 41 42 43 44 45 46 47      20 22 33 38 46 51 55 60
+// 48 49 50 51 52 53 54 55      21 34 37 47 50 56 59 61
+// 56 57 58 59 60 61 62 63      35 36 48 49 57 58 62 63
+//
+
+void
+fromHalfZigZag_scalar (unsigned short *src, float *dst)
+{
+    half *srcHalf = (half *)src;
+
+    dst[0] = (float)srcHalf[0];
+    dst[1] = (float)srcHalf[1];
+    dst[2] = (float)srcHalf[5];
+    dst[3] = (float)srcHalf[6];
+    dst[4] = (float)srcHalf[14];
+    dst[5] = (float)srcHalf[15];
+    dst[6] = (float)srcHalf[27];
+    dst[7] = (float)srcHalf[28];
+    dst[8] = (float)srcHalf[2];
+    dst[9] = (float)srcHalf[4];
+
+    dst[10] = (float)srcHalf[7];
+    dst[11] = (float)srcHalf[13];
+    dst[12] = (float)srcHalf[16];
+    dst[13] = (float)srcHalf[26];
+    dst[14] = (float)srcHalf[29];
+    dst[15] = (float)srcHalf[42];
+    dst[16] = (float)srcHalf[3];
+    dst[17] = (float)srcHalf[8];
+    dst[18] = (float)srcHalf[12];
+    dst[19] = (float)srcHalf[17];
+
+    dst[20] = (float)srcHalf[25];
+    dst[21] = (float)srcHalf[30];
+    dst[22] = (float)srcHalf[41];
+    dst[23] = (float)srcHalf[43];
+    dst[24] = (float)srcHalf[9];
+    dst[25] = (float)srcHalf[11];
+    dst[26] = (float)srcHalf[18];
+    dst[27] = (float)srcHalf[24];
+    dst[28] = (float)srcHalf[31];
+    dst[29] = (float)srcHalf[40];
+
+    dst[30] = (float)srcHalf[44];
+    dst[31] = (float)srcHalf[53];
+    dst[32] = (float)srcHalf[10];
+    dst[33] = (float)srcHalf[19];
+    dst[34] = (float)srcHalf[23];
+    dst[35] = (float)srcHalf[32];
+    dst[36] = (float)srcHalf[39];
+    dst[37] = (float)srcHalf[45];
+    dst[38] = (float)srcHalf[52];
+    dst[39] = (float)srcHalf[54];
+
+    dst[40] = (float)srcHalf[20];
+    dst[41] = (float)srcHalf[22];
+    dst[42] = (float)srcHalf[33];
+    dst[43] = (float)srcHalf[38];
+    dst[44] = (float)srcHalf[46];
+    dst[45] = (float)srcHalf[51];
+    dst[46] = (float)srcHalf[55];
+    dst[47] = (float)srcHalf[60];
+    dst[48] = (float)srcHalf[21];
+    dst[49] = (float)srcHalf[34];
+
+    dst[50] = (float)srcHalf[37];
+    dst[51] = (float)srcHalf[47];
+    dst[52] = (float)srcHalf[50];
+    dst[53] = (float)srcHalf[56];
+    dst[54] = (float)srcHalf[59];
+    dst[55] = (float)srcHalf[61];
+    dst[56] = (float)srcHalf[35];
+    dst[57] = (float)srcHalf[36];
+    dst[58] = (float)srcHalf[48];
+    dst[59] = (float)srcHalf[49];
+
+    dst[60] = (float)srcHalf[57];
+    dst[61] = (float)srcHalf[58];
+    dst[62] = (float)srcHalf[62];
+    dst[63] = (float)srcHalf[63];
+}
+
+
+//
+// If we can form the correct ordering in xmm registers,
+// we can use F16C to convert from HALF -> FLOAT. However,
+// making the correct order isn't trivial. 
+// 
+// We want to re-order a source 8x8 matrix from:
+//
+//  0  1  2  3  4  5  6  7       0  1  5  6 14 15 27 28
+//  8  9 10 11 12 13 14 15       2  4  7 13 16 26 29 42
+// 16 17 18 19 20 21 22 23       3  8 12 17 25 30 41 43
+// 24 25 26 27 28 29 30 31       9 11 18 24 31 40 44 53   (A)
+// 32 33 34 35 36 37 38 39  --> 10 19 23 32 39 45 52 54
+// 40 41 42 43 44 45 46 47      20 22 33 38 46 51 55 60
+// 48 49 50 51 52 53 54 55      21 34 37 47 50 56 59 61
+// 56 57 58 59 60 61 62 63      35 36 48 49 57 58 62 63
+//
+// Which looks like a mess, right? 
+//
+// Now, check out the NE/SW diagonals of (A). Along those lines, 
+// we have runs of contiguous values! If we rewrite (A) a bit, we get:
+//
+//  0
+//  1  2
+//  5  4  3
+//  6  7  8  9
+// 14 13 12 11 10
+// 15 16 17 18 19 20
+// 27 26 25 24 23 22 21            (B)
+// 28 29 30 31 32 33 34 35
+//    42 41 40 39 38 37 36
+//       43 44 45 46 47 48
+//          53 52 51 50 49
+//             54 55 56 57
+//                60 59 58
+//                   61 62
+//                      63
+//
+// In this ordering, the columns are the rows (A). If we can 'transpose' 
+// (B), we'll achieve our goal. But we want this to fit nicely into 
+// xmm registers and still be able to load large runs efficiently.  
+// Also, notice that the odd rows are in ascending order, while 
+// the even rows are in descending order. 
+//
+// If we 'fold' the bottom half up into the top, we can preserve ordered
+// runs accross rows, and still keep all the correct values in columns. 
+// After transposing, we'll need to rotate things back into place. 
+// This gives us:
+//
+//  0 | 42   41   40   39   38   37   36
+//  1    2 | 43   44   45   46   47   48
+//  5    4    3 | 53   52   51   50   49
+//  6    7    8    9 | 54   55   56   57      (C)
+// 14   13   12   11   10 | 60   59   58
+// 15   16   17   18   19   20 | 61   62
+// 27   26   25   24   23   22   21 | 61
+// 28   29   30   31   32   33   34   35
+//
+// But hang on. We still have the backwards descending rows to deal with.
+// Lets reverse the even rows so that all values are in ascending order
+//
+//  36   37  38   39   40   41   42 | 0
+//  1    2 | 43   44   45   46   47   48
+//  49   50  51   52   53 |  3    4    5  
+//  6    7    8    9 | 54   55   56   57      (D)
+// 58   59   60 | 10   11   12   13   14  
+// 15   16   17   18   19   20 | 61   62
+// 61 | 21   22   23   24   25   26   27 
+// 28   29   30   31   32   33   34   35
+//
+// If we can form (D),  we will then:
+//   1) Reverse the even rows
+//   2) Transpose
+//   3) Rotate the rows 
+//
+// and we'll have (A).
+//
+
+void 
+fromHalfZigZag_f16c (unsigned short *src, float *dst)
+{
+    #if defined IMF_HAVE_GCC_INLINEASM_64
+        __asm__
+
+           /* x3 <- 0                    
+            * x8 <- [ 0- 7]              
+            * x6 <- [56-63]              
+            * x9 <- [21-28]              
+            * x7 <- [28-35]              
+            * x3 <- [ 6- 9] (lower half) */
+          
+          ("vpxor   %%xmm3,  %%xmm3, %%xmm3   \n"
+           "vmovdqa    (%0), %%xmm8           \n"
+           "vmovdqa 112(%0), %%xmm6           \n"
+           "vmovdqu  42(%0), %%xmm9           \n"
+           "vmovdqu  56(%0), %%xmm7           \n"
+           "vmovq    12(%0), %%xmm3           \n"
+
+           /* Setup rows 0-2 of A in xmm0-xmm2 
+            * x1 <- x8 >> 16 (1 value)     
+            * x2 <- x8 << 32 (2 values)    
+            * x0 <- alignr([35-42], x8, 2) 
+            * x1 <- blend(x1, [41-48])     
+            * x2 <- blend(x2, [49-56])     */
+
+           "vpsrldq      $2, %%xmm8, %%xmm1   \n"      
+           "vpslldq      $4, %%xmm8, %%xmm2   \n"      
+           "vpalignr     $2, 70(%0), %%xmm8, %%xmm0 \n"
+           "vpblendw  $0xfc, 82(%0), %%xmm1, %%xmm1 \n"
+           "vpblendw  $0x1f, 98(%0), %%xmm2, %%xmm2 \n"
+     
+           /* Setup rows 4-6 of A in xmm4-xmm6 
+            * x4 <- x6 >> 32 (2 values)   
+            * x5 <- x6 << 16 (1 value)    
+            * x6 <- alignr(x6,x9,14)      
+            * x4 <- blend(x4, [ 7-14])    
+            * x5 <- blend(x5, [15-22])    */
+
+           "vpsrldq      $4, %%xmm6, %%xmm4         \n"
+           "vpslldq      $2, %%xmm6, %%xmm5         \n"
+           "vpalignr    $14, %%xmm6, %%xmm9, %%xmm6 \n"
+           "vpblendw  $0xf8, 14(%0), %%xmm4, %%xmm4 \n"
+           "vpblendw  $0x3f, 30(%0), %%xmm5, %%xmm5 \n"
+
+           /* Load the upper half of row 3 into xmm3 
+            * x3 <- [54-57] (upper half) */
+
+           "vpinsrq      $1, 108(%0), %%xmm3, %%xmm3\n"
+
+           /* Reverse the even rows. We're not using PSHUFB as
+            * that requires loading an extra constant all the time,
+            * and we're alreadly pretty memory bound.
+            */
+
+           "vpshuflw $0x1b, %%xmm0, %%xmm0          \n" 
+           "vpshuflw $0x1b, %%xmm2, %%xmm2          \n" 
+           "vpshuflw $0x1b, %%xmm4, %%xmm4          \n" 
+           "vpshuflw $0x1b, %%xmm6, %%xmm6          \n" 
+
+           "vpshufhw $0x1b, %%xmm0, %%xmm0          \n" 
+           "vpshufhw $0x1b, %%xmm2, %%xmm2          \n" 
+           "vpshufhw $0x1b, %%xmm4, %%xmm4          \n" 
+           "vpshufhw $0x1b, %%xmm6, %%xmm6          \n" 
+
+           "vpshufd $0x4e, %%xmm0, %%xmm0          \n" 
+           "vpshufd $0x4e, %%xmm2, %%xmm2          \n" 
+           "vpshufd $0x4e, %%xmm4, %%xmm4          \n" 
+           "vpshufd $0x4e, %%xmm6, %%xmm6          \n" 
+
+           /* Transpose xmm0-xmm7 into xmm8-xmm15 */
+
+           "vpunpcklwd %%xmm1, %%xmm0, %%xmm8       \n"
+           "vpunpcklwd %%xmm3, %%xmm2, %%xmm9       \n"
+           "vpunpcklwd %%xmm5, %%xmm4, %%xmm10      \n"
+           "vpunpcklwd %%xmm7, %%xmm6, %%xmm11      \n"
+           "vpunpckhwd %%xmm1, %%xmm0, %%xmm12      \n"
+           "vpunpckhwd %%xmm3, %%xmm2, %%xmm13      \n"
+           "vpunpckhwd %%xmm5, %%xmm4, %%xmm14      \n"
+           "vpunpckhwd %%xmm7, %%xmm6, %%xmm15      \n"
+     
+           "vpunpckldq  %%xmm9,  %%xmm8, %%xmm0     \n"
+           "vpunpckldq %%xmm11, %%xmm10, %%xmm1     \n"
+           "vpunpckhdq  %%xmm9,  %%xmm8, %%xmm2     \n"
+           "vpunpckhdq %%xmm11, %%xmm10, %%xmm3     \n"
+           "vpunpckldq %%xmm13, %%xmm12, %%xmm4     \n"
+           "vpunpckldq %%xmm15, %%xmm14, %%xmm5     \n"
+           "vpunpckhdq %%xmm13, %%xmm12, %%xmm6     \n"
+           "vpunpckhdq %%xmm15, %%xmm14, %%xmm7     \n"
+     
+           "vpunpcklqdq %%xmm1,  %%xmm0, %%xmm8     \n"
+           "vpunpckhqdq %%xmm1,  %%xmm0, %%xmm9     \n"
+           "vpunpcklqdq %%xmm3,  %%xmm2, %%xmm10    \n"
+           "vpunpckhqdq %%xmm3,  %%xmm2, %%xmm11    \n"
+           "vpunpcklqdq %%xmm4,  %%xmm5, %%xmm12    \n"
+           "vpunpckhqdq %%xmm5,  %%xmm4, %%xmm13    \n"
+           "vpunpcklqdq %%xmm7,  %%xmm6, %%xmm14    \n"
+           "vpunpckhqdq %%xmm7,  %%xmm6, %%xmm15    \n"
+
+           /* Rotate the rows to get the correct final order. 
+            * Rotating xmm12 isn't needed, as we can handle
+            * the rotation in the PUNPCKLQDQ above. Rotating
+            * xmm8 isn't needed as it's already in the right order           
+            */
+
+           "vpalignr  $2,  %%xmm9,  %%xmm9,  %%xmm9 \n"
+           "vpalignr  $4, %%xmm10, %%xmm10, %%xmm10 \n"
+           "vpalignr  $6, %%xmm11, %%xmm11, %%xmm11 \n"
+           "vpalignr $10, %%xmm13, %%xmm13, %%xmm13 \n"
+           "vpalignr $12, %%xmm14, %%xmm14, %%xmm14 \n"
+           "vpalignr $14, %%xmm15, %%xmm15, %%xmm15 \n"
+
+            /* Convert from half -> float */
+
+           "vcvtph2ps  %%xmm8, %%ymm8            \n"  
+           "vcvtph2ps  %%xmm9, %%ymm9            \n"
+           "vcvtph2ps %%xmm10, %%ymm10           \n"
+           "vcvtph2ps %%xmm11, %%ymm11           \n"
+           "vcvtph2ps %%xmm12, %%ymm12           \n"
+           "vcvtph2ps %%xmm13, %%ymm13           \n"
+           "vcvtph2ps %%xmm14, %%ymm14           \n"
+           "vcvtph2ps %%xmm15, %%ymm15           \n"
+           
+           /* Move float values to dst */
+
+           "vmovaps    %%ymm8,    (%1)           \n"
+           "vmovaps    %%ymm9,  32(%1)           \n"
+           "vmovaps   %%ymm10,  64(%1)           \n" 
+           "vmovaps   %%ymm11,  96(%1)           \n" 
+           "vmovaps   %%ymm12, 128(%1)           \n" 
+           "vmovaps   %%ymm13, 160(%1)           \n" 
+           "vmovaps   %%ymm14, 192(%1)           \n" 
+           "vmovaps   %%ymm15, 224(%1)           \n"
+        #ifndef __AVX__
+            "vzeroupper                          \n"
+        #endif /* __AVX__ */
+            : /* Output  */                
+            : /* Input   */ "r"(src), "r"(dst)
+            : /* Clobber */ "memory",
+        #ifndef __AVX__
+                            "%xmm0",  "%xmm1",  "%xmm2",  "%xmm3", 
+                            "%xmm4",  "%xmm5",  "%xmm6",  "%xmm7",
+                            "%xmm8",  "%xmm9",  "%xmm10", "%xmm11",
+                            "%xmm12", "%xmm13", "%xmm14", "%xmm15"
+        #else
+                            "%ymm0",  "%ymm1",  "%ymm2",  "%ymm3", 
+                            "%ymm4",  "%ymm5",  "%ymm6",  "%ymm7",
+                            "%ymm8",  "%ymm9",  "%ymm10", "%ymm11",
+                            "%ymm12", "%ymm13", "%ymm14", "%ymm15"
+        #endif /* __AVX__ */
+        );
+
+    #else
+        fromHalfZigZag_scalar(src, dst);
+    #endif /* defined IMF_HAVE_GCC_INLINEASM_64 */
+}
+
+
+//
+// Inverse 8x8 DCT, only inverting the DC. This assumes that
+// all AC frequencies are 0.
+//
+
+#ifndef IMF_HAVE_SSE2
+
+void 
+dctInverse8x8DcOnly (float *data)
+{
+    float val = data[0] * 3.535536e-01f * 3.535536e-01f;
+
+    for (int i = 0; i < 64; ++i)
+        data[i] = val;
+}
+
+#else  /* IMF_HAVE_SSE2 */
+
+void
+dctInverse8x8DcOnly (float *data)
+{
+    __m128 src = _mm_set1_ps (data[0] * 3.535536e-01f * 3.535536e-01f);
+    __m128 *dst = (__m128 *)data;
+
+    for (int i = 0; i < 16; ++i)
+        dst[i] = src;
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+
+//
+// Full 8x8 Inverse DCT:
+//
+// Simple inverse DCT on an 8x8 block, with scalar ops only.
+//  Operates on data in-place.
+//
+// This is based on the iDCT formuation (y = frequency domain,
+//                                       x = spatial domain)
+//
+//    [x0]    [        ][y0]    [        ][y1] 
+//    [x1] =  [  M1    ][y2]  + [  M2    ][y3] 
+//    [x2]    [        ][y4]    [        ][y5] 
+//    [x3]    [        ][y6]    [        ][y7]
+//
+//    [x7]    [        ][y0]    [        ][y1] 
+//    [x6] =  [  M1    ][y2]  - [  M2    ][y3] 
+//    [x5]    [        ][y4]    [        ][y5] 
+//    [x4]    [        ][y6]    [        ][y7]
+//
+// where M1:             M2:
+//
+//   [a  c  a   f]     [b  d  e  g]
+//   [a  f -a  -c]     [d -g -b -e]
+//   [a -f -a   c]     [e -b  g  d]
+//   [a -c  a  -f]     [g -e  d -b]
+//
+// and the constants are as defined below..
+//
+// If you know how many of the lower rows are zero, that can
+// be passed in to help speed things up. If you don't know, 
+// just set zeroedRows=0.
+//
+
+//
+// Default implementation
+//
+
+template <int zeroedRows>
+void
+dctInverse8x8_scalar (float *data)
+{
+    const float a = .5f * cosf (3.14159f / 4.0f);
+    const float b = .5f * cosf (3.14159f / 16.0f);
+    const float c = .5f * cosf (3.14159f / 8.0f);
+    const float d = .5f * cosf (3.f*3.14159f / 16.0f);
+    const float e = .5f * cosf (5.f*3.14159f / 16.0f);
+    const float f = .5f * cosf (3.f*3.14159f / 8.0f);
+    const float g = .5f * cosf (7.f*3.14159f / 16.0f);
+
+    float alpha[4], beta[4], theta[4], gamma[4];
+
+    float *rowPtr = NULL;
+
+    //
+    // First pass - row wise.
+    //
+    // This looks less-compact than the description above in
+    // an attempt to fold together common sub-expressions.
+    //
+
+    for (int row = 0; row < 8 - zeroedRows; ++row)
+    {
+        rowPtr = data + row * 8;
+
+        alpha[0] = c * rowPtr[2]; 
+        alpha[1] = f * rowPtr[2]; 
+        alpha[2] = c * rowPtr[6]; 
+        alpha[3] = f * rowPtr[6]; 
+
+        beta[0] = b * rowPtr[1] + d * rowPtr[3] + e * rowPtr[5] + g * rowPtr[7];
+        beta[1] = d * rowPtr[1] - g * rowPtr[3] - b * rowPtr[5] - e * rowPtr[7];
+        beta[2] = e * rowPtr[1] - b * rowPtr[3] + g * rowPtr[5] + d * rowPtr[7];
+        beta[3] = g * rowPtr[1] - e * rowPtr[3] + d * rowPtr[5] - b * rowPtr[7];
+
+        theta[0] = a * (rowPtr[0] + rowPtr[4]);
+        theta[3] = a * (rowPtr[0] - rowPtr[4]);
+
+        theta[1] = alpha[0] + alpha[3]; 
+        theta[2] = alpha[1] - alpha[2]; 
+
+
+        gamma[0] = theta[0] + theta[1];
+        gamma[1] = theta[3] + theta[2];
+        gamma[2] = theta[3] - theta[2];
+        gamma[3] = theta[0] - theta[1];
+
+
+        rowPtr[0] = gamma[0] + beta[0];
+        rowPtr[1] = gamma[1] + beta[1];
+        rowPtr[2] = gamma[2] + beta[2];
+        rowPtr[3] = gamma[3] + beta[3];
+
+        rowPtr[4] = gamma[3] - beta[3];
+        rowPtr[5] = gamma[2] - beta[2];
+        rowPtr[6] = gamma[1] - beta[1];
+        rowPtr[7] = gamma[0] - beta[0];
+    }
+
+    //
+    // Second pass - column wise.
+    //
+
+    for (int column = 0; column < 8; ++column)
+    {
+        alpha[0] = c * data[16+column]; 
+        alpha[1] = f * data[16+column]; 
+        alpha[2] = c * data[48+column]; 
+        alpha[3] = f * data[48+column]; 
+
+        beta[0] = b * data[8+column]  + d * data[24+column] +
+                  e * data[40+column] + g * data[56+column];
+
+        beta[1] = d * data[8+column]  - g * data[24+column] -
+                  b * data[40+column] - e * data[56+column];
+
+        beta[2] = e * data[8+column]  - b * data[24+column] + 
+                  g * data[40+column] + d * data[56+column];
+
+        beta[3] = g * data[8+column]  - e * data[24+column] + 
+                  d * data[40+column] - b * data[56+column];
+
+        theta[0] = a * (data[column] + data[32+column]);
+        theta[3] = a * (data[column] - data[32+column]);
+
+        theta[1] = alpha[0] + alpha[3]; 
+        theta[2] = alpha[1] - alpha[2]; 
+
+        gamma[0] = theta[0] + theta[1];
+        gamma[1] = theta[3] + theta[2];
+        gamma[2] = theta[3] - theta[2];
+        gamma[3] = theta[0] - theta[1];
+
+        data[     column] = gamma[0] + beta[0];
+        data[ 8 + column] = gamma[1] + beta[1];
+        data[16 + column] = gamma[2] + beta[2];
+        data[24 + column] = gamma[3] + beta[3];
+
+        data[32 + column] = gamma[3] - beta[3];
+        data[40 + column] = gamma[2] - beta[2];
+        data[48 + column] = gamma[1] - beta[1];
+        data[56 + column] = gamma[0] - beta[0];
+    }
+}
+
+
+//
+// SSE2 Implementation
+//
+
+template <int zeroedRows>
+void
+dctInverse8x8_sse2 (float *data)
+{
+    #ifdef IMF_HAVE_SSE2
+        __m128 a  = {3.535536e-01f,3.535536e-01f,3.535536e-01f,3.535536e-01f};
+        __m128 b  = {4.903927e-01f,4.903927e-01f,4.903927e-01f,4.903927e-01f};
+        __m128 c  = {4.619398e-01f,4.619398e-01f,4.619398e-01f,4.619398e-01f};
+        __m128 d  = {4.157349e-01f,4.157349e-01f,4.157349e-01f,4.157349e-01f};
+        __m128 e  = {2.777855e-01f,2.777855e-01f,2.777855e-01f,2.777855e-01f};
+        __m128 f  = {1.913422e-01f,1.913422e-01f,1.913422e-01f,1.913422e-01f};
+        __m128 g  = {9.754573e-02f,9.754573e-02f,9.754573e-02f,9.754573e-02f};
+
+        __m128 c0 = {3.535536e-01f, 3.535536e-01f, 3.535536e-01f, 3.535536e-01f};
+        __m128 c1 = {4.619398e-01f, 1.913422e-01f,-1.913422e-01f,-4.619398e-01f};
+        __m128 c2 = {3.535536e-01f,-3.535536e-01f,-3.535536e-01f, 3.535536e-01f};
+        __m128 c3 = {1.913422e-01f,-4.619398e-01f, 4.619398e-01f,-1.913422e-01f};
+
+        __m128 c4 = {4.903927e-01f, 4.157349e-01f, 2.777855e-01f, 9.754573e-02f};
+        __m128 c5 = {4.157349e-01f,-9.754573e-02f,-4.903927e-01f,-2.777855e-01f};
+        __m128 c6 = {2.777855e-01f,-4.903927e-01f, 9.754573e-02f, 4.157349e-01f};
+        __m128 c7 = {9.754573e-02f,-2.777855e-01f, 4.157349e-01f,-4.903927e-01f};
+
+        __m128 *srcVec = (__m128 *)data;
+        __m128 x[8], evenSum, oddSum;
+        __m128 in[8], alpha[4], beta[4], theta[4], gamma[4];
+        
+        //
+        // Rows -   
+        //
+        //  Treat this just like matrix-vector multiplication. The
+        //  trick is to note that:
+        //
+        //    [M00 M01 M02 M03][v0]   [(v0 M00) + (v1 M01) + (v2 M02) + (v3 M03)]
+        //    [M10 M11 M12 M13][v1] = [(v0 M10) + (v1 M11) + (v2 M12) + (v3 M13)]
+        //    [M20 M21 M22 M23][v2]   [(v0 M20) + (v1 M21) + (v2 M22) + (v3 M23)]
+        //    [M30 M31 M32 M33][v3]   [(v0 M30) + (v1 M31) + (v2 M32) + (v3 M33)]
+        //
+        // Then, we can fill a register with v_i and multiply by the i-th column
+        // of M, accumulating across all i-s. 
+        //
+        // The kids refer to the populating of a register with a single value
+        // "broadcasting", and it can be done with a shuffle instruction. It
+        // seems to be the slowest part of the whole ordeal.
+        //
+        // Our matrix columns are stored above in c0-c7. c0-3 make up M1, and
+        // c4-7 are from M2.
+        //
+
+        #define DCT_INVERSE_8x8_SS2_ROW_LOOP(i)                             \
+            /*                                                              \
+             * Broadcast the components of the row                          \
+             */                                                             \
+                                                                            \
+            x[0] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (0, 0, 0, 0));               \
+                                                                            \
+            x[1] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (1, 1, 1, 1));               \
+                                                                            \
+            x[2] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (2, 2, 2, 2));               \
+                                                                            \
+            x[3] = _mm_shuffle_ps (srcVec[2 * i],                           \
+                                   srcVec[2 * i],                           \
+                                   _MM_SHUFFLE (3, 3, 3, 3));               \
+                                                                            \
+            x[4] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (0, 0, 0, 0));               \
+                                                                            \
+            x[5] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (1, 1, 1, 1));               \
+                                                                            \
+            x[6] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (2, 2, 2, 2));               \
+                                                                            \
+            x[7] = _mm_shuffle_ps (srcVec[2 * i + 1],                       \
+                                   srcVec[2 * i + 1],                       \
+                                   _MM_SHUFFLE (3, 3, 3, 3));               \
+            /*                                                              \
+             * Multiply the components by each column of the matrix         \
+             */                                                             \
+                                                                            \
+            x[0] = _mm_mul_ps (x[0], c0);                                   \
+            x[2] = _mm_mul_ps (x[2], c1);                                   \
+            x[4] = _mm_mul_ps (x[4], c2);                                   \
+            x[6] = _mm_mul_ps (x[6], c3);                                   \
+                                                                            \
+            x[1] = _mm_mul_ps (x[1], c4);                                   \
+            x[3] = _mm_mul_ps (x[3], c5);                                   \
+            x[5] = _mm_mul_ps (x[5], c6);                                   \
+            x[7] = _mm_mul_ps (x[7], c7);                                   \
+                                                                            \
+            /*                                                              \
+             * Add across                                                   \
+             */                                                             \
+                                                                            \
+            evenSum = _mm_setzero_ps();                                     \
+            evenSum = _mm_add_ps (evenSum, x[0]);                           \
+            evenSum = _mm_add_ps (evenSum, x[2]);                           \
+            evenSum = _mm_add_ps (evenSum, x[4]);                           \
+            evenSum = _mm_add_ps (evenSum, x[6]);                           \
+                                                                            \
+            oddSum = _mm_setzero_ps();                                      \
+            oddSum = _mm_add_ps (oddSum, x[1]);                             \
+            oddSum = _mm_add_ps (oddSum, x[3]);                             \
+            oddSum = _mm_add_ps (oddSum, x[5]);                             \
+            oddSum = _mm_add_ps (oddSum, x[7]);                             \
+                                                                            \
+            /*                                                              \
+             * Final Sum:                                                   \
+             *    out [0, 1, 2, 3] = evenSum + oddSum                       \
+             *    out [7, 6, 5, 4] = evenSum - oddSum                       \
+             */                                                             \
+                                                                            \
+            srcVec[2 * i]     = _mm_add_ps (evenSum, oddSum);               \
+            srcVec[2 * i + 1] = _mm_sub_ps (evenSum, oddSum);               \
+            srcVec[2 * i + 1] = _mm_shuffle_ps (srcVec[2 * i + 1],          \
+                                                srcVec[2 * i + 1],          \
+                                                _MM_SHUFFLE (0, 1, 2, 3));
+
+        switch (zeroedRows)
+        {
+          case 0:
+          default:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (5)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (6)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (7)
+            break;
+
+          case 1:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (5)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (6)
+            break;
+
+          case 2:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (5)
+            break;
+
+          case 3:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (4)
+            break;
+
+          case 4:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (3)
+            break;
+
+          case 5:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (2)
+            break;
+
+          case 6:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (1)
+            break;
+
+          case 7:
+            DCT_INVERSE_8x8_SS2_ROW_LOOP (0)
+            break;
+        }
+
+        //
+        // Columns -
+        //
+        // This is slightly more straightforward, if less readable. Here
+        // we just operate on 4 columns at a time, in two batches.
+        //
+        // The slight mess is to try and cache sub-expressions, which
+        // we ignore in the row-wise pass.
+        //
+
+        for (int col = 0; col < 2; ++col)
+        {
+
+            for (int i = 0; i < 8; ++i)
+                in[i] = srcVec[2 * i + col];
+
+            alpha[0] = _mm_mul_ps (c, in[2]);
+            alpha[1] = _mm_mul_ps (f, in[2]);
+            alpha[2] = _mm_mul_ps (c, in[6]);
+            alpha[3] = _mm_mul_ps (f, in[6]);
+
+            beta[0] = _mm_add_ps (_mm_add_ps (_mm_mul_ps (in[1], b),
+                                                          _mm_mul_ps (in[3], d)),
+                                              _mm_add_ps (_mm_mul_ps (in[5], e),
+                                                          _mm_mul_ps (in[7], g)));
+
+            beta[1] = _mm_sub_ps (_mm_sub_ps (_mm_mul_ps (in[1], d),
+                                                          _mm_mul_ps (in[3], g)),
+                                              _mm_add_ps (_mm_mul_ps (in[5], b),
+                                                          _mm_mul_ps (in[7], e)));
+
+            beta[2] = _mm_add_ps (_mm_sub_ps (_mm_mul_ps (in[1], e),
+                                                          _mm_mul_ps (in[3], b)),
+                                              _mm_add_ps (_mm_mul_ps (in[5], g),
+                                                          _mm_mul_ps (in[7], d)));
+
+            beta[3] = _mm_add_ps (_mm_sub_ps (_mm_mul_ps (in[1], g),
+                                                          _mm_mul_ps (in[3], e)),
+                                              _mm_sub_ps (_mm_mul_ps (in[5], d),
+                                                          _mm_mul_ps (in[7], b)));
+
+            theta[0] = _mm_mul_ps (a, _mm_add_ps (in[0], in[4]));
+            theta[3] = _mm_mul_ps (a, _mm_sub_ps (in[0], in[4]));
+
+            theta[1] = _mm_add_ps (alpha[0], alpha[3]);
+            theta[2] = _mm_sub_ps (alpha[1], alpha[2]);
+
+            gamma[0] = _mm_add_ps (theta[0], theta[1]);
+            gamma[1] = _mm_add_ps (theta[3], theta[2]);
+            gamma[2] = _mm_sub_ps (theta[3], theta[2]);
+            gamma[3] = _mm_sub_ps (theta[0], theta[1]);
+
+            srcVec[  col] = _mm_add_ps (gamma[0], beta[0]);
+            srcVec[2+col] = _mm_add_ps (gamma[1], beta[1]);
+            srcVec[4+col] = _mm_add_ps (gamma[2], beta[2]);
+            srcVec[6+col] = _mm_add_ps (gamma[3], beta[3]);
+
+            srcVec[ 8+col] = _mm_sub_ps (gamma[3], beta[3]);
+            srcVec[10+col] = _mm_sub_ps (gamma[2], beta[2]);
+            srcVec[12+col] = _mm_sub_ps (gamma[1], beta[1]);
+            srcVec[14+col] = _mm_sub_ps (gamma[0], beta[0]);
+        }
+
+    #else /* IMF_HAVE_SSE2 */
+
+        dctInverse8x8_scalar<zeroedRows> (data);
+
+    #endif /* IMF_HAVE_SSE2 */
+}
+
+
+//
+// AVX Implementation
+//
+
+#define STR(A) #A
+
+#define IDCT_AVX_SETUP_2_ROWS(_DST0,  _DST1,  _TMP0,  _TMP1, \
+                              _OFF00, _OFF01, _OFF10, _OFF11) \
+    "vmovaps                 " STR(_OFF00) "(%0),  %%xmm" STR(_TMP0) "  \n" \
+    "vmovaps                 " STR(_OFF01) "(%0),  %%xmm" STR(_TMP1) "  \n" \
+    "                                                                                \n" \
+    "vinsertf128  $1, " STR(_OFF10) "(%0), %%ymm" STR(_TMP0) ", %%ymm" STR(_TMP0) "  \n" \
+    "vinsertf128  $1, " STR(_OFF11) "(%0), %%ymm" STR(_TMP1) ", %%ymm" STR(_TMP1) "  \n" \
+    "                                                                                \n" \
+    "vunpcklpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST0) "  \n" \
+    "vunpckhpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST1) "  \n" \
+    "                                                                                \n" \
+    "vunpcklps      %%ymm" STR(_DST1) ",  %%ymm" STR(_DST0) ",  %%ymm" STR(_TMP0) "  \n" \
+    "vunpckhps      %%ymm" STR(_DST1) ",  %%ymm" STR(_DST0) ",  %%ymm" STR(_TMP1) "  \n" \
+    "                                                                                \n" \
+    "vunpcklpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST0) "  \n" \
+    "vunpckhpd      %%ymm" STR(_TMP1) ",  %%ymm" STR(_TMP0) ",  %%ymm" STR(_DST1) "  \n" 
+
+#define IDCT_AVX_MMULT_ROWS(_SRC)                       \
+    /* Broadcast the source values into y12-y15 */      \
+    "vpermilps $0x00, " STR(_SRC) ", %%ymm12       \n"  \
+    "vpermilps $0x55, " STR(_SRC) ", %%ymm13       \n"  \
+    "vpermilps $0xaa, " STR(_SRC) ", %%ymm14       \n"  \
+    "vpermilps $0xff, " STR(_SRC) ", %%ymm15       \n"  \
+                                                        \
+    /* Multiple coefs and the broadcasted values */     \
+    "vmulps    %%ymm12,  %%ymm8, %%ymm12     \n"        \
+    "vmulps    %%ymm13,  %%ymm9, %%ymm13     \n"        \
+    "vmulps    %%ymm14, %%ymm10, %%ymm14     \n"        \
+    "vmulps    %%ymm15, %%ymm11, %%ymm15     \n"        \
+                                                        \
+    /* Accumulate the result back into the source */    \
+    "vaddps    %%ymm13, %%ymm12, %%ymm12      \n"       \
+    "vaddps    %%ymm15, %%ymm14, %%ymm14      \n"       \
+    "vaddps    %%ymm14, %%ymm12, " STR(_SRC) "\n"     
+
+#define IDCT_AVX_EO_TO_ROW_HALVES(_EVEN, _ODD, _FRONT, _BACK)      \
+    "vsubps   " STR(_ODD) "," STR(_EVEN) "," STR(_BACK)  "\n"  \
+    "vaddps   " STR(_ODD) "," STR(_EVEN) "," STR(_FRONT) "\n"  \
+    /* Reverse the back half                                */ \
+    "vpermilps $0x1b," STR(_BACK) "," STR(_BACK) "\n"  
+
+/* In order to allow for path paths when we know certain rows
+ * of the 8x8 block are zero, most of the body of the DCT is
+ * in the following macro. Statements are wrapped in a ROWn()
+ * macro, where n is the lowest row in the 8x8 block in which
+ * they depend.
+ *
+ * This should work for the cases where we have 2-8 full rows.
+ * the 1-row case is special, and we'll handle it seperately.  
+ */
+#define IDCT_AVX_BODY \
+    /* ==============================================               
+     *               Row 1D DCT                                     
+     * ----------------------------------------------
+     */                                                           \
+                                                                  \
+    /* Setup for the row-oriented 1D DCT. Assuming that (%0) holds 
+     * the row-major 8x8 block, load ymm0-3 with the even columns
+     * and ymm4-7 with the odd columns. The lower half of the ymm
+     * holds one row, while the upper half holds the next row.
+     *
+     * If our source is:
+     *    a0 a1 a2 a3   a4 a5 a6 a7
+     *    b0 b1 b2 b3   b4 b5 b6 b7
+     *
+     * We'll be forming:
+     *    a0 a2 a4 a6   b0 b2 b4 b6
+     *    a1 a3 a5 a7   b1 b3 b5 b7
+     */                                                              \
+    ROW0( IDCT_AVX_SETUP_2_ROWS(0, 4, 14, 15,    0,  16,  32,  48) ) \
+    ROW2( IDCT_AVX_SETUP_2_ROWS(1, 5, 12, 13,   64,  80,  96, 112) ) \
+    ROW4( IDCT_AVX_SETUP_2_ROWS(2, 6, 10, 11,  128, 144, 160, 176) ) \
+    ROW6( IDCT_AVX_SETUP_2_ROWS(3, 7,  8,  9,  192, 208, 224, 240) ) \
+                                                                     \
+    /* Multiple the even columns (ymm0-3) by the matrix M1
+     * storing the results back in ymm0-3
+     *
+     * Assume that (%1) holds the matrix in column major order
+     */                                                              \
+    "vbroadcastf128   (%1),  %%ymm8         \n"                      \
+    "vbroadcastf128 16(%1),  %%ymm9         \n"                      \
+    "vbroadcastf128 32(%1), %%ymm10         \n"                      \
+    "vbroadcastf128 48(%1), %%ymm11         \n"                      \
+                                                                     \
+    ROW0( IDCT_AVX_MMULT_ROWS(%%ymm0) )                              \
+    ROW2( IDCT_AVX_MMULT_ROWS(%%ymm1) )                              \
+    ROW4( IDCT_AVX_MMULT_ROWS(%%ymm2) )                              \
+    ROW6( IDCT_AVX_MMULT_ROWS(%%ymm3) )                              \
+                                                                     \
+    /* Repeat, but with the odd columns (ymm4-7) and the 
+     * matrix M2
+     */                                                              \
+    "vbroadcastf128  64(%1),  %%ymm8         \n"                     \
+    "vbroadcastf128  80(%1),  %%ymm9         \n"                     \
+    "vbroadcastf128  96(%1), %%ymm10         \n"                     \
+    "vbroadcastf128 112(%1), %%ymm11         \n"                     \
+                                                                     \
+    ROW0( IDCT_AVX_MMULT_ROWS(%%ymm4) )                              \
+    ROW2( IDCT_AVX_MMULT_ROWS(%%ymm5) )                              \
+    ROW4( IDCT_AVX_MMULT_ROWS(%%ymm6) )                              \
+    ROW6( IDCT_AVX_MMULT_ROWS(%%ymm7) )                              \
+                                                                     \
+    /* Sum the M1 (ymm0-3) and M2 (ymm4-7) results to get the 
+     * front halves of the results, and difference to get the 
+     * back halves. The front halfs end up in ymm0-3, the back
+     * halves end up in ymm12-15. 
+     */                                                                \
+    ROW0( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm0, %%ymm4, %%ymm0, %%ymm12) ) \
+    ROW2( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm1, %%ymm5, %%ymm1, %%ymm13) ) \
+    ROW4( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm2, %%ymm6, %%ymm2, %%ymm14) ) \
+    ROW6( IDCT_AVX_EO_TO_ROW_HALVES(%%ymm3, %%ymm7, %%ymm3, %%ymm15) ) \
+                                                                       \
+    /* Reassemble the rows halves into ymm0-7  */                      \
+    ROW7( "vperm2f128 $0x13, %%ymm3, %%ymm15, %%ymm7   \n" )           \
+    ROW6( "vperm2f128 $0x02, %%ymm3, %%ymm15, %%ymm6   \n" )           \
+    ROW5( "vperm2f128 $0x13, %%ymm2, %%ymm14, %%ymm5   \n" )           \
+    ROW4( "vperm2f128 $0x02, %%ymm2, %%ymm14, %%ymm4   \n" )           \
+    ROW3( "vperm2f128 $0x13, %%ymm1, %%ymm13, %%ymm3   \n" )           \
+    ROW2( "vperm2f128 $0x02, %%ymm1, %%ymm13, %%ymm2   \n" )           \
+    ROW1( "vperm2f128 $0x13, %%ymm0, %%ymm12, %%ymm1   \n" )           \
+    ROW0( "vperm2f128 $0x02, %%ymm0, %%ymm12, %%ymm0   \n" )           \
+                                                                       \
+                                                                       \
+    /* ==============================================
+     *                Column 1D DCT 
+     * ----------------------------------------------
+     */                                                                \
+                                                                       \
+    /* Rows should be in ymm0-7, and M2 columns should still be 
+     * preserved in ymm8-11.  M2 has 4 unique values (and +- 
+     * versions of each), and all (positive) values appear in 
+     * the first column (and row), which is in ymm8.
+     *
+     * For the column-wise DCT, we need to:
+     *   1) Broadcast each element a row of M2 into 4 vectors
+     *   2) Multiple the odd rows (ymm1,3,5,7) by the broadcasts.
+     *   3) Accumulate into ymm12-15 for the odd outputs.
+     *
+     * Instead of doing 16 broadcasts for each element in M2, 
+     * do 4, filling y8-11 with:
+     *
+     *     ymm8:  [ b  b  b  b  | b  b  b  b ]
+     *     ymm9:  [ d  d  d  d  | d  d  d  d ]
+     *     ymm10: [ e  e  e  e  | e  e  e  e ]
+     *     ymm11: [ g  g  g  g  | g  g  g  g ]
+     * 
+     * And deal with the negative values by subtracting during accum.
+     */                                                                \
+    "vpermilps        $0xff,  %%ymm8, %%ymm11  \n"                     \
+    "vpermilps        $0xaa,  %%ymm8, %%ymm10  \n"                     \
+    "vpermilps        $0x55,  %%ymm8, %%ymm9   \n"                     \
+    "vpermilps        $0x00,  %%ymm8, %%ymm8   \n"                     \
+                                                                       \
+    /* This one is easy, since we have ymm12-15 open for scratch   
+     *    ymm12 = b ymm1 + d ymm3 + e ymm5 + g ymm7 
+     */                                                                \
+    ROW1( "vmulps    %%ymm1,  %%ymm8, %%ymm12    \n" )                 \
+    ROW3( "vmulps    %%ymm3,  %%ymm9, %%ymm13    \n" )                 \
+    ROW5( "vmulps    %%ymm5, %%ymm10, %%ymm14    \n" )                 \
+    ROW7( "vmulps    %%ymm7, %%ymm11, %%ymm15    \n" )                 \
+                                                                       \
+    ROW3( "vaddps   %%ymm12, %%ymm13, %%ymm12    \n" )                 \
+    ROW7( "vaddps   %%ymm14, %%ymm15, %%ymm14    \n" )                 \
+    ROW5( "vaddps   %%ymm12, %%ymm14, %%ymm12    \n" )                 \
+                                                                       \
+    /* Tricker, since only y13-15 are open for scratch   
+     *    ymm13 = d ymm1 - g ymm3 - b ymm5 - e ymm7 
+     */                                                                \
+    ROW1( "vmulps    %%ymm1,   %%ymm9, %%ymm13   \n" )                 \
+    ROW3( "vmulps    %%ymm3,  %%ymm11, %%ymm14   \n" )                 \
+    ROW5( "vmulps    %%ymm5,   %%ymm8, %%ymm15   \n" )                 \
+                                                                       \
+    ROW5( "vaddps    %%ymm14, %%ymm15, %%ymm14   \n" )                 \
+    ROW3( "vsubps    %%ymm14, %%ymm13, %%ymm13   \n" )                 \
+                                                                       \
+    ROW7( "vmulps    %%ymm7,  %%ymm10, %%ymm15   \n" )                 \
+    ROW7( "vsubps    %%ymm15, %%ymm13, %%ymm13   \n" )                 \
+                                                                       \
+    /* Tricker still, as only y14-15 are open for scratch   
+     *    ymm14 = e ymm1 - b ymm3 + g ymm5 + d ymm7 
+     */                                                                \
+    ROW1( "vmulps     %%ymm1, %%ymm10,  %%ymm14  \n" )                 \
+    ROW3( "vmulps     %%ymm3,  %%ymm8,  %%ymm15  \n" )                 \
+                                                                       \
+    ROW3( "vsubps    %%ymm15, %%ymm14, %%ymm14   \n" )                 \
+                                                                       \
+    ROW5( "vmulps     %%ymm5, %%ymm11, %%ymm15   \n" )                 \
+    ROW5( "vaddps    %%ymm15, %%ymm14, %%ymm14   \n" )                 \
+                                                                       \
+    ROW7( "vmulps    %%ymm7,   %%ymm9, %%ymm15   \n" )                 \
+    ROW7( "vaddps    %%ymm15, %%ymm14, %%ymm14   \n" )                 \
+                                                                       \
+                                                                       \
+    /* Easy, as we can blow away ymm1,3,5,7 for scratch
+     *    ymm15 = g ymm1 - e ymm3 + d ymm5 - b ymm7 
+     */                                                                \
+    ROW1( "vmulps    %%ymm1, %%ymm11, %%ymm15    \n" )                 \
+    ROW3( "vmulps    %%ymm3, %%ymm10,  %%ymm3    \n" )                 \
+    ROW5( "vmulps    %%ymm5,  %%ymm9,  %%ymm5    \n" )                 \
+    ROW7( "vmulps    %%ymm7,  %%ymm8,  %%ymm7    \n" )                 \
+                                                                       \
+    ROW5( "vaddps   %%ymm15,  %%ymm5, %%ymm15    \n" )                 \
+    ROW7( "vaddps    %%ymm3,  %%ymm7,  %%ymm3    \n" )                 \
+    ROW3( "vsubps    %%ymm3, %%ymm15, %%ymm15    \n" )                 \
+                                                                       \
+                                                                       \
+    /* Load coefs for M1. Because we're going to broadcast
+     * coefs, we don't need to load the actual structure from
+     * M1. Instead, just load enough that we can broadcast.
+     * There are only 6 unique values in M1, but they're in +-
+     * pairs, leaving only 3 unique coefs if we add and subtract 
+     * properly.
+     *
+     * Fill      ymm1 with coef[2] = [ a  a  c  f | a  a  c  f ]
+     * Broadcast ymm5 with           [ f  f  f  f | f  f  f  f ]
+     * Broadcast ymm3 with           [ c  c  c  c | c  c  c  c ]
+     * Broadcast ymm1 with           [ a  a  a  a | a  a  a  a ]
+     */                                                                \
+    "vbroadcastf128   8(%1),  %%ymm1          \n"                      \
+    "vpermilps        $0xff,  %%ymm1, %%ymm5  \n"                      \
+    "vpermilps        $0xaa,  %%ymm1, %%ymm3  \n"                      \
+    "vpermilps        $0x00,  %%ymm1, %%ymm1  \n"                      \
+                                                                       \
+    /* If we expand E = [M1] [x0 x2 x4 x6]^t, we get the following 
+     * common expressions:
+     *
+     *   E_0 = ymm8  = (a ymm0 + a ymm4) + (c ymm2 + f ymm6) 
+     *   E_3 = ymm11 = (a ymm0 + a ymm4) - (c ymm2 + f ymm6)
+     * 
+     *   E_1 = ymm9  = (a ymm0 - a ymm4) + (f ymm2 - c ymm6)
+     *   E_2 = ymm10 = (a ymm0 - a ymm4) - (f ymm2 - c ymm6)
+     *
+     * Afterwards, ymm8-11 will hold the even outputs.
+     */                                                                \
+                                                                       \
+    /*  ymm11 = (a ymm0 + a ymm4),   ymm1 = (a ymm0 - a ymm4) */       \
+    ROW0( "vmulps    %%ymm1,  %%ymm0, %%ymm11   \n" )                  \
+    ROW4( "vmulps    %%ymm1,  %%ymm4,  %%ymm4   \n" )                  \
+    ROW0( "vmovaps   %%ymm11, %%ymm1            \n" )                  \
+    ROW4( "vaddps    %%ymm4, %%ymm11, %%ymm11   \n" )                  \
+    ROW4( "vsubps    %%ymm4,  %%ymm1,  %%ymm1   \n" )                  \
+                                                                       \
+    /* ymm7 = (c ymm2 + f ymm6) */                                     \
+    ROW2( "vmulps    %%ymm3, %%ymm2,  %%ymm7    \n" )                  \
+    ROW6( "vmulps    %%ymm5, %%ymm6,  %%ymm9    \n" )                  \
+    ROW6( "vaddps    %%ymm9, %%ymm7,  %%ymm7    \n" )                  \
+                                                                       \
+    /* E_0 = ymm8  = (a ymm0 + a ymm4) + (c ymm2 + f ymm6) 
+     * E_3 = ymm11 = (a ymm0 + a ymm4) - (c ymm2 + f ymm6) 
+     */                                                                \
+    ROW0( "vmovaps   %%ymm11, %%ymm8            \n" )                  \
+    ROW2( "vaddps     %%ymm7, %%ymm8,  %%ymm8   \n" )                  \
+    ROW2( "vsubps     %%ymm7, %%ymm11, %%ymm11  \n" )                  \
+                                                                       \
+    /* ymm7 = (f ymm2 - c ymm6) */                                     \
+    ROW2( "vmulps     %%ymm5,  %%ymm2, %%ymm7   \n" )                  \
+    ROW6( "vmulps     %%ymm3,  %%ymm6, %%ymm9   \n" )                  \
+    ROW6( "vsubps     %%ymm9,  %%ymm7, %%ymm7   \n" )                  \
+                                                                       \
+    /* E_1 = ymm9  = (a ymm0 - a ymm4) + (f ymm2 - c ymm6) 
+     * E_2 = ymm10 = (a ymm0 - a ymm4) - (f ymm2 - c ymm6)
+     */                                                                \
+    ROW0( "vmovaps   %%ymm1,  %%ymm9            \n" )                  \
+    ROW0( "vmovaps   %%ymm1, %%ymm10            \n" )                  \
+    ROW2( "vaddps    %%ymm7,  %%ymm1,  %%ymm9   \n" )                  \
+    ROW2( "vsubps    %%ymm7,  %%ymm1,  %%ymm10  \n" )                  \
+                                                                       \
+    /* Add the even (ymm8-11) and the odds (ymm12-15), 
+     * placing the results into ymm0-7 
+     */                                                                \
+    "vaddps   %%ymm12,  %%ymm8, %%ymm0       \n"                       \
+    "vaddps   %%ymm13,  %%ymm9, %%ymm1       \n"                       \
+    "vaddps   %%ymm14, %%ymm10, %%ymm2       \n"                       \
+    "vaddps   %%ymm15, %%ymm11, %%ymm3       \n"                       \
+                                                                       \
+    "vsubps   %%ymm12,  %%ymm8, %%ymm7       \n"                       \
+    "vsubps   %%ymm13,  %%ymm9, %%ymm6       \n"                       \
+    "vsubps   %%ymm14, %%ymm10, %%ymm5       \n"                       \
+    "vsubps   %%ymm15, %%ymm11, %%ymm4       \n"                       \
+                                                                       \
+    /* Copy out the results from ymm0-7  */                            \
+    "vmovaps   %%ymm0,    (%0)                   \n"                   \
+    "vmovaps   %%ymm1,  32(%0)                   \n"                   \
+    "vmovaps   %%ymm2,  64(%0)                   \n"                   \
+    "vmovaps   %%ymm3,  96(%0)                   \n"                   \
+    "vmovaps   %%ymm4, 128(%0)                   \n"                   \
+    "vmovaps   %%ymm5, 160(%0)                   \n"                   \
+    "vmovaps   %%ymm6, 192(%0)                   \n"                   \
+    "vmovaps   %%ymm7, 224(%0)                   \n"            
+
+/* Output, input, and clobber (OIC) sections of the inline asm */
+#define IDCT_AVX_OIC(_IN0)                          \
+        : /* Output  */                            \
+        : /* Input   */ "r"(_IN0), "r"(sAvxCoef)      \
+        : /* Clobber */ "memory",                  \
+                        "%xmm0",  "%xmm1",  "%xmm2",  "%xmm3", \
+                        "%xmm4",  "%xmm5",  "%xmm6",  "%xmm7", \
+                        "%xmm8",  "%xmm9",  "%xmm10", "%xmm11",\
+                        "%xmm12", "%xmm13", "%xmm14", "%xmm15" 
+
+/* Include vzeroupper for non-AVX builds                */
+#ifndef __AVX__ 
+    #define IDCT_AVX_ASM(_IN0)   \
+        __asm__(                 \
+            IDCT_AVX_BODY        \
+            "vzeroupper      \n" \
+            IDCT_AVX_OIC(_IN0)   \
+        );                       
+#else /* __AVX__ */
+    #define IDCT_AVX_ASM(_IN0)   \
+        __asm__(                 \
+            IDCT_AVX_BODY        \
+            IDCT_AVX_OIC(_IN0)   \
+        );                       
+#endif /* __AVX__ */
+
+template <int zeroedRows>
+void
+dctInverse8x8_avx (float *data)
+{
+    #if defined IMF_HAVE_GCC_INLINEASM_64
+
+    /* The column-major version of M1, followed by the 
+     * column-major version of M2:
+     *   
+     *          [ a  c  a  f ]          [ b  d  e  g ]
+     *   M1  =  [ a  f -a -c ]    M2 =  [ d -g -b -e ]
+     *          [ a -f -a  c ]          [ e -b  g  d ]
+     *          [ a -c  a -f ]          [ g -e  d -b ]
+     */   
+    const float sAvxCoef[32]  __attribute__((aligned(32))) = {
+        3.535536e-01,  3.535536e-01,  3.535536e-01,  3.535536e-01, /* a  a  a  a */
+        4.619398e-01,  1.913422e-01, -1.913422e-01, -4.619398e-01, /* c  f -f -c */
+        3.535536e-01, -3.535536e-01, -3.535536e-01,  3.535536e-01, /* a -a -a  a */
+        1.913422e-01, -4.619398e-01,  4.619398e-01, -1.913422e-01, /* f -c  c -f */
+
+        4.903927e-01,  4.157349e-01,  2.777855e-01,  9.754573e-02, /* b  d  e  g */
+        4.157349e-01, -9.754573e-02, -4.903927e-01, -2.777855e-01, /* d -g -b -e */
+        2.777855e-01, -4.903927e-01,  9.754573e-02,  4.157349e-01, /* e -b  g  d */
+        9.754573e-02, -2.777855e-01,  4.157349e-01, -4.903927e-01  /* g -e  d -b */
+    };
+
+        #define ROW0(_X) _X
+        #define ROW1(_X) _X
+        #define ROW2(_X) _X
+        #define ROW3(_X) _X 
+        #define ROW4(_X) _X
+        #define ROW5(_X) _X 
+        #define ROW6(_X) _X
+        #define ROW7(_X) _X 
+
+        if (zeroedRows == 0) {
+
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 1) {
+
+            #undef  ROW7
+            #define ROW7(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 2) {
+
+            #undef  ROW6
+            #define ROW6(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 3) {
+
+            #undef  ROW5
+            #define ROW5(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 4) {
+
+            #undef  ROW4
+            #define ROW4(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 5) {
+
+            #undef  ROW3
+            #define ROW3(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 6) {
+
+            #undef  ROW2
+            #define ROW2(_X)
+            IDCT_AVX_ASM(data)
+
+        } else if (zeroedRows == 7) {
+
+            __asm__(  
+
+                /* ==============================================
+                 *                Row 1D DCT 
+                 * ----------------------------------------------
+                 */ 
+                IDCT_AVX_SETUP_2_ROWS(0, 4, 14, 15,    0,  16,  32,  48) 
+
+                "vbroadcastf128   (%1),  %%ymm8         \n"
+                "vbroadcastf128 16(%1),  %%ymm9         \n"
+                "vbroadcastf128 32(%1), %%ymm10         \n"
+                "vbroadcastf128 48(%1), %%ymm11         \n"
+
+                /* Stash a vector of [a a a a | a a a a] away  in ymm2 */
+                "vinsertf128 $1,  %%xmm8,  %%ymm8,  %%ymm2 \n"
+
+                IDCT_AVX_MMULT_ROWS(%%ymm0) 
+
+                "vbroadcastf128  64(%1),  %%ymm8         \n"
+                "vbroadcastf128  80(%1),  %%ymm9         \n"
+                "vbroadcastf128  96(%1), %%ymm10         \n"
+                "vbroadcastf128 112(%1), %%ymm11         \n"
+
+                IDCT_AVX_MMULT_ROWS(%%ymm4) 
+
+                IDCT_AVX_EO_TO_ROW_HALVES(%%ymm0, %%ymm4, %%ymm0, %%ymm12) 
+
+                "vperm2f128 $0x02, %%ymm0, %%ymm12, %%ymm0   \n" 
+
+                /* ==============================================
+                 *                Column 1D DCT 
+                 * ----------------------------------------------
+                 */ 
+
+                /* DC only, so multiple by a and we're done */
+                "vmulps   %%ymm2, %%ymm0, %%ymm0  \n"
+
+                /* Copy out results  */
+                "vmovaps %%ymm0,    (%0)          \n"
+                "vmovaps %%ymm0,  32(%0)          \n"
+                "vmovaps %%ymm0,  64(%0)          \n"
+                "vmovaps %%ymm0,  96(%0)          \n"
+                "vmovaps %%ymm0, 128(%0)          \n"
+                "vmovaps %%ymm0, 160(%0)          \n"
+                "vmovaps %%ymm0, 192(%0)          \n"
+                "vmovaps %%ymm0, 224(%0)          \n"
+
+                #ifndef __AVX__
+                    "vzeroupper                   \n" 
+                #endif /* __AVX__ */
+                IDCT_AVX_OIC(data)
+            );
+        } else {
+            assert(false); // Invalid template instance parameter
+        }
+    #else  /* IMF_HAVE_GCC_INLINEASM_64 */
+
+        dctInverse8x8_scalar<zeroedRows>(data);
+
+    #endif /*  IMF_HAVE_GCC_INLINEASM_64 */
+}
+
+
+//
+// Full 8x8 Forward DCT:
+//
+// Base forward 8x8 DCT implementation. Works on the data in-place
+//
+// The implementation describedin Pennebaker + Mitchell,
+//  section 4.3.2, and illustrated in figure 4-7
+//
+// The basic idea is that the 1D DCT math reduces to:
+//
+//   2*out_0            = c_4 [(s_07 + s_34) + (s_12 + s_56)]
+//   2*out_4            = c_4 [(s_07 + s_34) - (s_12 + s_56)]
+//
+//   {2*out_2, 2*out_6} = rot_6 ((d_12 - d_56), (s_07 - s_34))
+//
+//   {2*out_3, 2*out_5} = rot_-3 (d_07 - c_4 (s_12 - s_56),
+//                                d_34 - c_4 (d_12 + d_56))
+//
+//   {2*out_1, 2*out_7} = rot_-1 (d_07 + c_4 (s_12 - s_56),
+//                               -d_34 - c_4 (d_12 + d_56))
+//
+// where:
+//
+//    c_i  = cos(i*pi/16)
+//    s_i  = sin(i*pi/16)
+//
+//    s_ij = in_i + in_j
+//    d_ij = in_i - in_j
+//
+//    rot_i(x, y) = {c_i*x + s_i*y, -s_i*x + c_i*y} 
+//
+// We'll run the DCT in two passes. First, run the 1D DCT on 
+// the rows, in-place. Then, run over the columns in-place, 
+// and be done with it.
+//
+
+#ifndef IMF_HAVE_SSE2
+
+//
+// Default implementation
+//
+
+void 
+dctForward8x8 (float *data)
+{
+    float A0, A1, A2, A3, A4, A5, A6, A7;
+    float K0, K1, rot_x, rot_y;
+
+    float *srcPtr = data;
+    float *dstPtr = data;
+
+    const float c1 = cosf (3.14159f * 1.0f / 16.0f);
+    const float c2 = cosf (3.14159f * 2.0f / 16.0f);
+    const float c3 = cosf (3.14159f * 3.0f / 16.0f);
+    const float c4 = cosf (3.14159f * 4.0f / 16.0f);
+    const float c5 = cosf (3.14159f * 5.0f / 16.0f);
+    const float c6 = cosf (3.14159f * 6.0f / 16.0f);
+    const float c7 = cosf (3.14159f * 7.0f / 16.0f);
+
+    const float c1Half = .5f * c1; 
+    const float c2Half = .5f * c2;
+    const float c3Half = .5f * c3;
+    const float c5Half = .5f * c5;
+    const float c6Half = .5f * c6;
+    const float c7Half = .5f * c7;
+
+    //
+    // First pass - do a 1D DCT over the rows and write the 
+    //              results back in place
+    //
+
+    for (int row=0; row<8; ++row)
+    {
+        float *srcRowPtr = srcPtr + 8 * row;
+        float *dstRowPtr = dstPtr + 8 * row;
+
+        A0 = srcRowPtr[0] + srcRowPtr[7];
+        A1 = srcRowPtr[1] + srcRowPtr[2];
+        A2 = srcRowPtr[1] - srcRowPtr[2];
+        A3 = srcRowPtr[3] + srcRowPtr[4];
+        A4 = srcRowPtr[3] - srcRowPtr[4];
+        A5 = srcRowPtr[5] + srcRowPtr[6];
+        A6 = srcRowPtr[5] - srcRowPtr[6];
+        A7 = srcRowPtr[0] - srcRowPtr[7];      
+
+        K0 = c4 * (A0 + A3); 
+        K1 = c4 * (A1 + A5); 
+
+        dstRowPtr[0] = .5f * (K0 + K1);
+        dstRowPtr[4] = .5f * (K0 - K1);
+
+        //
+        // (2*dst2, 2*dst6) = rot 6 (d12 - d56,  s07 - s34)
+        //
+
+        rot_x = A2 - A6;
+        rot_y = A0 - A3;
+
+        dstRowPtr[2] =  c6Half * rot_x + c2Half * rot_y;
+        dstRowPtr[6] =  c6Half * rot_y - c2Half * rot_x;
+
+        //
+        // K0, K1 are active until after dst[1],dst[7]
+        //  as well as dst[3], dst[5] are computed.
+        //
+
+        K0 = c4 * (A1 - A5);      
+        K1 = -1 * c4 * (A2 + A6); 
+
+        //
+        // Two ways to do a rotation:
+        //
+        //  rot i (x, y) = 
+        //           X =  c_i*x + s_i*y
+        //           Y = -s_i*x + c_i*y
+        //
+        //        OR
+        //
+        //           X = c_i*(x+y) + (s_i-c_i)*y
+        //           Y = c_i*y     - (s_i+c_i)*x
+        //
+        // the first case has 4 multiplies, but fewer constants,
+        // while the 2nd case has fewer multiplies but takes more space.
+
+        //
+        // (2*dst3, 2*dst5) = rot -3 ( d07 - K0,  d34 + K1 )
+        //
+
+        rot_x = A7 - K0;
+        rot_y = A4 + K1;
+
+        dstRowPtr[3] = c3Half * rot_x - c5Half * rot_y;
+        dstRowPtr[5] = c5Half * rot_x + c3Half * rot_y;
+
+        //
+        // (2*dst1, 2*dst7) = rot -1 ( d07 + K0,  K1  - d34 )
+        //
+
+        rot_x = A7 + K0;
+        rot_y = K1 - A4;
+
+        //
+        // A: 4, 7 are inactive. All A's are inactive
+        //
+
+        dstRowPtr[1] = c1Half * rot_x - c7Half * rot_y;
+        dstRowPtr[7] = c7Half * rot_x + c1Half * rot_y;
+    }
+
+    //
+    // Second pass - do the same, but on the columns
+    //
+
+    for (int column = 0; column < 8; ++column)
+    {
+
+        A0 = srcPtr[     column] + srcPtr[56 + column];
+        A7 = srcPtr[     column] - srcPtr[56 + column];
+
+        A1 = srcPtr[ 8 + column] + srcPtr[16 + column];
+        A2 = srcPtr[ 8 + column] - srcPtr[16 + column];
+
+        A3 = srcPtr[24 + column] + srcPtr[32 + column];
+        A4 = srcPtr[24 + column] - srcPtr[32 + column];
+
+        A5 = srcPtr[40 + column] + srcPtr[48 + column];
+        A6 = srcPtr[40 + column] - srcPtr[48 + column];
+
+        K0 = c4 * (A0 + A3); 
+        K1 = c4 * (A1 + A5); 
+
+        dstPtr[   column] = .5f * (K0 + K1);
+        dstPtr[32+column] = .5f * (K0 - K1);
+
+        //
+        // (2*dst2, 2*dst6) = rot 6 ( d12 - d56,  s07 - s34 )
+        //
+
+        rot_x = A2 - A6;
+        rot_y = A0 - A3;
+
+        dstPtr[16+column] = .5f * (c6 * rot_x + c2 * rot_y);
+        dstPtr[48+column] = .5f * (c6 * rot_y - c2 * rot_x);
+
+        //
+        // K0, K1 are active until after dst[1],dst[7]
+        //  as well as dst[3], dst[5] are computed.
+        //
+
+        K0 = c4 * (A1 - A5);      
+        K1 = -1 * c4 * (A2 + A6); 
+
+        //
+        // (2*dst3, 2*dst5) = rot -3 ( d07 - K0,  d34 + K1 )
+        //
+
+        rot_x = A7 - K0;
+        rot_y = A4 + K1;
+
+        dstPtr[24+column] = .5f * (c3 * rot_x - c5 * rot_y);
+        dstPtr[40+column] = .5f * (c5 * rot_x + c3 * rot_y);
+
+        //
+        // (2*dst1, 2*dst7) = rot -1 ( d07 + K0,  K1  - d34 )
+        //
+
+        rot_x = A7 + K0;
+        rot_y = K1 - A4;
+
+        dstPtr[ 8+column] = .5f * (c1 * rot_x - c7 * rot_y);
+        dstPtr[56+column] = .5f * (c7 * rot_x + c1 * rot_y);
+    }
+}
+
+#else  /* IMF_HAVE_SSE2 */
+
+//
+// SSE2 implementation
+//
+// Here, we're always doing a column-wise operation
+// plus transposes. This might be faster to do differently
+// between rows-wise and column-wise
+//
+
+void 
+dctForward8x8 (float *data)
+{
+    __m128 *srcVec = (__m128 *)data;
+    __m128  a0Vec, a1Vec, a2Vec, a3Vec, a4Vec, a5Vec, a6Vec, a7Vec;
+    __m128  k0Vec, k1Vec, rotXVec, rotYVec;
+    __m128  transTmp[4], transTmp2[4];
+
+    __m128  c4Vec     = { .70710678f,  .70710678f,  .70710678f,  .70710678f};
+    __m128  c4NegVec  = {-.70710678f, -.70710678f, -.70710678f, -.70710678f};
+
+    __m128  c1HalfVec = {.490392640f, .490392640f, .490392640f, .490392640f}; 
+    __m128  c2HalfVec = {.461939770f, .461939770f, .461939770f, .461939770f};
+    __m128  c3HalfVec = {.415734810f, .415734810f, .415734810f, .415734810f}; 
+    __m128  c5HalfVec = {.277785120f, .277785120f, .277785120f, .277785120f}; 
+    __m128  c6HalfVec = {.191341720f, .191341720f, .191341720f, .191341720f};
+    __m128  c7HalfVec = {.097545161f, .097545161f, .097545161f, .097545161f}; 
+
+    __m128  halfVec   = {.5f, .5f, .5f, .5f};
+
+    for (int iter = 0; iter < 2; ++iter)
+    {
+        //
+        //  Operate on 4 columns at a time. The
+        //    offsets into our row-major array are:
+        //                  0:  0      1
+        //                  1:  2      3
+        //                  2:  4      5
+        //                  3:  6      7
+        //                  4:  8      9
+        //                  5: 10     11
+        //                  6: 12     13
+        //                  7: 14     15
+        //
+
+        for (int pass=0; pass<2; ++pass)
+        {
+            a0Vec = _mm_add_ps (srcVec[ 0 + pass], srcVec[14 + pass]);
+            a1Vec = _mm_add_ps (srcVec[ 2 + pass], srcVec[ 4 + pass]);
+            a3Vec = _mm_add_ps (srcVec[ 6 + pass], srcVec[ 8 + pass]);
+            a5Vec = _mm_add_ps (srcVec[10 + pass], srcVec[12 + pass]);
+            a7Vec = _mm_sub_ps (srcVec[ 0 + pass], srcVec[14 + pass]);
+            a2Vec = _mm_sub_ps (srcVec[ 2 + pass], srcVec[ 4 + pass]);
+            a4Vec = _mm_sub_ps (srcVec[ 6 + pass], srcVec[ 8 + pass]);
+            a6Vec = _mm_sub_ps (srcVec[10 + pass], srcVec[12 + pass]);
+
+            //
+            // First stage; Compute out_0 and out_4
+            //
+
+            k0Vec = _mm_add_ps (a0Vec, a3Vec);
+            k1Vec = _mm_add_ps (a1Vec, a5Vec);
+
+            k0Vec = _mm_mul_ps (c4Vec, k0Vec);
+            k1Vec = _mm_mul_ps (c4Vec, k1Vec);
+
+            srcVec[0 + pass] = _mm_add_ps (k0Vec, k1Vec);
+            srcVec[8 + pass] = _mm_sub_ps (k0Vec, k1Vec);
+
+            srcVec[0 + pass] = _mm_mul_ps (srcVec[0 + pass], halfVec );
+            srcVec[8 + pass] = _mm_mul_ps (srcVec[8 + pass], halfVec );
+
+
+            //
+            // Second stage; Compute out_2 and out_6
+            //
+            
+            k0Vec = _mm_sub_ps (a2Vec, a6Vec);
+            k1Vec = _mm_sub_ps (a0Vec, a3Vec);
+
+            srcVec[ 4 + pass] = _mm_add_ps (_mm_mul_ps (c6HalfVec, k0Vec),
+                                            _mm_mul_ps (c2HalfVec, k1Vec));
+
+            srcVec[12 + pass] = _mm_sub_ps (_mm_mul_ps (c6HalfVec, k1Vec), 
+                                            _mm_mul_ps (c2HalfVec, k0Vec));
+
+            //
+            // Precompute K0 and K1 for the remaining stages
+            //
+
+            k0Vec = _mm_mul_ps (_mm_sub_ps (a1Vec, a5Vec), c4Vec);
+            k1Vec = _mm_mul_ps (_mm_add_ps (a2Vec, a6Vec), c4NegVec); 
+
+            //
+            // Third Stage, compute out_3 and out_5
+            //
+
+            rotXVec = _mm_sub_ps (a7Vec, k0Vec);
+            rotYVec = _mm_add_ps (a4Vec, k1Vec);
+
+            srcVec[ 6 + pass] = _mm_sub_ps (_mm_mul_ps (c3HalfVec, rotXVec),
+                                            _mm_mul_ps (c5HalfVec, rotYVec));
+
+            srcVec[10 + pass] = _mm_add_ps (_mm_mul_ps (c5HalfVec, rotXVec),
+                                            _mm_mul_ps (c3HalfVec, rotYVec));
+
+            //
+            // Fourth Stage, compute out_1 and out_7
+            //
+
+            rotXVec = _mm_add_ps (a7Vec, k0Vec);
+            rotYVec = _mm_sub_ps (k1Vec, a4Vec);
+
+            srcVec[ 2 + pass] = _mm_sub_ps (_mm_mul_ps (c1HalfVec, rotXVec),
+                                            _mm_mul_ps (c7HalfVec, rotYVec));
+
+            srcVec[14 + pass] = _mm_add_ps (_mm_mul_ps (c7HalfVec, rotXVec), 
+                                            _mm_mul_ps (c1HalfVec, rotYVec));
+        }
+
+        //
+        // Transpose the matrix, in 4x4 blocks. So, if we have our
+        // 8x8 matrix divied into 4x4 blocks:
+        //
+        //         M0 | M1         M0t | M2t
+        //        ----+---   -->  -----+------
+        //         M2 | M3         M1t | M3t
+        //
+
+        //
+        // M0t, done in place, the first half.
+        //
+
+        transTmp[0] = _mm_shuffle_ps (srcVec[0], srcVec[2], 0x44);
+        transTmp[1] = _mm_shuffle_ps (srcVec[4], srcVec[6], 0x44);
+        transTmp[3] = _mm_shuffle_ps (srcVec[4], srcVec[6], 0xEE);
+        transTmp[2] = _mm_shuffle_ps (srcVec[0], srcVec[2], 0xEE);
+
+        //
+        // M3t, also done in place, the first half.
+        //
+
+        transTmp2[0] = _mm_shuffle_ps (srcVec[ 9], srcVec[11], 0x44);
+        transTmp2[1] = _mm_shuffle_ps (srcVec[13], srcVec[15], 0x44);
+        transTmp2[2] = _mm_shuffle_ps (srcVec[ 9], srcVec[11], 0xEE);
+        transTmp2[3] = _mm_shuffle_ps (srcVec[13], srcVec[15], 0xEE);
+
+        //
+        // M0t, the second half.
+        //
+
+        srcVec[0] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0x88);
+        srcVec[4] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0x88);
+        srcVec[2] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0xDD);
+        srcVec[6] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0xDD);
+
+        //
+        // M3t, the second half.
+        //
+
+        srcVec[ 9] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0x88);
+        srcVec[13] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0x88);
+        srcVec[11] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0xDD);
+        srcVec[15] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0xDD);
+
+        //
+        // M1 and M2 need to be done at the same time, because we're
+        //  swapping. 
+        //
+        // First, the first half of M1t
+        //
+
+        transTmp[0] = _mm_shuffle_ps (srcVec[1], srcVec[3], 0x44);
+        transTmp[1] = _mm_shuffle_ps (srcVec[5], srcVec[7], 0x44);
+        transTmp[2] = _mm_shuffle_ps (srcVec[1], srcVec[3], 0xEE);
+        transTmp[3] = _mm_shuffle_ps (srcVec[5], srcVec[7], 0xEE);
+
+        //
+        // And the first half of M2t
+        //
+
+        transTmp2[0] = _mm_shuffle_ps (srcVec[ 8], srcVec[10], 0x44);
+        transTmp2[1] = _mm_shuffle_ps (srcVec[12], srcVec[14], 0x44);
+        transTmp2[2] = _mm_shuffle_ps (srcVec[ 8], srcVec[10], 0xEE);
+        transTmp2[3] = _mm_shuffle_ps (srcVec[12], srcVec[14], 0xEE);
+
+        //
+        // Second half of M1t
+        //
+
+        srcVec[ 8] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0x88);
+        srcVec[12] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0x88);
+        srcVec[10] = _mm_shuffle_ps (transTmp[0], transTmp[1], 0xDD);
+        srcVec[14] = _mm_shuffle_ps (transTmp[2], transTmp[3], 0xDD);
+
+        //
+        // Second half of M2
+        //
+
+        srcVec[1] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0x88);
+        srcVec[5] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0x88);
+        srcVec[3] = _mm_shuffle_ps (transTmp2[0], transTmp2[1], 0xDD);
+        srcVec[7] = _mm_shuffle_ps (transTmp2[2], transTmp2[3], 0xDD);
+    }
+}
+
+#endif /* IMF_HAVE_SSE2 */
+
+} // anonymous namespace
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
index f984aa3..f962fc9 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfEnvmap.h>
+#include "ImfEnvmap.h"
 #include "ImathFun.h"
+#include "ImfNamespace.h"
+
 #include <algorithm>
 #include <math.h>
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
 
-namespace Imf {
 namespace LatLongMap {
 
-V2f
+V2f    
 latLong (const V3f &dir)
 {
     float r = sqrt (dir.z * dir.z + dir.x * dir.x);
 
     float latitude = (r < abs (dir.y))?
-             acos (r / dir.length()) * sign (dir.y):
-             asin (dir.y / dir.length());
+                        acos (r / dir.length()) * sign (dir.y):
+                        asin (dir.y / dir.length());
 
     float longitude = (dir.z == 0 && dir.x == 0)? 0: atan2 (dir.x, dir.z);
 
@@ -72,24 +77,24 @@ latLong (const Box2i &dataWindow, const V2f &pixelPosition)
 
     if (dataWindow.max.y > dataWindow.min.y)
     {
-    latitude = -M_PI *
-          ((pixelPosition.y  - dataWindow.min.y) /
-           (dataWindow.max.y - dataWindow.min.y) - 0.5f);
+        latitude = -1 * float(M_PI) *
+            ((pixelPosition.y  - dataWindow.min.y) /
+            (dataWindow.max.y - dataWindow.min.y) - 0.5f);
     }
     else
     {
-    latitude = 0;
+       latitude = 0;
     }
 
     if (dataWindow.max.x > dataWindow.min.x)
     {
-    longitude = -2 * M_PI *
-           ((pixelPosition.x  - dataWindow.min.x) /
-            (dataWindow.max.x - dataWindow.min.x) - 0.5f);
+       longitude = -2 * float(M_PI) *
+                  ((pixelPosition.x  - dataWindow.min.x) /
+                   (dataWindow.max.x - dataWindow.min.x) - 0.5f);
     }
     else
     {
-    longitude = 0;
+       longitude = 0;
     }
 
     return V2f (latitude, longitude);
@@ -99,11 +104,11 @@ latLong (const Box2i &dataWindow, const V2f &pixelPosition)
 V2f
 pixelPosition (const Box2i &dataWindow, const V2f &latLong)
 {
-    float x = latLong.y / (-2 * M_PI) + 0.5f;
-    float y = latLong.x / -M_PI + 0.5f;
+    float x = latLong.y / (-2 * float(M_PI)) + 0.5f;
+    float y = latLong.x / (-1 * float(M_PI)) + 0.5f;
 
     return V2f (x * (dataWindow.max.x - dataWindow.min.x) + dataWindow.min.x,
-        y * (dataWindow.max.y - dataWindow.min.y) + dataWindow.min.y);
+               y * (dataWindow.max.y - dataWindow.min.y) + dataWindow.min.y);
 }
 
 
@@ -120,8 +125,8 @@ direction (const Box2i &dataWindow, const V2f &pixelPosition)
     V2f ll = latLong (dataWindow, pixelPosition);
 
     return V3f (sin (ll.y) * cos (ll.x),
-        sin (ll.x),
-        cos (ll.y) * cos (ll.x));
+               sin (ll.x),
+               cos (ll.y) * cos (ll.x));
 }
 
 } // namespace LatLongMap
@@ -133,7 +138,7 @@ int
 sizeOfFace (const Box2i &dataWindow)
 {
     return min ((dataWindow.max.x - dataWindow.min.x + 1),
-        (dataWindow.max.y - dataWindow.min.y + 1) / 6);
+               (dataWindow.max.y - dataWindow.min.y + 1) / 6);
 }
 
 
@@ -163,39 +168,39 @@ pixelPosition (CubeMapFace face, const Box2i &dataWindow, V2f positionInFace)
     {
       case CUBEFACE_POS_X:
 
-    pos.x = dwf.min.x + positionInFace.y;
-    pos.y = dwf.max.y - positionInFace.x;
-    break;
+       pos.x = dwf.min.x + positionInFace.y;
+       pos.y = dwf.max.y - positionInFace.x;
+       break;
 
       case CUBEFACE_NEG_X:
 
-    pos.x = dwf.max.x - positionInFace.y;
-    pos.y = dwf.max.y - positionInFace.x;
-    break;
+       pos.x = dwf.max.x - positionInFace.y;
+       pos.y = dwf.max.y - positionInFace.x;
+       break;
 
       case CUBEFACE_POS_Y:
 
-    pos.x = dwf.min.x + positionInFace.x;
-    pos.y = dwf.max.y - positionInFace.y;
-    break;
+       pos.x = dwf.min.x + positionInFace.x;
+       pos.y = dwf.max.y - positionInFace.y;
+       break;
 
       case CUBEFACE_NEG_Y:
 
-    pos.x = dwf.min.x + positionInFace.x;
-    pos.y = dwf.min.y + positionInFace.y;
-    break;
+       pos.x = dwf.min.x + positionInFace.x;
+       pos.y = dwf.min.y + positionInFace.y;
+       break;
 
       case CUBEFACE_POS_Z:
 
-    pos.x = dwf.max.x - positionInFace.x;
-    pos.y = dwf.max.y - positionInFace.y;
-    break;
+       pos.x = dwf.max.x - positionInFace.x;
+       pos.y = dwf.max.y - positionInFace.y;
+       break;
 
       case CUBEFACE_NEG_Z:
 
-    pos.x = dwf.min.x + positionInFace.x;
-    pos.y = dwf.max.y - positionInFace.y;
-    break;
+       pos.x = dwf.min.x + positionInFace.x;
+       pos.y = dwf.max.y - positionInFace.y;
+       break;
     }
 
     return pos;
@@ -204,9 +209,9 @@ pixelPosition (CubeMapFace face, const Box2i &dataWindow, V2f positionInFace)
 
 void
 faceAndPixelPosition (const V3f &direction,
-              const Box2i &dataWindow,
-              CubeMapFace &face,
-              V2f &pif)
+                     const Box2i &dataWindow,
+                     CubeMapFace &face,
+                     V2f &pif)
 {
     int sof = sizeOfFace (dataWindow);
     float absx = abs (direction.x);
@@ -215,44 +220,44 @@ faceAndPixelPosition (const V3f &direction,
 
     if (absx >= absy && absx >= absz)
     {
-    if (absx == 0)
-    {
-        //
-        // Special case - direction is (0, 0, 0)
-        //
-
-        face = CUBEFACE_POS_X;
-        pif = V2f (0, 0);
-        return;
-    }
-
-    pif.x = (direction.y / absx + 1) / 2 * (sof - 1);
-    pif.y = (direction.z / absx + 1) / 2 * (sof - 1);
-
-    if (direction.x > 0)
-        face = CUBEFACE_POS_X;
-    else
-        face = CUBEFACE_NEG_X;
+       if (absx == 0)
+       {
+           //
+           // Special case - direction is (0, 0, 0)
+           //
+
+           face = CUBEFACE_POS_X;
+           pif = V2f (0, 0);
+           return;
+       }
+
+       pif.x = (direction.y / absx + 1) / 2 * (sof - 1);
+       pif.y = (direction.z / absx + 1) / 2 * (sof - 1);
+
+       if (direction.x > 0)
+           face = CUBEFACE_POS_X;
+       else
+           face = CUBEFACE_NEG_X;
     }
     else if (absy >= absz)
     {
-    pif.x = (direction.x / absy + 1) / 2 * (sof - 1);
-    pif.y = (direction.z / absy + 1) / 2 * (sof - 1);
+       pif.x = (direction.x / absy + 1) / 2 * (sof - 1);
+       pif.y = (direction.z / absy + 1) / 2 * (sof - 1);
 
-    if (direction.y > 0)
-        face = CUBEFACE_POS_Y;
-    else
-        face = CUBEFACE_NEG_Y;
+       if (direction.y > 0)
+           face = CUBEFACE_POS_Y;
+       else
+           face = CUBEFACE_NEG_Y;
     }
     else
     {
-    pif.x = (direction.x / absz + 1) / 2 * (sof - 1);
-    pif.y = (direction.y / absz + 1) / 2 * (sof - 1);
+       pif.x = (direction.x / absz + 1) / 2 * (sof - 1);
+       pif.y = (direction.y / absz + 1) / 2 * (sof - 1);
 
-    if (direction.z > 0)
-        face = CUBEFACE_POS_Z;
-    else
-        face = CUBEFACE_NEG_Z;
+       if (direction.z > 0)
+           face = CUBEFACE_POS_Z;
+       else
+           face = CUBEFACE_NEG_Z;
     }
 }
 
@@ -263,15 +268,15 @@ direction (CubeMapFace face, const Box2i &dataWindow, const V2f &positionInFace)
     int sof = sizeOfFace (dataWindow);
 
     V2f pos;
-
+    
     if (sof > 1)
     {
-    pos = V2f (positionInFace.x / (sof - 1) * 2 - 1,
-           positionInFace.y / (sof - 1) * 2 - 1);
+       pos = V2f (positionInFace.x / (sof - 1) * 2 - 1,
+                  positionInFace.y / (sof - 1) * 2 - 1);
     }
     else
     {
-    pos = V2f (0, 0);
+       pos = V2f (0, 0);
     }
 
     V3f dir (1, 0, 0);
@@ -280,49 +285,51 @@ direction (CubeMapFace face, const Box2i &dataWindow, const V2f &positionInFace)
     {
       case CUBEFACE_POS_X:
 
-    dir.x = 1;
-    dir.y = pos.x;
-    dir.z = pos.y;
-    break;
+       dir.x = 1;
+       dir.y = pos.x;
+       dir.z = pos.y;
+       break;
 
       case CUBEFACE_NEG_X:
 
-    dir.x = -1;
-    dir.y = pos.x;
-    dir.z = pos.y;
-    break;
+       dir.x = -1;
+       dir.y = pos.x;
+       dir.z = pos.y;
+       break;
 
       case CUBEFACE_POS_Y:
 
-    dir.x = pos.x;
-    dir.y = 1;
-    dir.z = pos.y;
-    break;
+       dir.x = pos.x;
+       dir.y = 1;
+       dir.z = pos.y;
+       break;
 
       case CUBEFACE_NEG_Y:
 
-    dir.x = pos.x;
-    dir.y = -1;
-    dir.z = pos.y;
-    break;
+       dir.x = pos.x;
+       dir.y = -1;
+       dir.z = pos.y;
+       break;
 
       case CUBEFACE_POS_Z:
 
-    dir.x = pos.x;
-    dir.y = pos.y;
-    dir.z = 1;
-    break;
+       dir.x = pos.x;
+       dir.y = pos.y;
+       dir.z = 1;
+       break;
 
       case CUBEFACE_NEG_Z:
 
-    dir.x = pos.x;
-    dir.y = pos.y;
-    dir.z = -1;
-    break;
+       dir.x = pos.x;
+       dir.y = pos.y;
+       dir.z = -1;
+       break;
     }
 
     return dir;
 }
 
 } // namespace CubeMap
-} // namespace Imf
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index b82ca52..16e4ee3 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include "ImathBox.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //--------------------------------
 // Supported environment map types
@@ -116,7 +119,8 @@ namespace LatLongMap
     // and longitude.
     //----------------------------------------------------
 
-    Imath::V2f         latLong (const Imath::V3f &direction);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f               latLong (const IMATH_NAMESPACE::V3f &direction);
 
 
     //--------------------------------------------------------
@@ -125,8 +129,9 @@ namespace LatLongMap
     // and longitude.
     //--------------------------------------------------------
 
-    Imath::V2f         latLong (const Imath::Box2i &dataWindow,
-                 const Imath::V2f &pixelPosition);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f               latLong (const IMATH_NAMESPACE::Box2i &dataWindow,
+                                const IMATH_NAMESPACE::V2f &pixelPosition);
 
 
     //-------------------------------------------------------------
@@ -134,8 +139,9 @@ namespace LatLongMap
     // longitude and latitude, into a corresponding pixel position.
     //-------------------------------------------------------------
 
-    Imath::V2f         pixelPosition (const Imath::Box2i &dataWindow,
-                       const Imath::V2f &latLong);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f               pixelPosition (const IMATH_NAMESPACE::Box2i &dataWindow,
+                                      const IMATH_NAMESPACE::V2f &latLong);
 
 
     //-----------------------------------------------------
@@ -144,8 +150,9 @@ namespace LatLongMap
     // to pixelPosition(dw,latLong(dw,dir)).
     //-----------------------------------------------------
 
-    Imath::V2f         pixelPosition (const Imath::Box2i &dataWindow,
-                       const Imath::V3f &direction);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f               pixelPosition (const IMATH_NAMESPACE::Box2i &dataWindow,
+                                      const IMATH_NAMESPACE::V3f &direction);
 
 
     //--------------------------------------------------------
@@ -153,8 +160,9 @@ namespace LatLongMap
     // map into a corresponding 3D direction.
     //--------------------------------------------------------
 
-    Imath::V3f         direction (const Imath::Box2i &dataWindow,
-                   const Imath::V2f &pixelPosition);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V3f               direction (const IMATH_NAMESPACE::Box2i &dataWindow,
+                                  const IMATH_NAMESPACE::V2f &pixelPosition);
 }
 
 
@@ -177,10 +185,10 @@ namespace LatLongMap
 //      |           | /       /
 //      |           |/       /
 //      4-----------5       Z
-//
+// 
 //   dataWindow.min
 //        /
-//       /
+//       / 
 //      +-----------+
 //      |3    Y    7|
 //      |     |     |
@@ -237,7 +245,7 @@ namespace LatLongMap
 // The size of the data window should be N by 6*N pixels
 // (width by height), where N can be any integer greater
 // than 0.
-//
+// 
 //--------------------------------------------------------------
 
 //------------------------------------
@@ -260,7 +268,8 @@ namespace CubeMap
     // Width and height of a cube's face, in pixels
     //---------------------------------------------
 
-    int                        sizeOfFace (const Imath::Box2i &dataWindow);
+    IMF_EXPORT 
+    int                        sizeOfFace (const IMATH_NAMESPACE::Box2i &dataWindow);
 
 
     //------------------------------------------
@@ -268,8 +277,9 @@ namespace CubeMap
     // that is covered by the specified face.
     //------------------------------------------
 
-    Imath::Box2i       dataWindowForFace (CubeMapFace face,
-                       const Imath::Box2i &dataWindow);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::Box2i     dataWindowForFace (CubeMapFace face,
+                                          const IMATH_NAMESPACE::Box2i &dataWindow);
 
 
     //----------------------------------------------------
@@ -279,9 +289,10 @@ namespace CubeMap
     // in the environment map.
     //----------------------------------------------------
 
-    Imath::V2f         pixelPosition (CubeMapFace face,
-                       const Imath::Box2i &dataWindow,
-                       Imath::V2f positionInFace);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V2f               pixelPosition (CubeMapFace face,
+                                      const IMATH_NAMESPACE::Box2i &dataWindow,
+                                      IMATH_NAMESPACE::V2f positionInFace);
 
 
     //--------------------------------------------------------------
@@ -300,23 +311,26 @@ namespace CubeMap
     //
     //--------------------------------------------------------------
 
-    void               faceAndPixelPosition (const Imath::V3f &direction,
-                          const Imath::Box2i &dataWindow,
-                          CubeMapFace &face,
-                          Imath::V2f &positionInFace);
-
+    IMF_EXPORT 
+    void               faceAndPixelPosition (const IMATH_NAMESPACE::V3f &direction,
+                                             const IMATH_NAMESPACE::Box2i &dataWindow,
+                                             CubeMapFace &face,
+                                             IMATH_NAMESPACE::V2f &positionInFace);
 
+   
     // --------------------------------------------------------
     // Given a cube face and a pixel position within that face,
     // compute the corresponding 3D direction.
     // --------------------------------------------------------
 
-    Imath::V3f         direction (CubeMapFace face,
-                   const Imath::Box2i &dataWindow,
-                   const Imath::V2f &positionInFace);
+    IMF_EXPORT 
+    IMATH_NAMESPACE::V3f               direction (CubeMapFace face,
+                                  const IMATH_NAMESPACE::Box2i &dataWindow,
+                                  const IMATH_NAMESPACE::V2f &positionInFace);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
index a0eefc5..b6f88c2 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,8 +42,9 @@
 #include <ImfEnvmapAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ EnvmapAttribute::staticTypeName ()
 
 template <>
 void
-EnvmapAttribute::writeValueTo (OStream &os, int) const
+EnvmapAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     unsigned char tmp = _value;
     Xdr::write <StreamIO> (os, tmp);
@@ -64,7 +65,7 @@ EnvmapAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-EnvmapAttribute::readValueFrom (IStream &is, int, int)
+EnvmapAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned char tmp;
     Xdr::read <StreamIO> (is, tmp);
@@ -72,4 +73,4 @@ EnvmapAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 6ac73aa..0d0129b 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfEnvmap.h>
+#include "ImfAttribute.h"
+#include "ImfEnvmap.h"
+#include "ImfExport.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Envmap> EnvmapAttribute;
 
-typedef TypedAttribute<Envmap> EnvmapAttribute;
-template <> const char *EnvmapAttribute::staticTypeName ();
-template <> void EnvmapAttribute::writeValueTo (OStream &, int) const;
-template <> void EnvmapAttribute::readValueFrom (IStream &, int, int);
+template <> IMF_EXPORT const char *EnvmapAttribute::staticTypeName ();
 
+template <> IMF_EXPORT
+void EnvmapAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                    int) const;
 
-} // namespace Imf
+template <> IMF_EXPORT
+void EnvmapAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                     int,
+                                     int);
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfEnvmapAttribute.cpp>
-#endif
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfExport.h b/3rdparty/openexr/IlmImf/ImfExport.h
new file mode 100644 (file)
index 0000000..6563fd5
--- /dev/null
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(ILMIMF_EXPORTS)
+           #define IMF_EXPORT __declspec(dllexport)
+        #define IMF_EXPORT_CONST extern __declspec(dllexport)
+    #else
+           #define IMF_EXPORT __declspec(dllimport)
+           #define IMF_EXPORT_CONST extern __declspec(dllimport)
+    #endif
+#else
+    #define IMF_EXPORT
+    #define IMF_EXPORT_CONST extern const
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfFastHuf.cpp b/3rdparty/openexr/IlmImf/ImfFastHuf.cpp
new file mode 100644 (file)
index 0000000..e581c0f
--- /dev/null
@@ -0,0 +1,768 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfFastHuf.h"
+#include <Iex.h>
+
+#include <string.h>
+#include <assert.h>
+#include <math.h>
+#include <vector>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+//
+// Adapted from hufUnpackEncTable - 
+// We don't need to reconstruct the code book, just the encoded
+// lengths for each symbol. From the lengths, we can build the
+// base + offset tables. This should be a bit more efficient
+// for sparse code books.
+// 
+//   table     - ptr to the start of the code length data. Will be
+//               updated as we decode data
+//
+//   numBytes  - size of the encoded table (I think)?
+//
+//   minSymbol - smallest symbol in the code book
+//
+//   maxSymbol - largest symbol in the code book. 
+//
+//   rleSymbol - the symbol to trigger RLE in the encoded bitstream
+//
+
+FastHufDecoder::FastHufDecoder
+    (const char *&table,
+     int numBytes,
+     int minSymbol,
+     int maxSymbol,
+     int rleSymbol)
+:
+    _rleSymbol (rleSymbol),
+    _numSymbols (0),
+    _minCodeLength (255),
+    _maxCodeLength (0),
+    _idToSymbol (0)
+{
+    //
+    // List of symbols that we find with non-zero code lengths
+    // (listed in the order we find them). Store these in the
+    // same format as the code book stores codes + lengths - 
+    // low 6 bits are the length, everything above that is
+    // the symbol.
+    //
+
+    std::vector<Int64> symbols;
+
+    //
+    // The 'base' table is the minimum code at each code length. base[i]
+    // is the smallest code (numerically) of length i.
+    //
+
+    Int64 base[MAX_CODE_LEN + 1];     
+
+    //
+    // The 'offset' table is the position (in sorted order) of the first id
+    // of a given code lenght. Array is indexed by code length, like base.  
+    //
+
+    Int64 offset[MAX_CODE_LEN + 1];   
+
+    //
+    // Count of how many codes at each length there are. Array is 
+    // indexed by code length, like base and offset.
+    //
+
+    size_t codeCount[MAX_CODE_LEN + 1];    
+
+    for (int i = 0; i <= MAX_CODE_LEN; ++i)
+    {
+        codeCount[i] = 0;
+        base[i]      = 0xffffffffffffffffULL;
+        offset[i]    = 0;
+    }
+
+    //
+    // Count the number of codes, the min/max code lengths, the number of
+    // codes with each length, and record symbols with non-zero code
+    // length as we find them.
+    //
+
+    const char *currByte     = table;
+    Int64       currBits     = 0;
+    int         currBitCount = 0;
+
+    const int SHORT_ZEROCODE_RUN = 59;
+    const int LONG_ZEROCODE_RUN  = 63;
+    const int SHORTEST_LONG_RUN  = 2 + LONG_ZEROCODE_RUN - SHORT_ZEROCODE_RUN;
+
+    for (Int64 symbol = minSymbol; symbol <= maxSymbol; symbol++)
+    {
+        if (currByte - table > numBytes)
+        {
+            throw IEX_NAMESPACE::InputExc ("Error decoding Huffman table "
+                                           "(Truncated table data).");
+        }
+
+        //
+        // Next code length - either:
+        //       0-58  (literal code length)
+        //       59-62 (various lengths runs of 0)
+        //       63    (run of n 0's, with n is the next 8 bits)
+        //
+
+        Int64 codeLen = readBits (6, currBits, currBitCount, currByte);
+
+        if (codeLen == (Int64) LONG_ZEROCODE_RUN)
+        {
+            if (currByte - table > numBytes)
+            {
+                throw IEX_NAMESPACE::InputExc ("Error decoding Huffman table "
+                                               "(Truncated table data).");
+            }
+
+            int runLen = readBits (8, currBits, currBitCount, currByte) +
+                         SHORTEST_LONG_RUN;
+
+            if (symbol + runLen > maxSymbol + 1)
+            {
+                throw IEX_NAMESPACE::InputExc ("Error decoding Huffman table "
+                                               "(Run beyond end of table).");
+            }
+            
+            symbol += runLen - 1;
+
+        }
+        else if (codeLen >= (Int64) SHORT_ZEROCODE_RUN)
+        {
+            int runLen = codeLen - SHORT_ZEROCODE_RUN + 2;
+
+            if (symbol + runLen > maxSymbol + 1)
+            {
+                throw IEX_NAMESPACE::InputExc ("Error decoding Huffman table "
+                                               "(Run beyond end of table).");
+            }
+
+            symbol += runLen - 1;
+
+        }
+        else if (codeLen != 0)
+        {
+            symbols.push_back ((symbol << 6) | (codeLen & 63));
+
+            if (codeLen < _minCodeLength)
+                _minCodeLength = codeLen;
+
+            if (codeLen > _maxCodeLength)
+                _maxCodeLength = codeLen;
+
+            codeCount[codeLen]++;
+        }
+    }
+
+    for (int i = 0; i < MAX_CODE_LEN; ++i)
+        _numSymbols += codeCount[i];
+
+    table = currByte;
+
+    //
+    // Compute base - once we have the code length counts, there
+    //                is a closed form solution for this
+    //
+
+    {
+        double* countTmp = new double[_maxCodeLength+1];
+
+        for (int l = _minCodeLength; l <= _maxCodeLength; ++l)
+        {
+            countTmp[l] = (double)codeCount[l] * 
+                          (double)(2 << (_maxCodeLength-l));
+        }
+    
+        for (int l = _minCodeLength; l <= _maxCodeLength; ++l)
+        {
+            double tmp = 0;
+
+            for (int k =l + 1; k <= _maxCodeLength; ++k)
+                tmp += countTmp[k];
+            
+            tmp /= (double)(2 << (_maxCodeLength - l));
+
+            base[l] = (Int64)ceil (tmp);
+        }
+
+        delete [] countTmp;
+    }
+   
+    //
+    // Compute offset - these are the positions of the first
+    //                  id (not symbol) that has length [i]
+    //
+
+    offset[_maxCodeLength] = 0;
+
+    for (int i= _maxCodeLength - 1; i >= _minCodeLength; i--)
+        offset[i] = offset[i + 1] + codeCount[i + 1];
+
+    //
+    // Allocate and fill the symbol-to-id mapping. Smaller Ids should be
+    // mapped to less-frequent symbols (which have longer codes). Use
+    // the offset table to tell us where the id's for a given code 
+    // length start off.
+    //
+
+    _idToSymbol = new int[_numSymbols];
+
+    Int64 mapping[MAX_CODE_LEN + 1];
+    for (int i = 0; i < MAX_CODE_LEN + 1; ++i) 
+        mapping[i] = -1;
+    for (int i = _minCodeLength; i <= _maxCodeLength; ++i)
+        mapping[i] = offset[i];
+
+    for (std::vector<Int64>::const_iterator i = symbols.begin(); 
+         i != symbols.end();
+         ++i)
+    {
+        int codeLen = *i & 63;
+        int symbol  = *i >> 6;
+
+        if (mapping[codeLen] >= _numSymbols)
+            throw IEX_NAMESPACE::InputExc ("Huffman decode error "
+                                           "(Invalid symbol in header).");
+        
+        _idToSymbol[mapping[codeLen]] = symbol;
+        mapping[codeLen]++;
+    }
+
+    buildTables(base, offset);
+}
+
+
+FastHufDecoder::~FastHufDecoder()
+{
+    delete[] _idToSymbol;
+}
+
+
+//
+// Static check if the decoder is enabled.
+//
+// ATM, I only have access to little endian hardware for testing,
+// so I'm not entirely sure that we are reading fom the bit stream
+// properly on BE. 
+//
+// If you happen to have more obscure hardware, check that the 
+// byte swapping in refill() is happening sensable, add an endian 
+// check if needed, and fix the preprocessor magic here.
+//
+
+#define READ64(c) \
+    ((Int64)(c)[0] << 56) | ((Int64)(c)[1] << 48) | ((Int64)(c)[2] << 40) | \
+    ((Int64)(c)[3] << 32) | ((Int64)(c)[4] << 24) | ((Int64)(c)[5] << 16) | \
+    ((Int64)(c)[6] <<  8) | ((Int64)(c)[7] ) 
+
+#ifdef __INTEL_COMPILER // ICC built-in swap for LE hosts
+    #if defined (__i386__) || defined(__x86_64__)
+        #undef  READ64
+        #define READ64(c) _bswap64 (*(const Int64*)(c))
+    #endif
+#endif
+
+
+bool
+FastHufDecoder::enabled()
+{
+    #if defined(__INTEL_COMPILER) || defined(__GNUC__)  
+
+        //
+        // Enabled for ICC, GCC:
+        //       __i386__   -> x86
+        //       __x86_64__ -> 64-bit x86
+        //
+
+        #if defined (__i386__) || defined(__x86_64__)
+            return true;
+        #else
+            return false;
+        #endif
+
+    #elif defined (_MSC_VER)
+
+        //
+        // Enabled for Visual Studio:
+        //        _M_IX86 -> x86
+        //        _M_X64  -> 64bit x86
+
+        #if defined (_M_IX86) || defined(_M_X64)
+            return true;
+        #else
+            return false;
+        #endif
+
+    #else
+
+        //
+        // Unknown compiler - Be safe and disable.
+        //
+        return false;
+    #endif
+}
+
+//
+//
+// Built the acceleration tables for lookups on the upper bits
+// as well as the 'LJ' tables.
+//
+
+void
+FastHufDecoder::buildTables (Int64 *base, Int64 *offset)
+{
+    //
+    // Build the 'left justified' base table, by shifting base left..
+    //
+
+    for (int i = 0; i <= MAX_CODE_LEN; ++i)
+    {
+        if (base[i] != 0xffffffffffffffffULL)
+        {
+            _ljBase[i] = base[i] << (64 - i);
+        }
+        else
+        {
+            //
+            // Unused code length - insert dummy values
+            //
+
+            _ljBase[i] = 0xffffffffffffffffULL;
+        }
+    }
+
+    //
+    // Combine some terms into a big fat constant, which for
+    // lack of a better term we'll call the 'left justified' 
+    // offset table (because it serves the same function
+    // as 'offset', when using the left justified base table.
+    //
+
+    for (int i = 0; i <= MAX_CODE_LEN; ++i)
+        _ljOffset[i] = offset[i] - (_ljBase[i] >> (64 - i));
+
+    //
+    // Build the acceleration tables for the lookups of
+    // short codes ( <= TABLE_LOOKUP_BITS long)
+    //
+
+    for (Int64 i = 0; i < 1 << TABLE_LOOKUP_BITS; ++i)
+    {
+        Int64 value = i << (64 - TABLE_LOOKUP_BITS);
+
+        _tableSymbol[i]  = 0xffff;
+        _tableCodeLen[i] = 0; 
+
+        for (int codeLen = _minCodeLength; codeLen <= _maxCodeLength; ++codeLen)
+        {
+            if (_ljBase[codeLen] <= value)
+            {
+                _tableCodeLen[i] = codeLen;
+
+                Int64 id = _ljOffset[codeLen] + (value >> (64 - codeLen));
+                if (id < _numSymbols)
+                {
+                    _tableSymbol[i] = _idToSymbol[id];
+                }
+                else
+                {
+                    throw IEX_NAMESPACE::InputExc ("Huffman decode error "
+                                                   "(Overrun).");
+                }
+                break;
+            }
+        }
+    }
+
+    //
+    // Store the smallest value in the table that points to real data.
+    // This should be the entry for the largest length that has 
+    // valid data (in our case, non-dummy _ljBase)
+    //
+
+    int minIdx = TABLE_LOOKUP_BITS;
+
+    while (minIdx > 0 && _ljBase[minIdx] == 0xffffffffffffffffULL)
+        minIdx--;
+
+    if (minIdx < 0)
+    {
+        //
+        // Error, no codes with lengths 0-TABLE_LOOKUP_BITS used.
+        // Set the min value such that the table is never tested.
+        //
+
+        _tableMin = 0xffffffffffffffffULL;
+    }
+    else
+    {
+        _tableMin = _ljBase[minIdx];
+    }
+}
+
+
+// 
+// For decoding, we're holding onto 2 Int64's. 
+//
+// The first (buffer), holds the next bits from the bitstream to be 
+// decoded. For certain paths in the decoder, we only need TABLE_LOOKUP_BITS
+// valid bits to decode the next symbol. For other paths, we need a full
+// 64-bits to decode a symbol. 
+//
+// When we need to refill 'buffer', we could pull bits straight from 
+// the bitstream. But this is very slow and requires lots of book keeping
+// (what's the next bit in the next byte?). Instead, we keep another Int64
+// around that we use to refill from. While this doesn't cut down on the
+// book keeping (still need to know how many valid bits), it does cut
+// down on some of the bit shifting crazy and byte access. 
+//
+// The refill Int64 (bufferBack) gets left-shifted after we've pulled
+// off bits. If we run out of bits in the input bit stream, we just
+// shift in 0's to bufferBack. 
+//
+// The refill act takes numBits from the top of bufferBack and sticks
+// them in the bottom of buffer. If there arn't enough bits in bufferBack,
+// it gets refilled (to 64-bits) from the input bitstream.
+//
+
+inline void
+FastHufDecoder::refill
+    (Int64 &buffer,
+     int numBits,                       // number of bits to refill
+     Int64 &bufferBack,                 // the next 64-bits, to refill from
+     int &bufferBackNumBits,            // number of bits left in bufferBack
+     const unsigned char *&currByte,    // current byte in the bitstream
+     int &currBitsLeft)                 // number of bits left in the bitsream
+{
+    // 
+    // Refill bits into the bottom of buffer, from the top of bufferBack.
+    // Always top up buffer to be completely full.
+    //
+
+    buffer |= bufferBack >> (64 - numBits);
+
+    if (bufferBackNumBits < numBits)
+    {
+        numBits -= bufferBackNumBits;
+
+        // 
+        // Refill all of bufferBack from the bitstream. Either grab
+        // a full 64-bit chunk, or whatever bytes are left. If we
+        // don't have 64-bits left, pad with 0's.
+        //
+
+        if (currBitsLeft >= 64)
+        {
+            bufferBack        = READ64 (currByte); 
+            bufferBackNumBits = 64;
+            currByte         += sizeof (Int64);
+            currBitsLeft     -= 8 * sizeof (Int64);
+
+        }
+        else
+        {
+            bufferBack        = 0;
+            bufferBackNumBits = 64; 
+
+            Int64 shift = 56;
+            
+            while (currBitsLeft > 0)
+            {
+                bufferBack |= ((Int64)(*currByte)) << shift;
+
+                currByte++;
+                shift        -= 8;
+                currBitsLeft -= 8;
+            }
+
+            //
+            // At this point, currBitsLeft might be negative, just because
+            // we're subtracting whole bytes. To keep anyone from freaking
+            // out, zero the counter.
+            //
+
+            if (currBitsLeft < 0)
+                currBitsLeft = 0;
+        }
+
+        buffer |= bufferBack >> (64 - numBits);
+    }
+    
+    bufferBack         = bufferBack << numBits;
+    bufferBackNumBits -= numBits;
+
+    // 
+    // We can have cases where the previous shift of bufferBack is << 64 - 
+    // in which case no shift occurs. The bit count math still works though,
+    // so if we don't have any bits left, zero out bufferBack.
+    //
+
+    if (bufferBackNumBits == 0)
+        bufferBack = 0;
+}
+
+//
+// Read the next few bits out of a bitstream. Will be given a backing buffer
+// (buffer) that may still have data left over from previous reads
+// (bufferNumBits).  Bitstream pointer (currByte) will be advanced when needed.
+//
+
+inline Int64 
+FastHufDecoder::readBits
+    (int numBits,
+     Int64 &buffer,             // c
+     int &bufferNumBits,        // lc
+     const char *&currByte)     // in
+{
+    while (bufferNumBits < numBits)
+    {
+        buffer = (buffer << 8) | *(unsigned char*)(currByte++);
+        bufferNumBits += 8;
+    }
+
+    bufferNumBits -= numBits;
+    return (buffer >> bufferNumBits) & ((1 << numBits) - 1);
+}
+
+
+//
+// Decode using a the 'One-Shift' strategy for decoding, with a 
+// small-ish table to accelerate decoding of short codes.
+//
+// If possible, try looking up codes into the acceleration table.
+// This has a few benifits - there's no search involved; We don't
+// need an additional lookup to map id to symbol; we don't need
+// a full 64-bits (so less refilling). 
+//
+
+void
+FastHufDecoder::decode
+    (const unsigned char *src,
+     int numSrcBits,
+     unsigned short *dst, 
+     int numDstElems)
+{
+    if (numSrcBits < 128)
+        throw IEX_NAMESPACE::InputExc ("Error choosing Huffman decoder implementation "
+                                       "(insufficient number of bits).");
+
+    //
+    // Current position (byte/bit) in the src data stream
+    // (after the first buffer fill)
+    //
+
+    const unsigned char *currByte = src + 2 * sizeof (Int64);
+
+    numSrcBits -= 8 * 2 * sizeof (Int64);
+
+    //
+    // 64-bit buffer holding the current bits in the stream
+    //
+
+    Int64 buffer            = READ64 (src); 
+    int   bufferNumBits     = 64;
+
+    //
+    // 64-bit buffer holding the next bits in the stream
+    //
+
+    Int64 bufferBack        = READ64 ((src + sizeof (Int64))); 
+    int   bufferBackNumBits = 64;
+
+    int dstIdx = 0;
+
+    while (dstIdx < numDstElems)
+    {
+        int  codeLen;
+        int  symbol;
+
+        //
+        // Test if we can be table accelerated. If so, directly
+        // lookup the output symbol. Otherwise, we need to fall
+        // back to searching for the code.
+        //
+        // If we're doing table lookups, we don't really need
+        // a re-filled buffer, so long as we have TABLE_LOOKUP_BITS
+        // left. But for a search, we do need a refilled table.
+        //
+
+        if (_tableMin <= buffer)
+        {
+            int tableIdx = buffer >> (64 - TABLE_LOOKUP_BITS);
+
+            // 
+            // For invalid codes, _tableCodeLen[] should return 0. This
+            // will cause the decoder to get stuck in the current spot
+            // until we run out of elements, then barf that the codestream
+            // is bad.  So we don't need to stick a condition like
+            //     if (codeLen > _maxCodeLength) in this inner.
+            //
+
+            codeLen = _tableCodeLen[tableIdx];
+            symbol  = _tableSymbol[tableIdx];
+        }
+        else
+        {
+            if (bufferNumBits < 64)
+            {
+                refill (buffer,
+                        64 - bufferNumBits,
+                        bufferBack,
+                        bufferBackNumBits,
+                        currByte,
+                        numSrcBits);
+
+                bufferNumBits = 64;
+            }
+
+            // 
+            // Brute force search: 
+            // Find the smallest length where _ljBase[length] <= buffer
+            //
+
+            codeLen = TABLE_LOOKUP_BITS + 1;
+
+            while (_ljBase[codeLen] > buffer && codeLen <= _maxCodeLength)
+                codeLen++;
+
+            if (codeLen > _maxCodeLength)
+            {
+                throw IEX_NAMESPACE::InputExc ("Huffman decode error "
+                                               "(Decoded an invalid symbol).");
+            }
+
+            Int64 id = _ljOffset[codeLen] + (buffer >> (64 - codeLen));
+            if (id < _numSymbols)
+            {
+                symbol = _idToSymbol[id];
+            }
+            else
+            {
+                throw IEX_NAMESPACE::InputExc ("Huffman decode error "
+                                               "(Decoded an invalid symbol).");
+            }
+        }
+
+        //
+        // Shift over bit stream, and update the bit count in the buffer
+        //
+
+        buffer = buffer << codeLen;
+        bufferNumBits -= codeLen;
+
+        //
+        // If we recieved a RLE symbol (_rleSymbol), then we need
+        // to read ahead 8 bits to know how many times to repeat
+        // the previous symbol. Need to ensure we at least have
+        // 8 bits of data in the buffer
+        //
+
+        if (symbol == _rleSymbol)
+        {
+            if (bufferNumBits < 8)
+            {
+                refill (buffer,
+                        64 - bufferNumBits,
+                        bufferBack,
+                        bufferBackNumBits,
+                        currByte,
+                        numSrcBits);
+
+                bufferNumBits = 64;
+            }
+
+            int rleCount = buffer >> 56;
+
+            if (dstIdx < 1)
+            {
+                throw IEX_NAMESPACE::InputExc ("Huffman decode error (RLE code "
+                                               "with no previous symbol).");
+            }
+
+            if (dstIdx + rleCount > numDstElems)
+            {
+                throw IEX_NAMESPACE::InputExc ("Huffman decode error (Symbol run "
+                                               "beyond expected output buffer length).");
+            }
+
+            if (rleCount <= 0) 
+            {
+                throw IEX_NAMESPACE::InputExc("Huffman decode error"
+                                              " (Invalid RLE length)");
+            }
+
+            for (int i = 0; i < rleCount; ++i)
+                dst[dstIdx + i] = dst[dstIdx - 1];
+
+            dstIdx += rleCount;
+
+            buffer = buffer << 8;
+            bufferNumBits -= 8;
+        }
+        else
+        {
+            dst[dstIdx] = symbol;
+            dstIdx++;
+        }
+
+        //
+        // refill bit stream buffer if we're below the number of 
+        // bits needed for a table lookup
+        //
+
+        if (bufferNumBits < TABLE_LOOKUP_BITS)
+        {
+            refill (buffer,
+                    64 - bufferNumBits,
+                    bufferBack,
+                    bufferBackNumBits,
+                    currByte,
+                    numSrcBits);
+
+            bufferNumBits = 64;
+        }
+    }
+
+    if (numSrcBits != 0)
+    {
+        throw IEX_NAMESPACE::InputExc ("Huffman decode error (Compressed data remains "
+                                       "after filling expected output buffer).");
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfFastHuf.h b/3rdparty/openexr/IlmImf/ImfFastHuf.h
new file mode 100644 (file)
index 0000000..c8c84fd
--- /dev/null
@@ -0,0 +1,153 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_FAST_HUF_H
+#define INCLUDED_IMF_FAST_HUF_H
+
+#include "ImfInt64.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Alternative Canonical Huffman decoder:
+//
+// Canonical Huffman decoder based on 'On the Implementation of Minimum
+// Redundancy Prefix Codes' by Moffat and Turpin - highly recommended
+// reading as a good description of the problem space, as well as 
+// a fast decoding algorithm.
+//
+// The premise is that instead of working directly with the coded 
+// symbols, we create a new ordering based on the frequency of symbols.
+// Less frequent symbols (and thus longer codes) are ordered earler.
+// We're calling the values in this ordering 'Ids', as oppsed to 
+// 'Symbols' - which are the short values we eventually want decoded.
+//
+// With this new ordering, a few small tables can be derived ('base' 
+// and 'offset') which drive the decoding. To cut down on the 
+// linear scanning of these tables, you can add a small table
+// to directly look up short codes (as you might in a traditional
+// lookup-table driven decoder). 
+//
+// The decoder is meant to be compatible with the encoder (and decoder)
+// in ImfHuf.cpp, just faster. For ease of implementation, this decoder
+// should only be used on compressed bitstreams >= 128 bits long.
+//
+
+class FastHufDecoder
+{
+  public:
+
+    //
+    // Longest compressed code length that ImfHuf supports (58 bits)
+    //
+
+    static const int MAX_CODE_LEN = 58;
+
+    //
+    // Number of bits in our acceleration table. Should match all
+    // codes up to TABLE_LOOKUP_BITS in length.
+    //
+
+    static const int TABLE_LOOKUP_BITS = 12;
+
+    IMF_EXPORT
+    FastHufDecoder (const char*& table,
+                    int numBytes,
+                    int minSymbol,
+                    int maxSymbol,
+                    int rleSymbol);
+
+    IMF_EXPORT
+    ~FastHufDecoder ();
+
+    IMF_EXPORT
+    static bool enabled ();
+
+    IMF_EXPORT
+    void decode (const unsigned char *src,
+                 int numSrcBits,
+                 unsigned short *dst,
+                 int numDstElems);
+
+  private:
+
+    void  buildTables (Int64*, Int64*);
+    void  refill (Int64&, int, Int64&, int&, const unsigned char *&, int&);
+    Int64 readBits (int, Int64&, int&, const char *&);
+
+    int             _rleSymbol;        // RLE symbol written by the encoder.
+                                       // This could be 65536, so beware
+                                       // when you use shorts to hold things.
+
+    int             _numSymbols;       // Number of symbols in the codebook.
+
+    unsigned char   _minCodeLength;    // Minimum code length, in bits.
+    unsigned char   _maxCodeLength;    // Maximum code length, in bits.
+
+    int            *_idToSymbol;       // Maps Ids to symbols. Ids are a symbol
+                                       // ordering sorted first in terms of 
+                                       // code length, and by code within
+                                       // the same length. Ids run from 0
+                                       // to mNumSymbols-1.
+
+    Int64 _ljBase[MAX_CODE_LEN + 1];   // the 'left justified base' table.
+                                       // Takes base[i] (i = code length)
+                                       // and 'left justifies' it into an Int64
+
+    Int64 _ljOffset[MAX_CODE_LEN +1 ]; // There are some other terms that can 
+                                       // be folded into constants when taking
+                                       // the 'left justified' decode path. This
+                                       // holds those constants, indexed by
+                                       // code length
+
+    //
+    // We can accelerate the 'left justified' processing by running the
+    // top TABLE_LOOKUP_BITS through a LUT, to find the symbol and code
+    // length. These are those acceleration tables.
+    //
+    // Even though our evental 'symbols' are ushort's, the encoder adds
+    // a symbol to indicate RLE. So with a dense code book, we could
+    // have 2^16+1 codes, so both mIdToSymbol and mTableSymbol need
+    // to be bigger than 16 bits.
+    //
+
+    int            _tableSymbol[1 << TABLE_LOOKUP_BITS];
+    unsigned char  _tableCodeLen[1 << TABLE_LOOKUP_BITS];
+    Int64          _tableMin;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif 
index 3896cca..4e22e90 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,7 +43,7 @@
 #include <ImfFloatAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 template <>
@@ -54,4 +54,4 @@ FloatAttribute::staticTypeName ()
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 95eaff6..7370721 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<float> FloatAttribute;
-template <> const char *FloatAttribute::staticTypeName ();
+template <> IMF_EXPORT const char *FloatAttribute::staticTypeName ();
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfFloatAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2013, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 ///////////////////////////////////////////////////////////////////////////
 
-//---------------------------------------------------------------------------
-//
-//     b44ExpLogTable
-//
-//     A program to generate lookup tables for
-//
-//             y = exp (x / 8)
-//
-//     and
-//             x = 8 * log (x);
-//
-//     where x and y are 16-bit floating-point numbers
+
+//-----------------------------------------------------------------------------
 //
-//     The tables are used by class B44Compressor.
+//     class FloatVectorAttribute
 //
-//---------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
 
-#include <half.h>
-#include <math.h>
-#include <iostream>
-#include <iomanip>
+#include <ImfFloatVectorAttribute.h>
 
-using namespace std;
-
-//---------------------------------------------
-// Main - prints the half-to-float lookup table
-//---------------------------------------------
-
-int
-main ()
-{
-#ifndef HAVE_IOS_BASE
-    cout.setf (ios::hex, ios::basefield);
-#else
-    cout.setf (ios_base::hex, ios_base::basefield);
-#endif
 
-    cout << "//\n"
-        "// This is an automatically generated file.\n"
-        "// Do not edit.\n"
-        "//\n\n";
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-    const int iMax = (1 << 16);
 
-    cout << "const unsigned short expTable[] =\n"
-        "{\n"
-        "    ";
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
-    for (int i = 0; i < iMax; i++)
-    {
-    half h;
-    h.setBits (i);
 
-    if (!h.isFinite())
-        h = 0;
-    else if (h >= 8 * log (HALF_MAX))
-        h = HALF_MAX;
-    else
-        h = exp (h / 8);
-
-    cout << "0x" << setfill ('0') << setw (4) << h.bits() << ", ";
-
-    if (i % 8 == 7)
-    {
-        cout << "\n";
-
-        if (i < iMax - 1)
-        cout << "    ";
-    }
-    }
-
-    cout << "};\n\n";
+template <>
+const char *
+FloatVectorAttribute::staticTypeName ()
+{
+    return "floatvector";
+}
 
-    cout << "const unsigned short logTable[] =\n"
-        "{\n"
-        "    ";
 
-    for (int i = 0; i < iMax; i++)
-    {
-    half h;
-    h.setBits (i);
+template <>
+void
+FloatVectorAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
+{
+    int n = _value.size();
 
-    if (!h.isFinite() || h < 0)
-        h = 0;
-    else
-        h = 8 * log (h);
+    for (int i = 0; i < n; ++i)
+        Xdr::write <StreamIO> (os, _value[i]);
+}
 
-    cout << "0x" << setfill ('0') << setw (4) << h.bits() << ", ";
 
-    if (i % 8 == 7)
-    {
-        cout << "\n";
+template <>
+void
+FloatVectorAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
+{
+    int n = size / Xdr::size<float>();
+    _value.resize (n);
 
-        if (i < iMax - 1)
-        cout << "    ";
-    }
-    }
+    for (int i = 0; i < n; ++i)
+       Xdr::read <StreamIO> (is, _value[i]);
+}
 
-    cout << "};\n";
 
-    return 0;
-}
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
diff --git a/3rdparty/openexr/IlmImf/ImfFloatVectorAttribute.h b/3rdparty/openexr/IlmImf/ImfFloatVectorAttribute.h
new file mode 100644 (file)
index 0000000..66e7642
--- /dev/null
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2007, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef INCLUDED_IMF_FLOATVECTOR_ATTRIBUTE_H
+#define INCLUDED_IMF_FLOATVECTOR_ATTRIBUTE_H
+
+//-----------------------------------------------------------------------------
+//
+//     class FloatVectorAttribute
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfAttribute.h"
+#include "ImfNamespace.h"
+
+#include <vector>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+typedef std::vector<float>
+    FloatVector;
+
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::FloatVector>
+    FloatVectorAttribute;
+
+template <>
+IMF_EXPORT
+const char *FloatVectorAttribute::staticTypeName ();
+
+template <>
+IMF_EXPORT
+void FloatVectorAttribute::writeValueTo
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+
+template <>
+IMF_EXPORT
+void FloatVectorAttribute::readValueFrom
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfForward.h b/3rdparty/openexr/IlmImf/ImfForward.h
new file mode 100644 (file)
index 0000000..ea51c24
--- /dev/null
@@ -0,0 +1,127 @@
+
+
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// Portions (c) 2012 Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_FORWARD_H
+#define INCLUDED_IMF_FORWARD_H
+
+////////////////////////////////////////////////////////////////////
+//
+// Forward declarations for OpenEXR - correctly declares namespace
+//
+////////////////////////////////////////////////////////////////////
+
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+// classes for basic types;
+template<class T> class Array;
+template<class T> class Array2D;
+struct Channel;
+class  ChannelList;
+struct Chromaticities;
+
+// attributes used in headers are TypedAttributes
+class Attribute;
+
+class Header;
+
+// file handling classes
+class OutputFile;
+class TiledInputFile;
+class ScanLineInputFile;
+class InputFile;
+class TiledOutputFile;
+class DeepScanLineInputFile;
+class DeepScanLineOutputFile;
+class DeepTiledInputFile;
+class DeepTiledOutputFile;
+class AcesInputFile;
+class AcesOutputFile;
+class TiledInputPart;
+class TiledInputFile;
+class TileOffsets;
+
+// multipart file handling
+class GenericInputFile;
+class GenericOutputFile;
+class MultiPartInputFile;
+class MultiPartOutputFile;
+
+class InputPart;
+class TiledInputPart;
+class DeepScanLineInputPart;
+class DeepTiledInputPart;
+
+class OutputPart;
+class ScanLineOutputPart;
+class TiledOutputPart;
+class DeepScanLineOutputPart;
+class DeepTiledOutputPart;
+
+
+// internal use only
+struct InputPartData;
+struct OutputStreamMutex;
+struct OutputPartData;
+struct InputStreamMutex;
+
+// frame buffers
+
+class  FrameBuffer;
+class  DeepFrameBuffer;
+struct DeepSlice;
+
+// compositing
+class DeepCompositing;
+class CompositeDeepScanLine;
+
+// preview image
+class PreviewImage;
+struct PreviewRgba;
+
+// streams
+class OStream;
+class IStream;
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif // include guard
index 24f88db..bced3b1 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -36,8 +36,8 @@
 
 //-----------------------------------------------------------------------------
 //
-//     class Slice
-//     class FrameBuffer
+//      class Slice
+//      class FrameBuffer
 //
 //-----------------------------------------------------------------------------
 
 
 using namespace std;
 
-namespace Imf {
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 Slice::Slice (PixelType t,
-          char *b,
-          size_t xst,
-          size_t yst,
-          int xsm,
-          int ysm,
-          double fv,
+              char *b,
+              size_t xst,
+              size_t yst,
+              int xsm,
+              int ysm,
+              double fv,
               bool xtc,
               bool ytc)
 :
@@ -78,8 +80,8 @@ FrameBuffer::insert (const char name[], const Slice &slice)
 {
     if (name[0] == 0)
     {
-    THROW (Iex::ArgExc,
-           "Frame buffer slice name cannot be an empty string.");
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Frame buffer slice name cannot be an empty string.");
     }
 
     _map[name] = slice;
@@ -100,8 +102,8 @@ FrameBuffer::operator [] (const char name[])
 
     if (i == _map.end())
     {
-    THROW (Iex::ArgExc,
-           "Cannot find frame buffer slice \"" << name << "\".");
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
     }
 
     return i->second;
@@ -115,8 +117,8 @@ FrameBuffer::operator [] (const char name[]) const
 
     if (i == _map.end())
     {
-    THROW (Iex::ArgExc,
-           "Cannot find frame buffer slice \"" << name << "\".");
+        THROW (IEX_NAMESPACE::ArgExc,
+               "Cannot find frame buffer slice \"" << name << "\".");
     }
 
     return i->second;
@@ -223,4 +225,4 @@ FrameBuffer::find (const string &name) const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index bada3ca..e7ef247 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 //-----------------------------------------------------------------------------
 //
-//     class Slice
-//     class FrameBuffer
+//      class Slice
+//      class FrameBuffer
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfName.h>
-#include <ImfPixelType.h>
+#include "ImfName.h"
+#include "ImfPixelType.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 #include <map>
 #include <string>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-------------------------------------------------------
@@ -68,43 +71,43 @@ struct Slice
     // Data type; see ImfPixelType.h
     //------------------------------
 
-    PixelType          type;
+    PixelType           type;
 
 
     //---------------------------------------------------------------------
     // Memory layout:  The address of pixel (x, y) is
     //
-    // base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
+    //  base + (xp / xSampling) * xStride + (yp / ySampling) * yStride
     //
     // where xp and yp are computed as follows:
     //
-    // * If we are reading or writing a scanline-based file:
+    //  * If we are reading or writing a scanline-based file:
     //
-    //     xp = x
-    //     yp = y
+    //      xp = x
+    //      yp = y
     //
     //  * If we are reading a tile whose upper left coorner is at (xt, yt):
     //
-    //     if xTileCoords is true then xp = x - xt, else xp = x
-    //     if yTileCoords is true then yp = y - yt, else yp = y
+    //      if xTileCoords is true then xp = x - xt, else xp = x
+    //      if yTileCoords is true then yp = y - yt, else yp = y
     //
     //---------------------------------------------------------------------
 
-    char *             base;
-    size_t             xStride;
-    size_t             yStride;
+    char *              base;
+    size_t              xStride;
+    size_t              yStride;
 
 
     //--------------------------------------------
     // Subsampling: pixel (x, y) is present in the
-    // slice only if
+    // slice only if 
     //
     //  x % xSampling == 0 && y % ySampling == 0
     //
     //--------------------------------------------
 
-    int                        xSampling;
-    int                        ySampling;
+    int                 xSampling;
+    int                 ySampling;
 
 
     //----------------------------------------------------------
@@ -112,8 +115,8 @@ struct Slice
     // a channel that corresponds to this slice is read.
     //----------------------------------------------------------
 
-    double             fillValue;
-
+    double              fillValue;
+    
 
     //-------------------------------------------------------
     // For tiled files, the xTileCoords and yTileCoords flags
@@ -135,13 +138,14 @@ struct Slice
     // Constructor
     //------------
 
+    IMF_EXPORT
     Slice (PixelType type = HALF,
-       char * base = 0,
-       size_t xStride = 0,
-       size_t yStride = 0,
-       int xSampling = 1,
-       int ySampling = 1,
-       double fillValue = 0.0,
+           char * base = 0,
+           size_t xStride = 0,
+           size_t yStride = 0,
+           int xSampling = 1,
+           int ySampling = 1,
+           double fillValue = 0.0,
            bool xTileCoords = false,
            bool yTileCoords = false);
 };
@@ -155,35 +159,45 @@ class FrameBuffer
     // Add a slice
     //------------
 
-    void                       insert (const char name[],
-                    const Slice &slice);
+    IMF_EXPORT
+    void                        insert (const char name[],
+                                        const Slice &slice);
 
-    void                       insert (const std::string &name,
-                    const Slice &slice);
+    IMF_EXPORT
+    void                        insert (const std::string &name,
+                                        const Slice &slice);
 
     //----------------------------------------------------------------
     // Access to existing slices:
     //
-    // [n]             Returns a reference to the slice with name n.
-    //                 If no slice with name n exists, an Iex::ArgExc
-    //                 is thrown.
+    // [n]              Returns a reference to the slice with name n.
+    //                  If no slice with name n exists, an IEX_NAMESPACE::ArgExc
+    //                  is thrown.
     //
-    // findSlice(n)    Returns a pointer to the slice with name n,
-    //                 or 0 if no slice with name n exists.
+    // findSlice(n)     Returns a pointer to the slice with name n,
+    //                  or 0 if no slice with name n exists.
     //
     //----------------------------------------------------------------
 
-    Slice &                    operator [] (const char name[]);
-    const Slice &              operator [] (const char name[]) const;
+    IMF_EXPORT
+    Slice &                     operator [] (const char name[]);
+    IMF_EXPORT
+    const Slice &               operator [] (const char name[]) const;
 
-    Slice &                    operator [] (const std::string &name);
-    const Slice &              operator [] (const std::string &name) const;
+    IMF_EXPORT
+    Slice &                     operator [] (const std::string &name);
+    IMF_EXPORT
+    const Slice &               operator [] (const std::string &name) const;
 
-    Slice *                    findSlice (const char name[]);
-    const Slice *              findSlice (const char name[]) const;
+    IMF_EXPORT
+    Slice *                     findSlice (const char name[]);
+    IMF_EXPORT
+    const Slice *               findSlice (const char name[]) const;
 
-    Slice *                    findSlice (const std::string &name);
-    const Slice *              findSlice (const std::string &name) const;
+    IMF_EXPORT
+    Slice *                     findSlice (const std::string &name);
+    IMF_EXPORT
+    const Slice *               findSlice (const std::string &name) const;
 
 
     //-----------------------------------------
@@ -195,21 +209,29 @@ class FrameBuffer
     class Iterator;
     class ConstIterator;
 
-    Iterator                   begin ();
-    ConstIterator              begin () const;
+    IMF_EXPORT
+    Iterator                    begin ();
+    IMF_EXPORT
+    ConstIterator               begin () const;
 
-    Iterator                   end ();
-    ConstIterator              end () const;
+    IMF_EXPORT
+    Iterator                    end ();
+    IMF_EXPORT
+    ConstIterator               end () const;
 
-    Iterator                   find (const char name[]);
-    ConstIterator              find (const char name[]) const;
+    IMF_EXPORT
+    Iterator                    find (const char name[]);
+    IMF_EXPORT
+    ConstIterator               find (const char name[]) const;
 
-    Iterator                   find (const std::string &name);
-    ConstIterator              find (const std::string &name) const;
+    IMF_EXPORT
+    Iterator                    find (const std::string &name);
+    IMF_EXPORT
+    ConstIterator               find (const std::string &name) const;
 
   private:
 
-    SliceMap                   _map;
+    SliceMap                    _map;
 };
 
 
@@ -221,14 +243,20 @@ class FrameBuffer::Iterator
 {
   public:
 
+    IMF_EXPORT
     Iterator ();
+    IMF_EXPORT
     Iterator (const FrameBuffer::SliceMap::iterator &i);
 
-    Iterator &                 operator ++ ();
-    Iterator                   operator ++ (int);
+    IMF_EXPORT
+    Iterator &                  operator ++ ();
+    IMF_EXPORT
+    Iterator                    operator ++ (int);
 
-    const char *               name () const;
-    Slice &                    slice () const;
+    IMF_EXPORT
+    const char *                name () const;
+    IMF_EXPORT
+    Slice &                     slice () const;
 
   private:
 
@@ -242,15 +270,22 @@ class FrameBuffer::ConstIterator
 {
   public:
 
+    IMF_EXPORT
     ConstIterator ();
+    IMF_EXPORT
     ConstIterator (const FrameBuffer::SliceMap::const_iterator &i);
+    IMF_EXPORT
     ConstIterator (const FrameBuffer::Iterator &other);
 
-    ConstIterator &            operator ++ ();
-    ConstIterator              operator ++ (int);
+    IMF_EXPORT
+    ConstIterator &             operator ++ ();
+    IMF_EXPORT
+    ConstIterator               operator ++ (int);
 
-    const char *               name () const;
-    const Slice &              slice () const;
+    IMF_EXPORT
+    const char *                name () const;
+    IMF_EXPORT
+    const Slice &               slice () const;
 
   private:
 
@@ -364,7 +399,7 @@ FrameBuffer::ConstIterator::slice () const
 
 inline bool
 operator == (const FrameBuffer::ConstIterator &x,
-         const FrameBuffer::ConstIterator &y)
+             const FrameBuffer::ConstIterator &y)
 {
     return x._i == y._i;
 }
@@ -372,12 +407,12 @@ operator == (const FrameBuffer::ConstIterator &x,
 
 inline bool
 operator != (const FrameBuffer::ConstIterator &x,
-         const FrameBuffer::ConstIterator &y)
+             const FrameBuffer::ConstIterator &y)
 {
     return !(x == y);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index e3874d9..b56f948 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfFramesPerSecond.h>
 #include "ImathFun.h"
 
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 Rational
 guessExactFps (double fps)
@@ -58,18 +59,18 @@ guessExactFps (const Rational &fps)
     const double e = 0.002;
 
     if (abs (double (fps) - double (fps_23_976())) < e)
-    return fps_23_976();
+       return fps_23_976();
 
     if (abs (double (fps) - double (fps_29_97())) < e)
-    return fps_29_97();
+       return fps_29_97();
 
     if (abs (double (fps) - double (fps_47_952())) < e)
-    return fps_47_952();
+       return fps_47_952();
 
     if (abs (double (fps) - double (fps_59_94())) < e)
-    return fps_59_94();
+       return fps_59_94();
 
     return fps;
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index c950484..59ab4cb 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRational.h>
+#include "ImfRational.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
 inline Rational        fps_23_976 ()   {return Rational (24000, 1001);}
 inline Rational        fps_24 ()       {return Rational (24, 1);}
@@ -80,9 +84,11 @@ inline Rational      fps_50 ()       {return Rational (50, 1);}
 inline Rational        fps_59_94 ()    {return Rational (60000, 1001);}
 inline Rational        fps_60 ()       {return Rational (60, 1);}
 
-Rational       guessExactFps (double fps);
-Rational       guessExactFps (const Rational &fps);
+IMF_EXPORT Rational    guessExactFps (double fps);
+IMF_EXPORT Rational    guessExactFps (const Rational &fps);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfGenericInputFile.cpp b/3rdparty/openexr/IlmImf/ImfGenericInputFile.cpp
new file mode 100644 (file)
index 0000000..0096a0a
--- /dev/null
@@ -0,0 +1,76 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfGenericInputFile.h"
+
+#include <ImfVersion.h>
+#include <ImfXdr.h>
+#include <Iex.h>
+#include <OpenEXRConfig.h>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+void GenericInputFile::readMagicNumberAndVersionField(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int& version)
+{
+    //
+    // Read the magic number and the file format version number.
+    // Then check if we can read the rest of this file.
+    //
+
+    int magic;
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, magic);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, version);
+
+    if (magic != MAGIC)
+    {
+        throw IEX_NAMESPACE::InputExc ("File is not an image file.");
+    }
+
+    if (getVersion (version) != EXR_VERSION)
+    {
+        THROW (IEX_NAMESPACE::InputExc, "Cannot read "
+                              "version " << getVersion (version) << " "
+                              "image files.  Current file format version "
+                              "is " << EXR_VERSION << ".");
+    }
+
+    if (!supportsFlags (getFlags (version)))
+    {
+        THROW (IEX_NAMESPACE::InputExc, "The file format version number's flag field "
+                              "contains unrecognized flags.");
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfGenericInputFile.h b/3rdparty/openexr/IlmImf/ImfGenericInputFile.h
new file mode 100644 (file)
index 0000000..38cbcc2
--- /dev/null
@@ -0,0 +1,61 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFGENERICINPUTFILE_H_
+#define IMFGENERICINPUTFILE_H_
+
+#include "ImfIO.h"
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class GenericInputFile
+{
+    public:
+        IMF_EXPORT
+        virtual ~GenericInputFile() {}
+
+    protected:
+        IMF_EXPORT
+        GenericInputFile() {}
+        IMF_EXPORT
+        void readMagicNumberAndVersionField(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, int& version);
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif /* IMFGENERICINPUTFILE_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfGenericOutputFile.cpp b/3rdparty/openexr/IlmImf/ImfGenericOutputFile.cpp
new file mode 100644 (file)
index 0000000..8ec707b
--- /dev/null
@@ -0,0 +1,112 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfGenericOutputFile.h"
+
+#include <ImfBoxAttribute.h>
+#include <ImfFloatAttribute.h>
+#include <ImfTimeCodeAttribute.h>
+#include <ImfChromaticitiesAttribute.h>
+
+#include <ImfMisc.h>
+#include <ImfPartType.h>
+
+#include "ImfNamespace.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+    
+using namespace std;
+
+
+    
+void
+GenericOutputFile::writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os,
+                                                    const Header& header)
+{
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, MAGIC);
+
+    int version = EXR_VERSION;
+
+    if (header.hasType() && isDeepData(header.type()))
+    {
+        version |= NON_IMAGE_FLAG;
+    }
+    else
+    {
+        // (TODO) we may want to check something else in function signature
+        // instead of hasTileDescription()?
+        if (header.hasTileDescription())
+            version |= TILED_FLAG;
+    }
+
+    if (usesLongNames (header))
+        version |= LONG_NAMES_FLAG;
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, version);
+}
+
+void
+GenericOutputFile::writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os,
+                                                    const Header * headers,
+                                                    int parts)
+{
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, MAGIC);
+
+    int version = EXR_VERSION;
+
+    if (parts == 1)
+    {
+        if (headers[0].type() == TILEDIMAGE)
+            version |= TILED_FLAG;
+    }
+    else
+    {
+        version |= MULTI_PART_FILE_FLAG;
+    }
+    
+    for (int i = 0; i < parts; i++)
+    {
+        if (usesLongNames (headers[i]))
+            version |= LONG_NAMES_FLAG;
+
+        if (headers[i].hasType() && isImage(headers[i].type()) == false)
+            version |= NON_IMAGE_FLAG;
+    }
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, version);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfGenericOutputFile.h b/3rdparty/openexr/IlmImf/ImfGenericOutputFile.h
new file mode 100644 (file)
index 0000000..8980d36
--- /dev/null
@@ -0,0 +1,66 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFGENERICOUTPUTFILE_H_
+#define IMFGENERICOUTPUTFILE_H_
+
+#include "ImfVersion.h"
+#include "ImfIO.h"
+#include "ImfXdr.h"
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class GenericOutputFile
+{
+    public:
+        IMF_EXPORT
+        virtual ~GenericOutputFile() {}
+
+    protected:
+        IMF_EXPORT
+        GenericOutputFile() {}
+        IMF_EXPORT
+        void writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, const Header& header);
+        IMF_EXPORT
+        void writeMagicNumberAndVersionField (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream& os, const Header * headers, int parts);
+  
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* GENERICOUTPUTFILE_H_ */
index 394e8b3..d6b55f3 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfChannelListAttribute.h>
 #include <ImfChromaticitiesAttribute.h>
 #include <ImfCompressionAttribute.h>
+#include <ImfDeepImageStateAttribute.h>
 #include <ImfDoubleAttribute.h>
+#include <ImfDwaCompressor.h>
 #include <ImfEnvmapAttribute.h>
 #include <ImfFloatAttribute.h>
+#include <ImfFloatVectorAttribute.h>
 #include <ImfIntAttribute.h>
 #include <ImfKeyCodeAttribute.h>
 #include <ImfLineOrderAttribute.h>
 #include <ImfTileDescriptionAttribute.h>
 #include <ImfTimeCodeAttribute.h>
 #include <ImfVecAttribute.h>
+#include <ImfPartType.h>
 #include "IlmThreadMutex.h"
 #include "Iex.h"
 #include <sstream>
 #include <stdlib.h>
 #include <time.h>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 using namespace std;
-using Imath::Box2i;
-using Imath::V2i;
-using Imath::V2f;
-using IlmThread::Mutex;
-using IlmThread::Lock;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using IMATH_NAMESPACE::V2f;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
 
 
 namespace {
@@ -91,13 +96,13 @@ int maxTileHeight = 0;
 
 void
 initialize (Header &header,
-        const Box2i &displayWindow,
-        const Box2i &dataWindow,
-        float pixelAspectRatio,
-        const V2f &screenWindowCenter,
-        float screenWindowWidth,
-        LineOrder lineOrder,
-        Compression compression)
+           const Box2i &displayWindow,
+           const Box2i &dataWindow,
+           float pixelAspectRatio,
+           const V2f &screenWindowCenter,
+           float screenWindowWidth,
+           LineOrder lineOrder,
+           Compression compression)
 {
     header.insert ("displayWindow", Box2iAttribute (displayWindow));
     header.insert ("dataWindow", Box2iAttribute (dataWindow));
@@ -109,66 +114,29 @@ initialize (Header &header,
     header.insert ("channels", ChannelListAttribute ());
 }
 
-
-bool
-usesLongNames (const Header &header)
-{
-    //
-    // If an OpenEXR file contains any attribute names, attribute type names
-    // or channel names longer than 31 characters, then the file cannot be
-    // read by older versions of the IlmImf library (up to OpenEXR 1.6.1).
-    // Before writing the file header, we check if the header contains
-    // any names longer than 31 characters; if it does, then we set the
-    // LONG_NAMES_FLAG in the file version number.  Older versions of the
-    // IlmImf library will refuse to read files that have the LONG_NAMES_FLAG
-    // set.  Without the flag, older versions of the library would mis-
-    // interpret the file as broken.
-    //
-
-    for (Header::ConstIterator i = header.begin();
-         i != header.end();
-         ++i)
-    {
-        if (strlen (i.name()) >= 32 || strlen (i.attribute().typeName()) >= 32)
-            return true;
-    }
-
-    const ChannelList &channels = header.channels();
-
-    for (ChannelList::ConstIterator i = channels.begin();
-         i != channels.end();
-         ++i)
-    {
-        if (strlen (i.name()) >= 32)
-            return true;
-    }
-
-    return false;
-}
-
 template <size_t N>
 void checkIsNullTerminated (const char (&str)[N], const char *what)
 {
-    for (int i = 0; i < N; ++i) {
-        if (str[i] == '\0')
-            return;
-    }
-    std::stringstream s;
-    s << "Invalid " << what << ": it is more than " << (N - 1)
-        << " characters long.";
-    throw Iex::InputExc(s);
+       for (size_t i = 0; i < N; ++i) {
+               if (str[i] == '\0')
+                       return;
+       }
+       std::stringstream s;
+       s << "Invalid " << what << ": it is more than " << (N - 1) 
+               << " characters long.";
+       throw IEX_NAMESPACE::InputExc(s);
 }
 
 } // namespace
 
 
 Header::Header (int width,
-        int height,
-        float pixelAspectRatio,
-        const V2f &screenWindowCenter,
-        float screenWindowWidth,
-        LineOrder lineOrder,
-        Compression compression)
+               int height,
+               float pixelAspectRatio,
+               const V2f &screenWindowCenter,
+               float screenWindowWidth,
+               LineOrder lineOrder,
+               Compression compression)
 :
     _map()
 {
@@ -177,24 +145,24 @@ Header::Header (int width,
     Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1));
 
     initialize (*this,
-        displayWindow,
-        displayWindow,
-        pixelAspectRatio,
-        screenWindowCenter,
-        screenWindowWidth,
-        lineOrder,
-        compression);
+               displayWindow,
+               displayWindow,
+               pixelAspectRatio,
+               screenWindowCenter,
+               screenWindowWidth,
+               lineOrder,
+               compression);
 }
 
 
 Header::Header (int width,
-        int height,
-        const Box2i &dataWindow,
-        float pixelAspectRatio,
-        const V2f &screenWindowCenter,
-        float screenWindowWidth,
-        LineOrder lineOrder,
-        Compression compression)
+               int height,
+               const Box2i &dataWindow,
+               float pixelAspectRatio,
+               const V2f &screenWindowCenter,
+               float screenWindowWidth,
+               LineOrder lineOrder,
+               Compression compression)
 :
     _map()
 {
@@ -203,46 +171,46 @@ Header::Header (int width,
     Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1));
 
     initialize (*this,
-        displayWindow,
-        dataWindow,
-        pixelAspectRatio,
-        screenWindowCenter,
-        screenWindowWidth,
-        lineOrder,
-        compression);
+               displayWindow,
+               dataWindow,
+               pixelAspectRatio,
+               screenWindowCenter,
+               screenWindowWidth,
+               lineOrder,
+               compression);
 }
 
 
 Header::Header (const Box2i &displayWindow,
-        const Box2i &dataWindow,
-        float pixelAspectRatio,
-        const V2f &screenWindowCenter,
-        float screenWindowWidth,
-        LineOrder lineOrder,
-        Compression compression)
+               const Box2i &dataWindow,
+               float pixelAspectRatio,
+               const V2f &screenWindowCenter,
+               float screenWindowWidth,
+               LineOrder lineOrder,
+               Compression compression)
 :
     _map()
 {
     staticInitialize();
 
     initialize (*this,
-        displayWindow,
-        dataWindow,
-        pixelAspectRatio,
-        screenWindowCenter,
-        screenWindowWidth,
-        lineOrder,
-        compression);
+               displayWindow,
+               dataWindow,
+               pixelAspectRatio,
+               screenWindowCenter,
+               screenWindowWidth,
+               lineOrder,
+               compression);
 }
 
 
 Header::Header (const Header &other): _map()
 {
     for (AttributeMap::const_iterator i = other._map.begin();
-     i != other._map.end();
-     ++i)
+        i != other._map.end();
+        ++i)
     {
-    insert (*i->first, *i->second);
+       insert (*i->first, *i->second);
     }
 }
 
@@ -250,73 +218,94 @@ Header::Header (const Header &other): _map()
 Header::~Header ()
 {
     for (AttributeMap::iterator i = _map.begin();
-     i != _map.end();
-     ++i)
+        i != _map.end();
+        ++i)
     {
-     delete i->second;
+        delete i->second;
     }
 }
 
 
-Header &
+Header &               
 Header::operator = (const Header &other)
 {
     if (this != &other)
     {
-    for (AttributeMap::iterator i = _map.begin();
-         i != _map.end();
-         ++i)
-    {
-         delete i->second;
+       for (AttributeMap::iterator i = _map.begin();
+            i != _map.end();
+            ++i)
+       {
+            delete i->second;
+       }
+
+       _map.erase (_map.begin(), _map.end());
+
+       for (AttributeMap::const_iterator i = other._map.begin();
+            i != other._map.end();
+            ++i)
+       {
+           insert (*i->first, *i->second);
+       }
     }
 
-    _map.erase (_map.begin(), _map.end());
+    return *this;
+}
 
-    for (AttributeMap::const_iterator i = other._map.begin();
-         i != other._map.end();
-         ++i)
-    {
-        insert (*i->first, *i->second);
-    }
-    }
 
-    return *this;
+void
+Header::erase (const char name[])
+{
+    if (name[0] == 0)
+        THROW (IEX_NAMESPACE::ArgExc, "Image attribute name cannot be an empty string.");
+    
+    
+    AttributeMap::iterator i = _map.find (name);
+    if (i != _map.end())
+        _map.erase (i);
+
 }
 
 
 void
+Header::erase (const string &name)
+{
+    erase (name.c_str());
+}
+    
+    
+void
 Header::insert (const char name[], const Attribute &attribute)
 {
     if (name[0] == 0)
-    THROW (Iex::ArgExc, "Image attribute name cannot be an empty string.");
+       THROW (IEX_NAMESPACE::ArgExc, "Image attribute name cannot be an empty string.");
 
     AttributeMap::iterator i = _map.find (name);
 
     if (i == _map.end())
     {
-    Attribute *tmp = attribute.copy();
-
-    try
-    {
-        _map[name] = tmp;
-    }
-    catch (...)
-    {
-        delete tmp;
-        throw;
-    }
+       Attribute *tmp = attribute.copy();
+
+       try
+       {
+           _map[name] = tmp;
+       }
+       catch (...)
+       {
+           delete tmp;
+           throw;
+       }
     }
     else
     {
-    if (strcmp (i->second->typeName(), attribute.typeName()))
-        THROW (Iex::TypeExc, "Cannot assign a value of "
-                 "type \"" << attribute.typeName() << "\" "
-                 "to image attribute \"" << name << "\" of "
-                 "type \"" << i->second->typeName() << "\".");
-
-    Attribute *tmp = attribute.copy();
-    delete i->second;
-    i->second = tmp;
+       if (strcmp (i->second->typeName(), attribute.typeName()))
+           THROW (IEX_NAMESPACE::TypeExc, "Cannot assign a value of "
+                                "type \"" << attribute.typeName() << "\" "
+                                "to image attribute \"" << name << "\" of "
+                                "type \"" << i->second->typeName() << "\".");
+
+       Attribute *tmp = attribute.copy();
+       delete i->second;
+       i->second = tmp;
     }
 }
 
@@ -328,38 +317,38 @@ Header::insert (const string &name, const Attribute &attribute)
 }
 
 
-Attribute &
+Attribute &            
 Header::operator [] (const char name[])
 {
     AttributeMap::iterator i = _map.find (name);
 
     if (i == _map.end())
-    THROW (Iex::ArgExc, "Cannot find image attribute \"" << name << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot find image attribute \"" << name << "\".");
 
     return *i->second;
 }
 
 
-const Attribute &
+const Attribute &      
 Header::operator [] (const char name[]) const
 {
     AttributeMap::const_iterator i = _map.find (name);
 
     if (i == _map.end())
-    THROW (Iex::ArgExc, "Cannot find image attribute \"" << name << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot find image attribute \"" << name << "\".");
 
     return *i->second;
 }
 
 
-Attribute &
+Attribute &            
 Header::operator [] (const string &name)
 {
     return this->operator[] (name.c_str());
 }
 
 
-const Attribute &
+const Attribute &      
 Header::operator [] (const string &name) const
 {
     return this->operator[] (name.c_str());
@@ -422,99 +411,99 @@ Header::find (const string &name) const
 }
 
 
-Imath::Box2i &
+IMATH_NAMESPACE::Box2i &       
 Header::displayWindow ()
 {
     return static_cast <Box2iAttribute &>
-    ((*this)["displayWindow"]).value();
+       ((*this)["displayWindow"]).value();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 Header::displayWindow () const
 {
     return static_cast <const Box2iAttribute &>
-    ((*this)["displayWindow"]).value();
+       ((*this)["displayWindow"]).value();
 }
 
 
-Imath::Box2i &
+IMATH_NAMESPACE::Box2i &       
 Header::dataWindow ()
 {
     return static_cast <Box2iAttribute &>
-    ((*this)["dataWindow"]).value();
+       ((*this)["dataWindow"]).value();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 Header::dataWindow () const
 {
     return static_cast <const Box2iAttribute &>
-    ((*this)["dataWindow"]).value();
+       ((*this)["dataWindow"]).value();
 }
 
 
-float &
+float &                
 Header::pixelAspectRatio ()
 {
     return static_cast <FloatAttribute &>
-    ((*this)["pixelAspectRatio"]).value();
+       ((*this)["pixelAspectRatio"]).value();
 }
 
 
-const float &
+const float &  
 Header::pixelAspectRatio () const
 {
     return static_cast <const FloatAttribute &>
-    ((*this)["pixelAspectRatio"]).value();
+       ((*this)["pixelAspectRatio"]).value();
 }
 
 
-Imath::V2f &
+IMATH_NAMESPACE::V2f & 
 Header::screenWindowCenter ()
 {
     return static_cast <V2fAttribute &>
-    ((*this)["screenWindowCenter"]).value();
+       ((*this)["screenWindowCenter"]).value();
 }
 
 
-const Imath::V2f &
+const IMATH_NAMESPACE::V2f &   
 Header::screenWindowCenter () const
 {
     return static_cast <const V2fAttribute &>
-    ((*this)["screenWindowCenter"]).value();
+       ((*this)["screenWindowCenter"]).value();
 }
 
 
-float &
+float &                
 Header::screenWindowWidth ()
 {
     return static_cast <FloatAttribute &>
-    ((*this)["screenWindowWidth"]).value();
+       ((*this)["screenWindowWidth"]).value();
 }
 
 
-const float &
+const float &  
 Header::screenWindowWidth () const
 {
     return static_cast <const FloatAttribute &>
-    ((*this)["screenWindowWidth"]).value();
+       ((*this)["screenWindowWidth"]).value();
 }
 
 
-ChannelList &
+ChannelList &  
 Header::channels ()
 {
     return static_cast <ChannelListAttribute &>
-    ((*this)["channels"]).value();
+       ((*this)["channels"]).value();
 }
 
 
-const ChannelList &
+const ChannelList &    
 Header::channels () const
 {
     return static_cast <const ChannelListAttribute &>
-    ((*this)["channels"]).value();
+       ((*this)["channels"]).value();
 }
 
 
@@ -522,7 +511,7 @@ LineOrder &
 Header::lineOrder ()
 {
     return static_cast <LineOrderAttribute &>
-    ((*this)["lineOrder"]).value();
+       ((*this)["lineOrder"]).value();
 }
 
 
@@ -530,7 +519,7 @@ const LineOrder &
 Header::lineOrder () const
 {
     return static_cast <const LineOrderAttribute &>
-    ((*this)["lineOrder"]).value();
+       ((*this)["lineOrder"]).value();
 }
 
 
@@ -538,7 +527,7 @@ Compression &
 Header::compression ()
 {
     return static_cast <CompressionAttribute &>
-    ((*this)["compression"]).value();
+       ((*this)["compression"]).value();
 }
 
 
@@ -546,11 +535,167 @@ const Compression &
 Header::compression () const
 {
     return static_cast <const CompressionAttribute &>
-    ((*this)["compression"]).value();
+       ((*this)["compression"]).value();
+}
+
+
+void
+Header::setName(const string& name)
+{
+    insert ("name", StringAttribute (name));
+}
+
+
+bool
+Header::hasName() const
+{
+    return findTypedAttribute <StringAttribute> ("name") != 0;
+}
+
+
+string &
+Header::name()
+{
+    return typedAttribute <StringAttribute> ("name").value();
+}
+
+
+const string &
+Header::name() const
+{
+    return typedAttribute <StringAttribute> ("name").value();
+}
+
+
+void
+Header::setType(const string& type)
+{
+    if (isSupportedType(type) == false)
+    {
+        throw IEX_NAMESPACE::ArgExc (type + "is not a supported image type." +
+                           "The following are supported: " +
+                           SCANLINEIMAGE + ", " +
+                           TILEDIMAGE + ", " +
+                           DEEPSCANLINE + " or " +
+                           DEEPTILE + ".");
+    }
+
+    insert ("type", StringAttribute (type));
+
+    // (TODO) Should we do it here?
+    if (isDeepData(type) && hasVersion() == false)
+    {
+        setVersion(1);
+    }
+}
+
+
+bool
+Header::hasType() const
+{
+    return findTypedAttribute <StringAttribute> ("type") != 0;
+}
+
+
+string &
+Header::type()
+{
+    return typedAttribute <StringAttribute> ("type").value();
+}
+
+
+const string &
+Header::type() const
+{
+    return typedAttribute <StringAttribute> ("type").value();
 }
 
 
 void
+Header::setView(const string& view)
+{
+    insert ("view", StringAttribute (view));
+}
+
+
+bool
+Header::hasView() const
+{
+    return findTypedAttribute <StringAttribute> ("view") != 0;
+}
+
+
+string &
+Header::view()
+{
+    return typedAttribute <StringAttribute> ("view").value();
+}
+
+
+const string &
+Header::view() const
+{
+    return typedAttribute <StringAttribute> ("view").value();
+}
+
+
+void
+Header::setVersion(const int version)
+{
+    if (version != 1)
+    {
+        throw IEX_NAMESPACE::ArgExc ("We can only process version 1");
+    }
+
+    insert ("version", IntAttribute (version));
+}
+
+
+bool
+Header::hasVersion() const
+{
+    return findTypedAttribute <IntAttribute> ("version") != 0;
+}
+
+
+int &
+Header::version()
+{
+    return typedAttribute <IntAttribute> ("version").value();
+}
+
+
+const int &
+Header::version() const
+{
+    return typedAttribute <IntAttribute> ("version").value();
+}
+
+void 
+Header::setChunkCount(int chunks)
+{
+    insert("chunkCount",IntAttribute(chunks));
+}
+
+bool 
+Header::hasChunkCount() const
+{
+   return findTypedAttribute<IntAttribute>("chunkCount") != 0;
+}
+
+int& 
+Header::chunkCount()
+{
+    return typedAttribute <IntAttribute> ("chunkCount").value();
+}
+
+const int& 
+Header::chunkCount() const
+{
+    return typedAttribute <IntAttribute> ("chunkCount").value();
+}
+
+void
 Header::setTileDescription(const TileDescription& td)
 {
     insert ("tiles", TileDescriptionAttribute (td));
@@ -577,7 +722,7 @@ Header::tileDescription () const
     return typedAttribute <TileDescriptionAttribute> ("tiles").value();
 }
 
-void
+void           
 Header::setPreviewImage (const PreviewImage &pi)
 {
     insert ("preview", PreviewImageAttribute (pi));
@@ -598,15 +743,15 @@ Header::previewImage () const
 }
 
 
-bool
+bool           
 Header::hasPreviewImage () const
 {
     return findTypedAttribute <PreviewImageAttribute> ("preview") != 0;
 }
 
 
-void
-Header::sanityCheck (bool isTiled) const
+void           
+Header::sanityCheck (bool isTiled, bool isMultipartFile) const
 {
     //
     // The display window and the data window must each
@@ -619,41 +764,53 @@ Header::sanityCheck (bool isTiled) const
     const Box2i &displayWindow = this->displayWindow();
 
     if (displayWindow.min.x > displayWindow.max.x ||
-    displayWindow.min.y > displayWindow.max.y ||
-    displayWindow.min.x <= -(INT_MAX / 2) ||
-    displayWindow.min.y <= -(INT_MAX / 2) ||
-    displayWindow.max.x >=  (INT_MAX / 2) ||
-    displayWindow.max.y >=  (INT_MAX / 2))
+       displayWindow.min.y > displayWindow.max.y ||
+       displayWindow.min.x <= -(INT_MAX / 2) ||
+       displayWindow.min.y <= -(INT_MAX / 2) ||
+       displayWindow.max.x >=  (INT_MAX / 2) ||
+       displayWindow.max.y >=  (INT_MAX / 2))
     {
-    throw Iex::ArgExc ("Invalid display window in image header.");
+       throw IEX_NAMESPACE::ArgExc ("Invalid display window in image header.");
     }
 
     const Box2i &dataWindow = this->dataWindow();
 
     if (dataWindow.min.x > dataWindow.max.x ||
-    dataWindow.min.y > dataWindow.max.y ||
-    dataWindow.min.x <= -(INT_MAX / 2) ||
-    dataWindow.min.y <= -(INT_MAX / 2) ||
-    dataWindow.max.x >=  (INT_MAX / 2) ||
-    dataWindow.max.y >=  (INT_MAX / 2))
+       dataWindow.min.y > dataWindow.max.y ||
+       dataWindow.min.x <= -(INT_MAX / 2) ||
+       dataWindow.min.y <= -(INT_MAX / 2) ||
+       dataWindow.max.x >=  (INT_MAX / 2) ||
+       dataWindow.max.y >=  (INT_MAX / 2))
     {
-    throw Iex::ArgExc ("Invalid data window in image header.");
+       throw IEX_NAMESPACE::ArgExc ("Invalid data window in image header.");
     }
 
     if (maxImageWidth > 0 &&
-    maxImageWidth < dataWindow.max.x - dataWindow.min.x + 1)
+        maxImageWidth < (dataWindow.max.x - dataWindow.min.x + 1))
     {
-    THROW (Iex::ArgExc, "The width of the data window exceeds the "
-                "maximum width of " << maxImageWidth << "pixels.");
+       THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
+                           "maximum width of " << maxImageWidth << "pixels.");
     }
 
     if (maxImageHeight > 0 &&
-    maxImageHeight < dataWindow.max.y - dataWindow.min.y + 1)
+       maxImageHeight < dataWindow.max.y - dataWindow.min.y + 1)
     {
-    THROW (Iex::ArgExc, "The width of the data window exceeds the "
-                "maximum width of " << maxImageHeight << "pixels.");
+       THROW (IEX_NAMESPACE::ArgExc, "The width of the data window exceeds the "
+                           "maximum width of " << maxImageHeight << "pixels.");
     }
 
+   // chunk table must be smaller than the maximum image area
+   // (only reachable for unknown types or damaged files: will have thrown earlier
+   //  for regular image types)
+   if( maxImageHeight>0 && maxImageWidth>0 && 
+       hasChunkCount() && chunkCount()>Int64(maxImageWidth)*Int64(maxImageHeight))
+   {
+       THROW (IEX_NAMESPACE::ArgExc, "chunkCount exceeds maximum area of "
+       << Int64(maxImageWidth)*Int64(maxImageHeight) << " pixels." );
+       
+   }
+
+
     //
     // The pixel aspect ratio must be greater than 0.
     // In applications, numbers like the the display or
@@ -671,9 +828,9 @@ Header::sanityCheck (bool isTiled) const
     const float MAX_PIXEL_ASPECT_RATIO = 1e+6f;
 
     if (pixelAspectRatio < MIN_PIXEL_ASPECT_RATIO ||
-    pixelAspectRatio > MAX_PIXEL_ASPECT_RATIO)
+       pixelAspectRatio > MAX_PIXEL_ASPECT_RATIO)
     {
-    throw Iex::ArgExc ("Invalid pixel aspect ratio in image header.");
+       throw IEX_NAMESPACE::ArgExc ("Invalid pixel aspect ratio in image header.");
     }
 
     //
@@ -687,63 +844,98 @@ Header::sanityCheck (bool isTiled) const
     float screenWindowWidth = this->screenWindowWidth();
 
     if (screenWindowWidth < 0)
-    throw Iex::ArgExc ("Invalid screen window width in image header.");
+       throw IEX_NAMESPACE::ArgExc ("Invalid screen window width in image header.");
 
     //
-    // If the file is tiled, verify that the tile description has resonable
-    // values and check to see if the lineOrder is one of the predefined 3.
-    // If the file is not tiled, then the lineOrder can only be INCREASING_Y
-    // or DECREASING_Y.
+    // If the file has multiple parts, verify that each header has attribute
+    // name and type.
+    // (TODO) We may want to check more stuff here.
     //
 
-    LineOrder lineOrder = this->lineOrder();
-
-    if (isTiled)
+    if (isMultipartFile)
     {
-    if (!hasTileDescription())
-    {
-        throw Iex::ArgExc ("Tiled image has no tile "
-                   "description attribute.");
-    }
-
-    const TileDescription &tileDesc = tileDescription();
+        if (!hasName())
+        {
+            throw IEX_NAMESPACE::ArgExc ("Headers in a multipart file should"
+                               " have name attribute.");
+        }
 
-    if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0)
-        throw Iex::ArgExc ("Invalid tile size in image header.");
+        if (!hasType())
+        {
+            throw IEX_NAMESPACE::ArgExc ("Headers in a multipart file should"
+                               " have type attribute.");
+        }
 
-    if (maxTileWidth > 0 &&
-        maxTileWidth < tileDesc.xSize)
-    {
-        THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum "
-                "width of " << maxTileWidth << "pixels.");
     }
-
-    if (maxTileHeight > 0 &&
-        maxTileHeight < tileDesc.ySize)
+    
+    const std::string & part_type=hasType() ? type() : "";
+    
+    if(part_type!="" && !isSupportedType(part_type))
     {
-        THROW (Iex::ArgExc, "The width of the tiles exceeds the maximum "
-                "width of " << maxTileHeight << "pixels.");
+        //
+        // skip remaining sanity checks with unsupported types - they may not hold
+        //
+        return;
     }
+    
+   
+    //
+    // If the file is tiled, verify that the tile description has reasonable
+    // values and check to see if the lineOrder is one of the predefined 3.
+    // If the file is not tiled, then the lineOrder can only be INCREASING_Y
+    // or DECREASING_Y.
+    //
 
-    if (tileDesc.mode != ONE_LEVEL &&
-        tileDesc.mode != MIPMAP_LEVELS &&
-        tileDesc.mode != RIPMAP_LEVELS)
-        throw Iex::ArgExc ("Invalid level mode in image header.");
-
-    if (tileDesc.roundingMode != ROUND_UP &&
-        tileDesc.roundingMode != ROUND_DOWN)
-        throw Iex::ArgExc ("Invalid level rounding mode in image header.");
+    LineOrder lineOrder = this->lineOrder();
 
-    if (lineOrder != INCREASING_Y &&
-        lineOrder != DECREASING_Y &&
-        lineOrder != RANDOM_Y)
-        throw Iex::ArgExc ("Invalid line order in image header.");
+    if (isTiled)
+    {
+       if (!hasTileDescription())
+       {
+           throw IEX_NAMESPACE::ArgExc ("Tiled image has no tile "
+                              "description attribute.");
+       }
+
+       const TileDescription &tileDesc = tileDescription();
+
+       if (tileDesc.xSize <= 0 || tileDesc.ySize <= 0)
+           throw IEX_NAMESPACE::ArgExc ("Invalid tile size in image header.");
+
+       if (maxTileWidth > 0 &&
+           maxTileWidth < int(tileDesc.xSize))
+       {
+           THROW (IEX_NAMESPACE::ArgExc, "The width of the tiles exceeds the maximum "
+                               "width of " << maxTileWidth << "pixels.");
+       }
+
+       if (maxTileHeight > 0 &&
+           maxTileHeight < int(tileDesc.ySize))
+       {
+           THROW (IEX_NAMESPACE::ArgExc, "The width of the tiles exceeds the maximum "
+                               "width of " << maxTileHeight << "pixels.");
+       }
+
+       if (tileDesc.mode != ONE_LEVEL &&
+           tileDesc.mode != MIPMAP_LEVELS &&
+           tileDesc.mode != RIPMAP_LEVELS)
+           throw IEX_NAMESPACE::ArgExc ("Invalid level mode in image header.");
+
+       if (tileDesc.roundingMode != ROUND_UP &&
+           tileDesc.roundingMode != ROUND_DOWN)
+           throw IEX_NAMESPACE::ArgExc ("Invalid level rounding mode in image header.");
+
+       if (lineOrder != INCREASING_Y &&
+           lineOrder != DECREASING_Y &&
+           lineOrder != RANDOM_Y)
+           throw IEX_NAMESPACE::ArgExc ("Invalid line order in image header.");
     }
     else
     {
-    if (lineOrder != INCREASING_Y &&
-        lineOrder != DECREASING_Y)
-        throw Iex::ArgExc ("Invalid line order in image header.");
+        if (lineOrder != INCREASING_Y &&
+            lineOrder != DECREASING_Y)
+            throw IEX_NAMESPACE::ArgExc ("Invalid line order in image header.");
+        
+        
     }
 
     //
@@ -751,7 +943,13 @@ Header::sanityCheck (bool isTiled) const
     //
 
     if (!isValidCompression (this->compression()))
-    throw Iex::ArgExc ("Unknown compression type in image header.");
+       throw IEX_NAMESPACE::ArgExc ("Unknown compression type in image header.");
+    
+    if(isDeepData(part_type))
+    {
+        if (!isValidDeepCompression (this->compression()))
+            throw IEX_NAMESPACE::ArgExc ("Compression type in header not valid for deep data");
+    }
 
     //
     // Check the channel list:
@@ -767,103 +965,103 @@ Header::sanityCheck (bool isTiled) const
     //
 
     const ChannelList &channels = this->channels();
-
+    
     if (isTiled)
     {
-    for (ChannelList::ConstIterator i = channels.begin();
-         i != channels.end();
-         ++i)
-    {
-        if (i.channel().type != UINT &&
-        i.channel().type != HALF &&
-        i.channel().type != FLOAT)
-        {
-        THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" "
-                        "image channel is invalid.");
-        }
-
-        if (i.channel().xSampling != 1)
-        {
-        THROW (Iex::ArgExc, "The x subsampling factor for the "
-                    "\"" << i.name() << "\" channel "
-                    "is not 1.");
-        }
-
-        if (i.channel().ySampling != 1)
-        {
-        THROW (Iex::ArgExc, "The y subsampling factor for the "
-                    "\"" << i.name() << "\" channel "
-                    "is not 1.");
-        }
-    }
+       for (ChannelList::ConstIterator i = channels.begin();
+            i != channels.end();
+            ++i)
+       {
+           if (i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::UINT &&
+                   i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF &&
+                   i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" "
+                                   "image channel is invalid.");
+           }
+
+           if (i.channel().xSampling != 1)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "The x subsampling factor for the "
+                                   "\"" << i.name() << "\" channel "
+                                   "is not 1.");
+           }   
+
+           if (i.channel().ySampling != 1)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "The y subsampling factor for the "
+                                   "\"" << i.name() << "\" channel "
+                                   "is not 1.");
+           }   
+       }
     }
     else
     {
-    for (ChannelList::ConstIterator i = channels.begin();
-         i != channels.end();
-         ++i)
-    {
-        if (i.channel().type != UINT &&
-        i.channel().type != HALF &&
-        i.channel().type != FLOAT)
-        {
-        THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" "
-                        "image channel is invalid.");
-        }
-
-        if (i.channel().xSampling < 1)
-        {
-        THROW (Iex::ArgExc, "The x subsampling factor for the "
-                    "\"" << i.name() << "\" channel "
-                    "is invalid.");
-        }
-
-        if (i.channel().ySampling < 1)
-        {
-        THROW (Iex::ArgExc, "The y subsampling factor for the "
-                    "\"" << i.name() << "\" channel "
-                    "is invalid.");
-        }
-
-        if (dataWindow.min.x % i.channel().xSampling)
-        {
-        THROW (Iex::ArgExc, "The minimum x coordinate of the "
-                    "image's data window is not a multiple "
-                    "of the x subsampling factor of "
-                    "the \"" << i.name() << "\" channel.");
-        }
-
-        if (dataWindow.min.y % i.channel().ySampling)
-        {
-        THROW (Iex::ArgExc, "The minimum y coordinate of the "
-                    "image's data window is not a multiple "
-                    "of the y subsampling factor of "
-                    "the \"" << i.name() << "\" channel.");
-        }
-
-        if ((dataWindow.max.x - dataWindow.min.x + 1) %
-            i.channel().xSampling)
-        {
-        THROW (Iex::ArgExc, "Number of pixels per row in the "
-                    "image's data window is not a multiple "
-                    "of the x subsampling factor of "
-                    "the \"" << i.name() << "\" channel.");
-        }
-
-        if ((dataWindow.max.y - dataWindow.min.y + 1) %
-            i.channel().ySampling)
-        {
-        THROW (Iex::ArgExc, "Number of pixels per column in the "
-                    "image's data window is not a multiple "
-                    "of the y subsampling factor of "
-                    "the \"" << i.name() << "\" channel.");
-        }
-    }
+       for (ChannelList::ConstIterator i = channels.begin();
+            i != channels.end();
+            ++i)
+       {
+           if (i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::UINT &&
+                   i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF &&
+                   i.channel().type != OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" "
+                                   "image channel is invalid.");
+           }
+
+           if (i.channel().xSampling < 1)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "The x subsampling factor for the "
+                                   "\"" << i.name() << "\" channel "
+                                   "is invalid.");
+           }
+
+           if (i.channel().ySampling < 1)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "The y subsampling factor for the "
+                                   "\"" << i.name() << "\" channel "
+                                   "is invalid.");
+           }
+
+           if (dataWindow.min.x % i.channel().xSampling)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "The minimum x coordinate of the "
+                                   "image's data window is not a multiple "
+                                   "of the x subsampling factor of "
+                                   "the \"" << i.name() << "\" channel.");
+           }
+
+           if (dataWindow.min.y % i.channel().ySampling)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "The minimum y coordinate of the "
+                                   "image's data window is not a multiple "
+                                   "of the y subsampling factor of "
+                                   "the \"" << i.name() << "\" channel.");
+           }
+
+           if ((dataWindow.max.x - dataWindow.min.x + 1) %
+                   i.channel().xSampling)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "Number of pixels per row in the "
+                                   "image's data window is not a multiple "
+                                   "of the x subsampling factor of "
+                                   "the \"" << i.name() << "\" channel.");
+           }
+
+           if ((dataWindow.max.y - dataWindow.min.y + 1) %
+                   i.channel().ySampling)
+           {
+               THROW (IEX_NAMESPACE::ArgExc, "Number of pixels per column in the "
+                                   "image's data window is not a multiple "
+                                   "of the y subsampling factor of "
+                                   "the \"" << i.name() << "\" channel.");
+           }
+       }
     }
 }
 
 
-void
+void           
 Header::setMaxImageSize (int maxWidth, int maxHeight)
 {
     maxImageWidth = maxWidth;
@@ -871,7 +1069,7 @@ Header::setMaxImageSize (int maxWidth, int maxHeight)
 }
 
 
-void
+void           
 Header::setMaxTileSize (int maxWidth, int maxHeight)
 {
     maxTileWidth = maxWidth;
@@ -879,26 +1077,23 @@ Header::setMaxTileSize (int maxWidth, int maxHeight)
 }
 
 
+bool
+Header::readsNothing()
+{
+    return _readsNothing;
+}
+
+
 Int64
-Header::writeTo (OStream &os, bool isTiled) const
+Header::writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, bool isTiled) const
 {
     //
     // Write a "magic number" to identify the file as an image file.
     // Write the current file format version number.
     //
 
-    Xdr::write <StreamIO> (os, MAGIC);
-
     int version = EXR_VERSION;
 
-    if (isTiled)
-        version |= TILED_FLAG;
-
-    if (usesLongNames (*this))
-        version |= LONG_NAMES_FLAG;
-
-    Xdr::write <StreamIO> (os, version);
-
     //
     // Write all attributes.  If we have a preview image attribute,
     // keep track of its position in the file.
@@ -907,150 +1102,129 @@ Header::writeTo (OStream &os, bool isTiled) const
     Int64 previewPosition = 0;
 
     const Attribute *preview =
-        findTypedAttribute <PreviewImageAttribute> ("preview");
+           findTypedAttribute <PreviewImageAttribute> ("preview");
 
     for (ConstIterator i = begin(); i != end(); ++i)
     {
-    //
-    // Write the attribute's name and type.
-    //
+       //
+       // Write the attribute's name and type.
+       //
 
-    Xdr::write <StreamIO> (os, i.name());
-    Xdr::write <StreamIO> (os, i.attribute().typeName());
+       OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, i.name());
+       OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, i.attribute().typeName());
 
-    //
-    // Write the size of the attribute value,
-    // and the value itself.
-    //
+       //
+       // Write the size of the attribute value,
+       // and the value itself.
+       //
 
-    StdOSStream oss;
-    i.attribute().writeValueTo (oss, version);
+       StdOSStream oss;
+       i.attribute().writeValueTo (oss, version);
 
-    std::string s = oss.str();
-    Xdr::write <StreamIO> (os, (int) s.length());
+       std::string s = oss.str();
+       OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, (int) s.length());
 
-    if (&i.attribute() == preview)
-        previewPosition = os.tellp();
+       if (&i.attribute() == preview)
+           previewPosition = os.tellp();
 
-    os.write (s.data(), s.length());
+       os.write (s.data(), int(s.length()));
     }
 
     //
     // Write zero-length attribute name to mark the end of the header.
     //
 
-    Xdr::write <StreamIO> (os, "");
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, "");
 
     return previewPosition;
 }
 
 
 void
-Header::readFrom (IStream &is, int &version)
+Header::readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int &version)
 {
     //
-    // Read the magic number and the file format version number.
-    // Then check if we can read the rest of this file.
-    //
-
-    int magic;
-
-    Xdr::read <StreamIO> (is, magic);
-    Xdr::read <StreamIO> (is, version);
-
-    if (magic != MAGIC)
-    {
-    throw Iex::InputExc ("File is not an image file.");
-    }
-
-    if (getVersion (version) != EXR_VERSION)
-    {
-    THROW (Iex::InputExc, "Cannot read "
-                  "version " << getVersion (version) << " "
-                  "image files.  Current file format version "
-                  "is " << EXR_VERSION << ".");
-    }
-
-    if (!supportsFlags (getFlags (version)))
-    {
-    THROW (Iex::InputExc, "The file format version number's flag field "
-                  "contains unrecognized flags.");
-    }
-
-    //
     // Read all attributes.
     //
 
-    while (true)
-    {
-    //
-    // Read the name of the attribute.
-    // A zero-length attribute name indicates the end of the header.
-    //
-
-    char name[Name::SIZE];
-    Xdr::read <StreamIO> (is, Name::MAX_LENGTH, name);
-
-    if (name[0] == 0)
-        break;
-
-    checkIsNullTerminated (name, "attribute name");
-
-    //
-    // Read the attribute type and the size of the attribute value.
-    //
-
-    char typeName[Name::SIZE];
-    int size;
-
-    Xdr::read <StreamIO> (is, Name::MAX_LENGTH, typeName);
-    checkIsNullTerminated (typeName, "attribute type name");
-    Xdr::read <StreamIO> (is, size);
-
-    AttributeMap::iterator i = _map.find (name);
-
-    if (i != _map.end())
-    {
-        //
-        // The attribute already exists (for example,
-        // because it is a predefined attribute).
-        // Read the attribute's new value from the file.
-        //
-
-        if (strncmp (i->second->typeName(), typeName, sizeof (typeName)))
-        THROW (Iex::InputExc, "Unexpected type for image attribute "
-                      "\"" << name << "\".");
+    int attrCount = 0;
 
-        i->second->readValueFrom (is, size, version);
-    }
-    else
+    while (true)
     {
-        //
-        // The new attribute does not exist yet.
-        // If the attribute type is of a known type,
-        // read the attribute value.  If the attribute
-        // is of an unknown type, read its value and
-        // store it as an OpaqueAttribute.
-        //
-
-        Attribute *attr;
-
-        if (Attribute::knownType (typeName))
-        attr = Attribute::newAttribute (typeName);
-        else
-        attr = new OpaqueAttribute (typeName);
-
-        try
-        {
-        attr->readValueFrom (is, size, version);
-        _map[name] = attr;
-        }
-        catch (...)
-        {
-        delete attr;
-        throw;
-        }
-    }
+       //
+       // Read the name of the attribute.
+       // A zero-length attribute name indicates the end of the header.
+       //
+
+       char name[Name::SIZE];
+       OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, Name::MAX_LENGTH, name);
+
+       if (name[0] == 0)
+       {
+           if (attrCount == 0) _readsNothing = true;
+           else                _readsNothing = false;
+           break;
+       }
+
+       attrCount++;
+
+       checkIsNullTerminated (name, "attribute name");
+
+       //
+       // Read the attribute type and the size of the attribute value.
+       //
+
+       char typeName[Name::SIZE];
+       int size;
+
+       OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, Name::MAX_LENGTH, typeName);
+       checkIsNullTerminated (typeName, "attribute type name");
+       OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, size);
+
+       AttributeMap::iterator i = _map.find (name);
+
+       if (i != _map.end())
+       {
+           //
+           // The attribute already exists (for example,
+           // because it is a predefined attribute).
+           // Read the attribute's new value from the file.
+           //
+
+           if (strncmp (i->second->typeName(), typeName, sizeof (typeName)))
+               THROW (IEX_NAMESPACE::InputExc, "Unexpected type for image attribute "
+                                     "\"" << name << "\".");
+
+           i->second->readValueFrom (is, size, version);
+       }
+       else
+       {
+           //
+           // The new attribute does not exist yet.
+           // If the attribute type is of a known type,
+           // read the attribute value.  If the attribute
+           // is of an unknown type, read its value and
+           // store it as an OpaqueAttribute.
+           //
+
+           Attribute *attr;
+
+           if (Attribute::knownType (typeName))
+               attr = Attribute::newAttribute (typeName);
+           else
+               attr = new OpaqueAttribute (typeName);
+
+           try
+           {
+               attr->readValueFrom (is, size, version);
+               _map[name] = attr;
+           }
+           catch (...)
+           {
+               delete attr;
+               throw;
+           }
+       }
     }
 }
 
@@ -1065,42 +1239,45 @@ staticInitialize ()
 
     if (!initialized)
     {
-    //
-    // One-time initialization -- register
-    // some predefined attribute types.
-    //
-
-    Box2fAttribute::registerAttributeType();
-    Box2iAttribute::registerAttributeType();
-    ChannelListAttribute::registerAttributeType();
-    CompressionAttribute::registerAttributeType();
-    ChromaticitiesAttribute::registerAttributeType();
-    DoubleAttribute::registerAttributeType();
-    EnvmapAttribute::registerAttributeType();
-    FloatAttribute::registerAttributeType();
-    IntAttribute::registerAttributeType();
-    KeyCodeAttribute::registerAttributeType();
-    LineOrderAttribute::registerAttributeType();
-    M33dAttribute::registerAttributeType();
-    M33fAttribute::registerAttributeType();
-    M44dAttribute::registerAttributeType();
-    M44fAttribute::registerAttributeType();
-    PreviewImageAttribute::registerAttributeType();
-    RationalAttribute::registerAttributeType();
-    StringAttribute::registerAttributeType();
+       //
+       // One-time initialization -- register
+       // some predefined attribute types.
+       //
+       
+       Box2fAttribute::registerAttributeType();
+       Box2iAttribute::registerAttributeType();
+       ChannelListAttribute::registerAttributeType();
+       CompressionAttribute::registerAttributeType();
+       ChromaticitiesAttribute::registerAttributeType();
+       DeepImageStateAttribute::registerAttributeType();
+       DoubleAttribute::registerAttributeType();
+       EnvmapAttribute::registerAttributeType();
+       FloatAttribute::registerAttributeType();
+       FloatVectorAttribute::registerAttributeType();
+       IntAttribute::registerAttributeType();
+       KeyCodeAttribute::registerAttributeType();
+       LineOrderAttribute::registerAttributeType();
+       M33dAttribute::registerAttributeType();
+       M33fAttribute::registerAttributeType();
+       M44dAttribute::registerAttributeType();
+       M44fAttribute::registerAttributeType();
+       PreviewImageAttribute::registerAttributeType();
+       RationalAttribute::registerAttributeType();
+       StringAttribute::registerAttributeType();
         StringVectorAttribute::registerAttributeType();
-    TileDescriptionAttribute::registerAttributeType();
-    TimeCodeAttribute::registerAttributeType();
-    V2dAttribute::registerAttributeType();
-    V2fAttribute::registerAttributeType();
-    V2iAttribute::registerAttributeType();
-    V3dAttribute::registerAttributeType();
-    V3fAttribute::registerAttributeType();
-    V3iAttribute::registerAttributeType();
-
-    initialized = true;
+       TileDescriptionAttribute::registerAttributeType();
+       TimeCodeAttribute::registerAttributeType();
+       V2dAttribute::registerAttributeType();
+       V2fAttribute::registerAttributeType();
+       V2iAttribute::registerAttributeType();
+       V3dAttribute::registerAttributeType();
+       V3fAttribute::registerAttributeType();
+       V3iAttribute::registerAttributeType();
+       DwaCompressor::initializeFuncs();
+
+       initialized = true;
     }
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 8b83829..638d298 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfLineOrder.h>
-#include <ImfCompression.h>
-#include <ImfName.h>
-#include <ImfTileDescription.h>
-#include <ImfInt64.h>
+#include "ImfLineOrder.h"
+#include "ImfCompression.h"
+#include "ImfName.h"
+#include "ImfTileDescription.h"
+#include "ImfInt64.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "IexBaseExc.h"
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <map>
 #include <iosfwd>
 #include <string>
 
-namespace Imf {
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class Attribute;
-class ChannelList;
-class IStream;
-class OStream;
-class PreviewImage;
+using std::string;
 
 
 class Header
 {
   public:
-
+    
     //----------------------------------------------------------------
     // Default constructor -- the display window and the data window
     // are both set to Box2i (V2i (0, 0), V2i (width-1, height-1).
     //----------------------------------------------------------------
 
+    IMF_EXPORT
     Header (int width = 64,
-        int height = 64,
-        float pixelAspectRatio = 1,
-        const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
-        float screenWindowWidth = 1,
-        LineOrder lineOrder = INCREASING_Y,
-        Compression = ZIP_COMPRESSION);
+           int height = 64,
+           float pixelAspectRatio = 1,
+           const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
+           float screenWindowWidth = 1,
+           LineOrder lineOrder = INCREASING_Y,
+           Compression = ZIP_COMPRESSION);
 
 
     //--------------------------------------------------------------------
@@ -88,14 +90,15 @@ class Header
     // window is set to Box2i (V2i (0, 0), V2i (width-1, height-1).
     //--------------------------------------------------------------------
 
+    IMF_EXPORT
     Header (int width,
-        int height,
-        const Imath::Box2i &dataWindow,
-        float pixelAspectRatio = 1,
-        const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
-        float screenWindowWidth = 1,
-        LineOrder lineOrder = INCREASING_Y,
-        Compression = ZIP_COMPRESSION);
+           int height,
+           const IMATH_NAMESPACE::Box2i &dataWindow,
+           float pixelAspectRatio = 1,
+           const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
+           float screenWindowWidth = 1,
+           LineOrder lineOrder = INCREASING_Y,
+           Compression = ZIP_COMPRESSION);
 
 
     //----------------------------------------------------------
@@ -103,19 +106,21 @@ class Header
     // both specified explicitly.
     //----------------------------------------------------------
 
-    Header (const Imath::Box2i &displayWindow,
-        const Imath::Box2i &dataWindow,
-        float pixelAspectRatio = 1,
-        const Imath::V2f &screenWindowCenter = Imath::V2f (0, 0),
-        float screenWindowWidth = 1,
-        LineOrder lineOrder = INCREASING_Y,
-        Compression = ZIP_COMPRESSION);
+    IMF_EXPORT
+    Header (const IMATH_NAMESPACE::Box2i &displayWindow,
+           const IMATH_NAMESPACE::Box2i &dataWindow,
+           float pixelAspectRatio = 1,
+           const IMATH_NAMESPACE::V2f &screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
+           float screenWindowWidth = 1,
+           LineOrder lineOrder = INCREASING_Y,
+           Compression = ZIP_COMPRESSION);
 
 
     //-----------------
     // Copy constructor
     //-----------------
 
+    IMF_EXPORT
     Header (const Header &other);
 
 
@@ -123,6 +128,7 @@ class Header
     // Destructor
     //-----------
 
+    IMF_EXPORT
     ~Header ();
 
 
@@ -130,6 +136,7 @@ class Header
     // Assignment
     //-----------
 
+    IMF_EXPORT
     Header &                   operator = (const Header &other);
 
 
@@ -146,30 +153,50 @@ class Header
     //                 is copied into this attribute.
     //
     //                 If an attribute with name n exists, and its
-    //                 type is different from attr, an Iex::TypeExc
+    //                 type is different from attr, an IEX_NAMESPACE::TypeExc
     //                 is thrown.
     //
     //---------------------------------------------------------------
 
+    IMF_EXPORT
     void                       insert (const char name[],
-                        const Attribute &attribute);
+                                       const Attribute &attribute);
 
+    IMF_EXPORT
     void                       insert (const std::string &name,
-                        const Attribute &attribute);
+                                       const Attribute &attribute);
+
+    //---------------------------------------------------------------
+    // Remove an attribute:
+    //
+    // remove(n)       If an attribute with name n exists, then it
+    //                 is removed from the map of present attributes.
+    //
+    //                 If no attribute with name n exists, then this
+    //                 functions becomes a 'no-op'
+    //
+    //---------------------------------------------------------------
 
+    IMF_EXPORT
+    void                        erase (const char name[]);
+    IMF_EXPORT
+    void                        erase (const std::string &name);
+
+    
+    
     //------------------------------------------------------------------
     // Access to existing attributes:
     //
     // [n]                     Returns a reference to the attribute
     //                         with name n.  If no attribute with
-    //                         name n exists, an Iex::ArgExc is thrown.
+    //                         name n exists, an IEX_NAMESPACE::ArgExc is thrown.
     //
     // typedAttribute<T>(n)    Returns a reference to the attribute
     //                         with name n and type T.  If no attribute
-    //                         with name n exists, an Iex::ArgExc is
+    //                         with name n exists, an IEX_NAMESPACE::ArgExc is
     //                         thrown.  If an attribute with name n
     //                         exists, but its type is not T, an
-    //                         Iex::TypeExc is thrown.
+    //                         IEX_NAMESPACE::TypeExc is thrown.
     //
     // findTypedAttribute<T>(n)        Returns a pointer to the attribute with
     //                         name n and type T, or 0 if no attribute
@@ -177,10 +204,14 @@ class Header
     //
     //------------------------------------------------------------------
 
+    IMF_EXPORT
     Attribute &                        operator [] (const char name[]);
+    IMF_EXPORT
     const Attribute &          operator [] (const char name[]) const;
 
+    IMF_EXPORT
     Attribute &                        operator [] (const std::string &name);
+    IMF_EXPORT
     const Attribute &          operator [] (const std::string &name) const;
 
     template <class T> T&      typedAttribute (const char name[]);
@@ -194,7 +225,7 @@ class Header
 
     template <class T> T*      findTypedAttribute (const std::string &name);
     template <class T> const T*        findTypedAttribute (const std::string &name)
-                                       const;
+                                                                      const;
 
     //---------------------------------------------
     // Iterator-style access to existing attributes
@@ -205,16 +236,24 @@ class Header
     class Iterator;
     class ConstIterator;
 
+    IMF_EXPORT
     Iterator                   begin ();
+    IMF_EXPORT
     ConstIterator              begin () const;
 
+    IMF_EXPORT
     Iterator                   end ();
+    IMF_EXPORT
     ConstIterator              end () const;
 
+    IMF_EXPORT
     Iterator                   find (const char name[]);
+    IMF_EXPORT
     ConstIterator              find (const char name[]) const;
 
+    IMF_EXPORT
     Iterator                   find (const std::string &name);
+    IMF_EXPORT
     ConstIterator              find (const std::string &name) const;
 
 
@@ -222,31 +261,113 @@ class Header
     // Access to predefined attributes
     //--------------------------------
 
-    Imath::Box2i &             displayWindow ();
-    const Imath::Box2i &       displayWindow () const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i &           displayWindow ();
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     displayWindow () const;
 
-    Imath::Box2i &             dataWindow ();
-    const Imath::Box2i &       dataWindow () const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i &           dataWindow ();
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     dataWindow () const;
 
+    IMF_EXPORT
     float &                    pixelAspectRatio ();
+    IMF_EXPORT
     const float &              pixelAspectRatio () const;
 
-    Imath::V2f &               screenWindowCenter ();
-    const Imath::V2f &         screenWindowCenter () const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::V2f &             screenWindowCenter ();
+    IMF_EXPORT
+    const IMATH_NAMESPACE::V2f &               screenWindowCenter () const;
 
+    IMF_EXPORT
     float &                    screenWindowWidth ();
+    IMF_EXPORT
     const float &              screenWindowWidth () const;
 
+    IMF_EXPORT
     ChannelList &              channels ();
+    IMF_EXPORT
     const ChannelList &                channels () const;
 
+    IMF_EXPORT
     LineOrder &                        lineOrder ();
+    IMF_EXPORT
     const LineOrder &          lineOrder () const;
 
+    IMF_EXPORT
     Compression &              compression ();
+    IMF_EXPORT
     const Compression &                compression () const;
 
 
+    //-----------------------------------------------------
+    // Access to required attributes for multipart files
+    // They are optional to non-multipart files and mandatory
+    // for multipart files.
+    //-----------------------------------------------------
+    IMF_EXPORT
+    void                        setName (const string& name);
+
+    IMF_EXPORT
+    string&                     name();
+    IMF_EXPORT
+    const string&               name() const;
+
+    IMF_EXPORT
+    bool                        hasName() const;
+
+    IMF_EXPORT
+    void                        setType (const string& Type);
+
+    IMF_EXPORT
+    string&                     type();
+    IMF_EXPORT
+    const string&               type() const;
+
+    IMF_EXPORT
+    bool                        hasType() const;
+
+    IMF_EXPORT
+    void                        setVersion (const int version);
+
+    IMF_EXPORT
+    int&                        version();
+    IMF_EXPORT
+    const int&                  version() const;
+
+    IMF_EXPORT
+    bool                        hasVersion() const;
+
+    //
+    // the chunkCount attribute is set automatically when a file is written.
+    // There is no need to set it manually
+    //
+    IMF_EXPORT
+    void                        setChunkCount(int chunks);
+    IMF_EXPORT
+    bool                        hasChunkCount() const;
+    IMF_EXPORT
+    const int &                 chunkCount() const;
+    IMF_EXPORT
+    int &                       chunkCount();
+
+    
+    //
+    // for multipart files, return whether the file has a view string attribute
+    // (for the deprecated single part multiview format EXR, see ImfMultiView.h)
+    //
+    IMF_EXPORT
+    void                       setView(const string & view);
+    IMF_EXPORT
+    bool                       hasView() const;
+    IMF_EXPORT
+    string &                   view();
+    IMF_EXPORT
+    const string &             view() const;
+    
+
     //----------------------------------------------------------------------
     // Tile Description:
     //
@@ -268,11 +389,15 @@ class Header
     //
     //----------------------------------------------------------------------
 
+    IMF_EXPORT
     void                       setTileDescription (const TileDescription & td);
 
+    IMF_EXPORT
     TileDescription &          tileDescription ();
+    IMF_EXPORT
     const TileDescription &    tileDescription () const;
 
+    IMF_EXPORT
     bool                       hasTileDescription() const;
 
 
@@ -297,11 +422,15 @@ class Header
     //
     //----------------------------------------------------------------------
 
+    IMF_EXPORT
     void                       setPreviewImage (const PreviewImage &p);
 
+    IMF_EXPORT
     PreviewImage &             previewImage ();
+    IMF_EXPORT
     const PreviewImage &       previewImage () const;
 
+    IMF_EXPORT
     bool                       hasPreviewImage () const;
 
 
@@ -314,7 +443,9 @@ class Header
     // header
     //-------------------------------------------------------------
 
-    void                       sanityCheck (bool isTiled = false) const;
+    IMF_EXPORT
+    void                       sanityCheck (bool isTiled = false,
+                                            bool isMultipartFile = false) const;
 
 
     //----------------------------------------------------------------
@@ -323,7 +454,7 @@ class Header
     // sanityCheck() will throw an exception if the width or height of
     // the data window exceeds the maximum image width or height, or
     // if the size of a tile exceeds the maximum tile width or height.
-    //
+    // 
     // At program startup the maximum image and tile width and height
     // are set to zero, meaning that width and height are unlimited.
     //
@@ -333,9 +464,17 @@ class Header
     // a damaged image file.
     //----------------------------------------------------------------
 
+    IMF_EXPORT
     static void                        setMaxImageSize (int maxWidth, int maxHeight);
+    IMF_EXPORT
     static void                        setMaxTileSize (int maxWidth, int maxHeight);
 
+    //
+    // Check if the header reads nothing.
+    //
+    IMF_EXPORT
+    bool                        readsNothing();
+
 
     //------------------------------------------------------------------
     // Input and output:
@@ -348,14 +487,20 @@ class Header
     //------------------------------------------------------------------
 
 
-    Int64                      writeTo (OStream &os,
-                     bool isTiled = false) const;
+    IMF_EXPORT
+    Int64                      writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                                        bool isTiled = false) const;
 
-    void                       readFrom (IStream &is, int &version);
+    IMF_EXPORT
+    void                       readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                         int &version);
+    
 
   private:
 
     AttributeMap               _map;
+
+    bool                        _readsNothing;
 };
 
 
@@ -367,13 +512,19 @@ class Header::Iterator
 {
   public:
 
+    IMF_EXPORT
     Iterator ();
+    IMF_EXPORT
     Iterator (const Header::AttributeMap::iterator &i);
 
+    IMF_EXPORT
     Iterator &                 operator ++ ();
+    IMF_EXPORT
     Iterator                   operator ++ (int);
 
+    IMF_EXPORT
     const char *               name () const;
+    IMF_EXPORT
     Attribute &                        attribute () const;
 
   private:
@@ -388,14 +539,21 @@ class Header::ConstIterator
 {
   public:
 
+    IMF_EXPORT
     ConstIterator ();
+    IMF_EXPORT
     ConstIterator (const Header::AttributeMap::const_iterator &i);
+    IMF_EXPORT
     ConstIterator (const Header::Iterator &other);
 
+    IMF_EXPORT
     ConstIterator &            operator ++ ();
+    IMF_EXPORT
     ConstIterator              operator ++ (int);
 
+    IMF_EXPORT
     const char *               name () const;
+    IMF_EXPORT
     const Attribute &          attribute () const;
 
   private:
@@ -421,7 +579,7 @@ class Header::ConstIterator
 //
 //------------------------------------------------------------------------
 
-void staticInitialize ();
+void IMF_EXPORT staticInitialize ();
 
 
 //-----------------
@@ -443,7 +601,7 @@ Header::Iterator::Iterator (const Header::AttributeMap::iterator &i): _i (i)
 }
 
 
-inline Header::Iterator &
+inline Header::Iterator &              
 Header::Iterator::operator ++ ()
 {
     ++_i;
@@ -451,7 +609,7 @@ Header::Iterator::operator ++ ()
 }
 
 
-inline Header::Iterator
+inline Header::Iterator        
 Header::Iterator::operator ++ (int)
 {
     Iterator tmp = *this;
@@ -467,7 +625,7 @@ Header::Iterator::name () const
 }
 
 
-inline Attribute &
+inline Attribute &     
 Header::Iterator::attribute () const
 {
     return *_i->second;
@@ -503,7 +661,7 @@ Header::ConstIterator::operator ++ ()
 }
 
 
-inline Header::ConstIterator
+inline Header::ConstIterator           
 Header::ConstIterator::operator ++ (int)
 {
     ConstIterator tmp = *this;
@@ -519,7 +677,7 @@ Header::ConstIterator::name () const
 }
 
 
-inline const Attribute &
+inline const Attribute &       
 Header::ConstIterator::attribute () const
 {
     return *_i->second;
@@ -552,7 +710,7 @@ Header::typedAttribute (const char name[])
     T *tattr = dynamic_cast <T*> (attr);
 
     if (tattr == 0)
-    throw Iex::TypeExc ("Unexpected attribute type.");
+       throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return *tattr;
 }
@@ -566,7 +724,7 @@ Header::typedAttribute (const char name[]) const
     const T *tattr = dynamic_cast <const T*> (attr);
 
     if (tattr == 0)
-    throw Iex::TypeExc ("Unexpected attribute type.");
+       throw IEX_NAMESPACE::TypeExc ("Unexpected attribute type.");
 
     return *tattr;
 }
@@ -622,6 +780,6 @@ Header::findTypedAttribute (const std::string &name) const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 3450f11..97909a5 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include <ImfHuf.h>
 #include <ImfInt64.h>
-#include <ImfAutoArray.h>
+#include "ImfAutoArray.h"
+#include "ImfFastHuf.h"
 #include "Iex.h"
-#include <string.h>
-#include <assert.h>
+#include <cstring>
+#include <cassert>
 #include <algorithm>
 
 
 using namespace std;
-using namespace Iex;
+using namespace IEX_NAMESPACE;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 
@@ -71,10 +74,10 @@ const int HUF_DECMASK = HUF_DECSIZE - 1;
 
 struct HufDec
 {                              // short code           long code
-                //-------------------------------
-    int                len:8;          // code length          0
-    int                lit:24;         // lit                  p size
-    int        *       p;              // 0                    lits
+                               //-------------------------------
+    int                len:8;          // code length          0        
+    int                lit:24;         // lit                  p size   
+    int        *       p;              // 0                    lits     
 };
 
 
@@ -82,7 +85,7 @@ void
 invalidNBits ()
 {
     throw InputExc ("Error in header for Huffman-encoded data "
-            "(invalid number of bits).");
+                   "(invalid number of bits).");
 }
 
 
@@ -90,7 +93,7 @@ void
 tooMuchData ()
 {
     throw InputExc ("Error in Huffman-encoded data "
-            "(decoded data are longer than expected).");
+                   "(decoded data are longer than expected).");
 }
 
 
@@ -98,7 +101,7 @@ void
 notEnoughData ()
 {
     throw InputExc ("Error in Huffman-encoded data "
-            "(decoded data are shorter than expected).");
+                   "(decoded data are shorter than expected).");
 }
 
 
@@ -106,7 +109,7 @@ void
 invalidCode ()
 {
     throw InputExc ("Error in Huffman-encoded data "
-            "(invalid code).");
+                   "(invalid code).");
 }
 
 
@@ -114,7 +117,7 @@ void
 invalidTableSize ()
 {
     throw InputExc ("Error in Huffman-encoded data "
-            "(invalid code table size).");
+                   "(invalid code table size).");
 }
 
 
@@ -122,7 +125,7 @@ void
 unexpectedEndOfTable ()
 {
     throw InputExc ("Error in Huffman-encoded data "
-            "(unexpected end of code table data).");
+                   "(unexpected end of code table data).");
 }
 
 
@@ -130,7 +133,7 @@ void
 tableTooLong ()
 {
     throw InputExc ("Error in Huffman-encoded data "
-            "(code table is longer than expected).");
+                   "(code table is longer than expected).");
 }
 
 
@@ -138,7 +141,7 @@ void
 invalidTableEntry ()
 {
     throw InputExc ("Error in Huffman-encoded data "
-            "(invalid code table entry).");
+                   "(invalid code table entry).");
 }
 
 
@@ -165,7 +168,7 @@ outputBits (int nBits, Int64 bits, Int64 &c, int &lc, char *&out)
     c |= bits;
 
     while (lc >= 8)
-    *out++ = (c >> (lc -= 8));
+       *out++ = (c >> (lc -= 8));
 }
 
 
@@ -174,8 +177,8 @@ getBits (int nBits, Int64 &c, int &lc, const char *&in)
 {
     while (lc < nBits)
     {
-    c = (c << 8) | *(unsigned char *)(in++);
-    lc += 8;
+       c = (c << 8) | *(unsigned char *)(in++);
+       lc += 8;
     }
 
     lc -= nBits;
@@ -215,10 +218,10 @@ hufCanonicalCodeTable (Int64 hcode[HUF_ENCSIZE])
     //
 
     for (int i = 0; i <= 58; ++i)
-    n[i] = 0;
+       n[i] = 0;
 
     for (int i = 0; i < HUF_ENCSIZE; ++i)
-    n[hcode[i]] += 1;
+       n[hcode[i]] += 1;
 
     //
     // For each i from 58 through 1, compute the
@@ -230,9 +233,9 @@ hufCanonicalCodeTable (Int64 hcode[HUF_ENCSIZE])
 
     for (int i = 58; i > 0; --i)
     {
-    Int64 nc = ((c + n[i]) >> 1);
-    n[i] = c;
-    c = nc;
+       Int64 nc = ((c + n[i]) >> 1);
+       n[i] = c;
+       c = nc;
     }
 
     //
@@ -244,10 +247,10 @@ hufCanonicalCodeTable (Int64 hcode[HUF_ENCSIZE])
 
     for (int i = 0; i < HUF_ENCSIZE; ++i)
     {
-    int l = hcode[i];
+       int l = hcode[i];
 
-    if (l > 0)
-        hcode[i] = l | (n[l]++ << 6);
+       if (l > 0)
+           hcode[i] = l | (n[l]++ << 6);
     }
 }
 
@@ -301,20 +304,20 @@ hufBuildEncTable
     *im = 0;
 
     while (!frq[*im])
-    (*im)++;
+       (*im)++;
 
     int nf = 0;
 
     for (int i = *im; i < HUF_ENCSIZE; i++)
     {
-    hlink[i] = i;
-
-    if (frq[i])
-    {
-        fHeap[nf] = &frq[i];
-        nf++;
-        *iM = i;
-    }
+       hlink[i] = i;
+
+       if (frq[i])
+       {
+           fHeap[nf] = &frq[i];
+           nf++;
+           *iM = i;
+       }
     }
 
     //
@@ -363,71 +366,71 @@ hufBuildEncTable
 
     while (nf > 1)
     {
-    //
-    // Find the indices, mm and m, of the two smallest non-zero frq
-    // values in fHeap, add the smallest frq to the second-smallest
-    // frq, and remove the smallest frq value from fHeap.
-    //
-
-    int mm = fHeap[0] - frq;
-    pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare());
-    --nf;
-
-    int m = fHeap[0] - frq;
-    pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare());
-
-    frq[m ] += frq[mm];
-    push_heap (&fHeap[0], &fHeap[nf], FHeapCompare());
-
-    //
-    // The entries in scode are linked into lists with the
-    // entries in hlink serving as "next" pointers and with
-    // the end of a list marked by hlink[j] == j.
-    //
-    // Traverse the lists that start at scode[m] and scode[mm].
-    // For each element visited, increment the length of the
-    // corresponding code by one bit. (If we visit scode[j]
-    // during the traversal, then the code for symbol j becomes
-    // one bit longer.)
-    //
-    // Merge the lists that start at scode[m] and scode[mm]
-    // into a single list that starts at scode[m].
-    //
-
-    //
-    // Add a bit to all codes in the first list.
-    //
-
-    for (int j = m; true; j = hlink[j])
-    {
-        scode[j]++;
-
-        assert (scode[j] <= 58);
-
-        if (hlink[j] == j)
-        {
-        //
-        // Merge the two lists.
-        //
-
-        hlink[j] = mm;
-        break;
-        }
-    }
-
-    //
-    // Add a bit to all codes in the second list
-    //
-
-    for (int j = mm; true; j = hlink[j])
-    {
-        scode[j]++;
-
-        assert (scode[j] <= 58);
-
-        if (hlink[j] == j)
-        break;
-    }
+       //
+       // Find the indices, mm and m, of the two smallest non-zero frq
+       // values in fHeap, add the smallest frq to the second-smallest
+       // frq, and remove the smallest frq value from fHeap.
+       //
+
+       int mm = fHeap[0] - frq;
+       pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare());
+       --nf;
+
+       int m = fHeap[0] - frq;
+       pop_heap (&fHeap[0], &fHeap[nf], FHeapCompare());
+
+       frq[m ] += frq[mm];
+       push_heap (&fHeap[0], &fHeap[nf], FHeapCompare());
+
+       //
+       // The entries in scode are linked into lists with the
+       // entries in hlink serving as "next" pointers and with
+       // the end of a list marked by hlink[j] == j.
+       //
+       // Traverse the lists that start at scode[m] and scode[mm].
+       // For each element visited, increment the length of the
+       // corresponding code by one bit. (If we visit scode[j]
+       // during the traversal, then the code for symbol j becomes
+       // one bit longer.)
+       //
+       // Merge the lists that start at scode[m] and scode[mm]
+       // into a single list that starts at scode[m].
+       //
+       
+       //
+       // Add a bit to all codes in the first list.
+       //
+
+       for (int j = m; true; j = hlink[j])
+       {
+           scode[j]++;
+
+           assert (scode[j] <= 58);
+
+           if (hlink[j] == j)
+           {
+               //
+               // Merge the two lists.
+               //
+
+               hlink[j] = mm;
+               break;
+           }
+       }
+
+       //
+       // Add a bit to all codes in the second list
+       //
+
+       for (int j = mm; true; j = hlink[j])
+       {
+           scode[j]++;
+
+           assert (scode[j] <= 58);
+
+           if (hlink[j] == j)
+               break;
+       }
     }
 
     //
@@ -475,40 +478,40 @@ hufPackEncTable
 
     for (; im <= iM; im++)
     {
-    int l = hufLength (hcode[im]);
-
-    if (l == 0)
-    {
-        int zerun = 1;
-
-        while ((im < iM) && (zerun < LONGEST_LONG_RUN))
-        {
-        if (hufLength (hcode[im+1]) > 0 )
-            break;
-        im++;
-        zerun++;
-        }
-
-        if (zerun >= 2)
-        {
-        if (zerun >= SHORTEST_LONG_RUN)
-        {
-            outputBits (6, LONG_ZEROCODE_RUN, c, lc, p);
-            outputBits (8, zerun - SHORTEST_LONG_RUN, c, lc, p);
-        }
-        else
-        {
-            outputBits (6, SHORT_ZEROCODE_RUN + zerun - 2, c, lc, p);
-        }
-        continue;
-        }
-    }
-
-    outputBits (6, l, c, lc, p);
+       int l = hufLength (hcode[im]);
+
+       if (l == 0)
+       {
+           int zerun = 1;
+
+           while ((im < iM) && (zerun < LONGEST_LONG_RUN))
+           {
+               if (hufLength (hcode[im+1]) > 0 )        
+                   break;
+               im++;
+               zerun++;
+           }
+
+           if (zerun >= 2)
+           {
+               if (zerun >= SHORTEST_LONG_RUN)
+               {
+                   outputBits (6, LONG_ZEROCODE_RUN, c, lc, p);
+                   outputBits (8, zerun - SHORTEST_LONG_RUN, c, lc, p);
+               }
+               else
+               {
+                   outputBits (6, SHORT_ZEROCODE_RUN + zerun - 2, c, lc, p);
+               }
+               continue;
+           }
+       }
+
+       outputBits (6, l, c, lc, p);
     }
 
     if (lc > 0)
-    *p++ = (unsigned char) (c << (8 - lc));
+       *p++ = (unsigned char) (c << (8 - lc));
 
     *pcode = p;
 }
@@ -534,41 +537,41 @@ hufUnpackEncTable
 
     for (; im <= iM; im++)
     {
-    if (p - *pcode > ni)
-        unexpectedEndOfTable();
+       if (p - *pcode > ni)
+           unexpectedEndOfTable();
 
-    Int64 l = hcode[im] = getBits (6, c, lc, p); // code length
+       Int64 l = hcode[im] = getBits (6, c, lc, p); // code length
 
-    if (l == (Int64) LONG_ZEROCODE_RUN)
-    {
-        if (p - *pcode > ni)
-        unexpectedEndOfTable();
+       if (l == (Int64) LONG_ZEROCODE_RUN)
+       {
+           if (p - *pcode > ni)
+               unexpectedEndOfTable();
 
-        int zerun = getBits (8, c, lc, p) + SHORTEST_LONG_RUN;
+           int zerun = getBits (8, c, lc, p) + SHORTEST_LONG_RUN;
 
-        if (im + zerun > iM + 1)
-        tableTooLong();
+           if (im + zerun > iM + 1)
+               tableTooLong();
 
-        while (zerun--)
-        hcode[im++] = 0;
+           while (zerun--)
+               hcode[im++] = 0;
 
-        im--;
-    }
-    else if (l >= (Int64) SHORT_ZEROCODE_RUN)
-    {
-        int zerun = l - SHORT_ZEROCODE_RUN + 2;
+           im--;
+       }
+       else if (l >= (Int64) SHORT_ZEROCODE_RUN)
+       {
+           int zerun = l - SHORT_ZEROCODE_RUN + 2;
 
-        if (im + zerun > iM + 1)
-        tableTooLong();
+           if (im + zerun > iM + 1)
+               tableTooLong();
 
-        while (zerun--)
-        hcode[im++] = 0;
+           while (zerun--)
+               hcode[im++] = 0;
 
-        im--;
-    }
+           im--;
+       }
     }
 
-    *pcode = (char *) p;
+    *pcode = const_cast<char *>(p);
 
     hufCanonicalCodeTable (hcode);
 }
@@ -585,7 +588,7 @@ hufUnpackEncTable
 void
 hufClearDecTable
     (HufDec *          hdecod)         // io: (allocated by caller)
-                        //     decoding table [HUF_DECSIZE]
+                                       //     decoding table [HUF_DECSIZE]
 {
     memset (hdecod, 0, sizeof (HufDec) * HUF_DECSIZE);
 }
@@ -605,7 +608,7 @@ hufBuildDecTable
      int               im,             // i : min index in hcode
      int               iM,             // i : max index in hcode
      HufDec *          hdecod)         //  o: (allocated by caller)
-                        //     decoding table [HUF_DECSIZE]
+                                       //     decoding table [HUF_DECSIZE]
 {
     //
     // Init hashtable & loop on all codes.
@@ -614,81 +617,81 @@ hufBuildDecTable
 
     for (; im <= iM; im++)
     {
-    Int64 c = hufCode (hcode[im]);
-    int l = hufLength (hcode[im]);
-
-    if (c >> l)
-    {
-        //
-        // Error: c is supposed to be an l-bit code,
-        // but c contains a value that is greater
-        // than the largest l-bit number.
-        //
-
-        invalidTableEntry();
-    }
-
-    if (l > HUF_DECBITS)
-    {
-        //
-        // Long code: add a secondary entry
-        //
-
-        HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));
-
-        if (pl->len)
-        {
-        //
-        // Error: a short code has already
-        // been stored in table entry *pl.
-        //
-
-        invalidTableEntry();
-        }
-
-        pl->lit++;
-
-        if (pl->p)
-        {
-        int *p = pl->p;
-        pl->p = new int [pl->lit];
-
-        for (int i = 0; i < pl->lit - 1; ++i)
-            pl->p[i] = p[i];
-
-        delete [] p;
-        }
-        else
-        {
-        pl->p = new int [1];
-        }
-
-        pl->p[pl->lit - 1]= im;
-    }
-    else if (l)
-    {
-        //
-        // Short code: init all primary entries
-        //
-
-        HufDec *pl = hdecod + (c << (HUF_DECBITS - l));
-
-        for (Int64 i = 1 << (HUF_DECBITS - l); i > 0; i--, pl++)
-        {
-        if (pl->len || pl->p)
-        {
-            //
-            // Error: a short code or a long code has
-            // already been stored in table entry *pl.
-            //
-
-            invalidTableEntry();
-        }
-
-        pl->len = l;
-        pl->lit = im;
-        }
-    }
+       Int64 c = hufCode (hcode[im]);
+       int l = hufLength (hcode[im]);
+
+       if (c >> l)
+       {
+           //
+           // Error: c is supposed to be an l-bit code,
+           // but c contains a value that is greater
+           // than the largest l-bit number.
+           //
+
+           invalidTableEntry();
+       }
+
+       if (l > HUF_DECBITS)
+       {
+           //
+           // Long code: add a secondary entry
+           //
+
+           HufDec *pl = hdecod + (c >> (l - HUF_DECBITS));
+
+           if (pl->len)
+           {
+               //
+               // Error: a short code has already
+               // been stored in table entry *pl.
+               //
+
+               invalidTableEntry();
+           }
+
+           pl->lit++;
+
+           if (pl->p)
+           {
+               int *p = pl->p;
+               pl->p = new int [pl->lit];
+
+               for (int i = 0; i < pl->lit - 1; ++i)
+                   pl->p[i] = p[i];
+
+               delete [] p;
+           }
+           else
+           {
+               pl->p = new int [1];
+           }
+
+           pl->p[pl->lit - 1]= im;
+       }
+       else if (l)
+       {
+           //
+           // Short code: init all primary entries
+           //
+
+           HufDec *pl = hdecod + (c << (HUF_DECBITS - l));
+
+           for (Int64 i = 1 << (HUF_DECBITS - l); i > 0; i--, pl++)
+           {
+               if (pl->len || pl->p)
+               {
+                   //
+                   // Error: a short code or a long code has
+                   // already been stored in table entry *pl.
+                   //
+
+                   invalidTableEntry();
+               }
+
+               pl->len = l;
+               pl->lit = im;
+           }
+       }
     }
 }
 
@@ -702,11 +705,11 @@ hufFreeDecTable (HufDec *hdecod)  // io: Decoding table
 {
     for (int i = 0; i < HUF_DECSIZE; i++)
     {
-    if (hdecod[i].p)
-    {
-        delete [] hdecod[i].p;
-        hdecod[i].p = 0;
-    }
+       if (hdecod[i].p)
+       {
+           delete [] hdecod[i].p;
+           hdecod[i].p = 0;
+       }
     }
 }
 
@@ -724,20 +727,26 @@ outputCode (Int64 code, Int64 &c, int &lc, char *&out)
 
 inline void
 sendCode (Int64 sCode, int runCount, Int64 runCode,
-      Int64 &c, int &lc, char *&out)
+         Int64 &c, int &lc, char *&out)
 {
-    static const int RLMIN = 32; // min count to activate run-length coding
-
-    if (runCount > RLMIN)
+    //
+    // Output a run of runCount instances of the symbol sCount.
+    // Output the symbols explicitly, or if that is shorter, output
+    // the sCode symbol once followed by a runCode symbol and runCount
+    // expressed as an 8-bit number.
+    //
+    
+    if (hufLength (sCode) + hufLength (runCode) + 8 <
+        hufLength (sCode) * runCount)
     {
-    outputCode (sCode, c, lc, out);
-    outputCode (runCode, c, lc, out);
-    outputBits (8, runCount, c, lc, out);
+       outputCode (sCode, c, lc, out);
+       outputCode (runCode, c, lc, out);
+       outputBits (8, runCount, c, lc, out);
     }
     else
     {
-    while (runCount-- >= 0)
-        outputCode (sCode, c, lc, out);
+       while (runCount-- >= 0)
+           outputCode (sCode, c, lc, out);
     }
 }
 
@@ -766,21 +775,21 @@ hufEncode                         // return: output size (in bits)
 
     for (int i = 1; i < ni; i++)
     {
-    //
-    // Count same values or send code
-    //
-
-    if (s == in[i] && cs < 255)
-    {
-        cs++;
-    }
-    else
-    {
-        sendCode (hcode[s], cs, hcode[rlc], c, lc, out);
-        cs=0;
-    }
-
-    s = in[i];
+       //
+       // Count same values or send code
+       //
+
+       if (s == in[i] && cs < 255)
+       {
+           cs++;
+       }
+       else
+       {
+           sendCode (hcode[s], cs, hcode[rlc], c, lc, out);
+           cs=0;
+       }
+
+       s = in[i];
     }
 
     //
@@ -790,7 +799,7 @@ hufEncode                           // return: output size (in bits)
     sendCode (hcode[s], cs, hcode[rlc], c, lc, out);
 
     if (lc)
-    *out = (c << (8 - lc)) & 0xff;
+       *out = (c << (8 - lc)) & 0xff;
 
     return (out - outStart) * 8 + lc;
 }
@@ -813,32 +822,34 @@ hufEncode                         // return: output size (in bits)
 }
 
 
-#define getCode(po, rlc, c, lc, in, out, oe)   \
+#define getCode(po, rlc, c, lc, in, out, ob, oe)\
 {                                              \
     if (po == rlc)                             \
     {                                          \
-    if (lc < 8)                                \
-        getChar(c, lc, in);                    \
-                        \
-    lc -= 8;                           \
-                        \
-    unsigned char cs = (c >> lc);              \
-                        \
-    if (out + cs > oe)                 \
-        tooMuchData();                 \
-                        \
-    unsigned short s = out[-1];                \
-                        \
-    while (cs-- > 0)                   \
-        *out++ = s;                            \
+       if (lc < 8)                             \
+           getChar(c, lc, in);                 \
+                                               \
+       lc -= 8;                                \
+                                               \
+       unsigned char cs = (c >> lc);           \
+                                               \
+       if (out + cs > oe)                      \
+           tooMuchData();                      \
+       else if (out - 1 < ob)                  \
+           notEnoughData();                    \
+                                               \
+       unsigned short s = out[-1];             \
+                                               \
+       while (cs-- > 0)                        \
+           *out++ = s;                         \
     }                                          \
     else if (out < oe)                         \
     {                                          \
-    *out++ = po;                               \
+       *out++ = po;                            \
     }                                          \
     else                                       \
     {                                          \
-    tooMuchData();                             \
+       tooMuchData();                          \
     }                                          \
 }
 
@@ -869,63 +880,63 @@ hufDecode
 
     while (in < ie)
     {
-    getChar (c, lc, in);
-
-    //
-    // Access decoding table
-    //
-
-    while (lc >= HUF_DECBITS)
-    {
-        const HufDec pl = hdecod[(c >> (lc-HUF_DECBITS)) & HUF_DECMASK];
-
-        if (pl.len)
-        {
-        //
-        // Get short code
-        //
-
-        lc -= pl.len;
-        getCode (pl.lit, rlc, c, lc, in, out, oe);
-        }
-        else
-        {
-        if (!pl.p)
-            invalidCode(); // wrong code
-
-        //
-        // Search long code
-        //
-
-        int j;
-
-        for (j = 0; j < pl.lit; j++)
-        {
-            int        l = hufLength (hcode[pl.p[j]]);
-
-            while (lc < l && in < ie)  // get more bits
-            getChar (c, lc, in);
-
-            if (lc >= l)
-            {
-            if (hufCode (hcode[pl.p[j]]) ==
-                ((c >> (lc - l)) & ((Int64(1) << l) - 1)))
-            {
-                //
-                // Found : get long code
-                //
-
-                lc -= l;
-                getCode (pl.p[j], rlc, c, lc, in, out, oe);
-                break;
-            }
-            }
-        }
-
-        if (j == pl.lit)
-            invalidCode(); // Not found
-        }
-    }
+       getChar (c, lc, in);
+
+       //
+       // Access decoding table
+       //
+
+       while (lc >= HUF_DECBITS)
+       {
+           const HufDec pl = hdecod[(c >> (lc-HUF_DECBITS)) & HUF_DECMASK];
+
+           if (pl.len)
+           {
+               //
+               // Get short code
+               //
+
+               lc -= pl.len;
+               getCode (pl.lit, rlc, c, lc, in, out, outb, oe);
+           }
+           else
+           {
+               if (!pl.p)
+                   invalidCode(); // wrong code
+
+               //
+               // Search long code
+               //
+
+               int j;
+
+               for (j = 0; j < pl.lit; j++)
+               {
+                   int l = hufLength (hcode[pl.p[j]]);
+
+                   while (lc < l && in < ie)   // get more bits
+                       getChar (c, lc, in);
+
+                   if (lc >= l)
+                   {
+                       if (hufCode (hcode[pl.p[j]]) ==
+                               ((c >> (lc - l)) & ((Int64(1) << l) - 1)))
+                       {
+                           //
+                           // Found : get long code
+                           //
+
+                           lc -= l;
+                           getCode (pl.p[j], rlc, c, lc, in, out, outb, oe);
+                           break;
+                       }
+                   }
+               }
+
+               if (j == pl.lit)
+                   invalidCode(); // Not found
+           }
+       }
     }
 
     //
@@ -938,34 +949,34 @@ hufDecode
 
     while (lc > 0)
     {
-    const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];
-
-    if (pl.len)
-    {
-        lc -= pl.len;
-        getCode (pl.lit, rlc, c, lc, in, out, oe);
-    }
-    else
-    {
-        invalidCode(); // wrong (long) code
-    }
+       const HufDec pl = hdecod[(c << (HUF_DECBITS - lc)) & HUF_DECMASK];
+
+       if (pl.len)
+       {
+           lc -= pl.len;
+           getCode (pl.lit, rlc, c, lc, in, out, outb, oe);
+       }
+       else
+       {
+           invalidCode(); // wrong (long) code
+       }
     }
 
     if (out - outb != no)
-    notEnoughData ();
+       notEnoughData ();
 }
 
 
 void
 countFrequencies (Int64 freq[HUF_ENCSIZE],
-          const unsigned short data[/*n*/],
-          int n)
+                 const unsigned short data[/*n*/],
+                 int n)
 {
     for (int i = 0; i < HUF_ENCSIZE; ++i)
-    freq[i] = 0;
+       freq[i] = 0;
 
     for (int i = 0; i < n; ++i)
-    ++freq[data[i]];
+       ++freq[data[i]];
 }
 
 
@@ -987,9 +998,9 @@ readUInt (const char buf[4])
     const unsigned char *b = (const unsigned char *) buf;
 
     return ( b[0]        & 0x000000ff) |
-       ((b[1] <<  8) & 0x0000ff00) |
-       ((b[2] << 16) & 0x00ff0000) |
-       ((b[3] << 24) & 0xff000000);
+          ((b[1] <<  8) & 0x0000ff00) |
+          ((b[2] << 16) & 0x00ff0000) |
+          ((b[3] << 24) & 0xff000000);
 }
 
 } // namespace
@@ -1002,17 +1013,18 @@ readUInt (const char buf[4])
 
 int
 hufCompress (const unsigned short raw[],
-         int nRaw,
-         char compressed[])
+            int nRaw,
+            char compressed[])
 {
     if (nRaw == 0)
-    return 0;
+       return 0;
 
     AutoArray <Int64, HUF_ENCSIZE> freq;
 
     countFrequencies (freq, raw, nRaw);
 
-    int im, iM;
+    int im = 0;
+    int iM = 0;
     hufBuildEncTable (freq, &im, &iM);
 
     char *tableStart = compressed + 20;
@@ -1036,16 +1048,16 @@ hufCompress (const unsigned short raw[],
 
 void
 hufUncompress (const char compressed[],
-           int nCompressed,
-           unsigned short raw[],
-           int nRaw)
+              int nCompressed,
+              unsigned short raw[],
+              int nRaw)
 {
     if (nCompressed == 0)
     {
-    if (nRaw != 0)
-        notEnoughData();
+       if (nRaw != 0)
+           notEnoughData();
 
-    return;
+       return;
     }
 
     int im = readUInt (compressed);
@@ -1054,33 +1066,51 @@ hufUncompress (const char compressed[],
     int nBits = readUInt (compressed + 12);
 
     if (im < 0 || im >= HUF_ENCSIZE || iM < 0 || iM >= HUF_ENCSIZE)
-    invalidTableSize();
+       invalidTableSize();
 
     const char *ptr = compressed + 20;
 
-    AutoArray <Int64, HUF_ENCSIZE> freq;
-    AutoArray <HufDec, HUF_DECSIZE> hdec;
-
-    hufClearDecTable (hdec);
-
-    hufUnpackEncTable (&ptr, nCompressed - (ptr - compressed), im, iM, freq);
+    // 
+    // Fast decoder needs at least 2x64-bits of compressed data, and
+    // needs to be run-able on this platform. Otherwise, fall back
+    // to the original decoder
+    //
 
-    try
+    if (FastHufDecoder::enabled() && nBits > 128)
     {
-    if (nBits > 8 * (nCompressed - (ptr - compressed)))
-        invalidNBits();
-
-    hufBuildDecTable (freq, im, iM, hdec);
-    hufDecode (freq, hdec, ptr, nBits, iM, nRaw, raw);
+        FastHufDecoder fhd (ptr, nCompressed - (ptr - compressed), im, iM, iM);
+        fhd.decode ((unsigned char*)ptr, nBits, raw, nRaw);
     }
-    catch (...)
+    else
     {
-    hufFreeDecTable (hdec);
-    throw;
-    }
+        AutoArray <Int64, HUF_ENCSIZE> freq;
+        AutoArray <HufDec, HUF_DECSIZE> hdec;
+
+        hufClearDecTable (hdec);
 
-    hufFreeDecTable (hdec);
+        hufUnpackEncTable (&ptr,
+                           nCompressed - (ptr - compressed),
+                           im,
+                           iM,
+                           freq);
+
+        try
+        {
+            if (nBits > 8 * (nCompressed - (ptr - compressed)))
+                invalidNBits();
+
+            hufBuildDecTable (freq, im, iM, hdec);
+            hufDecode (freq, hdec, ptr, nBits, iM, nRaw, raw);
+        }
+        catch (...)
+        {
+            hufFreeDecTable (hdec);
+            throw;
+        }
+
+        hufFreeDecTable (hdec);
+    }
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 776d04b..fa89604 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -37,6 +37,8 @@
 #ifndef INCLUDED_IMF_HUF_H
 #define INCLUDED_IMF_HUF_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
 //-----------------------------------------------------------------------------
 //
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
+IMF_EXPORT 
 int
 hufCompress (const unsigned short raw[/*nRaw*/],
-         int nRaw,
-         char compressed[/*2 * nRaw + 65536*/]);
-
+            int nRaw,
+            char compressed[/*2 * nRaw + 65536*/]);
 
+IMF_EXPORT
 void
 hufUncompress (const char compressed[/*nCompressed*/],
-           int nCompressed,
-           unsigned short raw[/*nRaw*/],
-           int nRaw);
+              int nCompressed,
+              unsigned short raw[/*nRaw*/],
+              int nRaw);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 0c651aa..c52fc54 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -41,8 +41,9 @@
 
 #include <ImfIO.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 IStream::IStream (const char fileName[]): _fileName (fileName)
@@ -65,10 +66,10 @@ IStream::isMemoryMapped () const
 
 
 char *
-IStream::readMemoryMapped (int)
+IStream::readMemoryMapped (int n)
 {
-    throw Iex::InputExc ("Attempt to perform a memory-mapped read "
-             "on a file that is not memory mapped.");
+    throw IEX_NAMESPACE::InputExc ("Attempt to perform a memory-mapped read "
+                        "on a file that is not memory mapped.");
     return 0;
 }
 
@@ -106,4 +107,4 @@ OStream::fileName () const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 1e634fb..8c32fea 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfInt64.h>
+#include "ImfInt64.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <string>
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //-----------------------------------------------------------
 // class IStream -- an abstract base class for input streams.
@@ -59,9 +63,10 @@ class IStream
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~IStream ();
-
-
+    
+    
     //-------------------------------------------------
     // Does this input stream support memory-mapped IO?
     //
@@ -71,6 +76,7 @@ class IStream
     // into a buffer supplied by the caller.
     //-------------------------------------------------
 
+    IMF_EXPORT
     virtual bool        isMemoryMapped () const;
 
 
@@ -85,8 +91,8 @@ class IStream
     //------------------------------------------------------
 
     virtual bool       read (char c[/*n*/], int n) = 0;
-
-
+    
+    
     //---------------------------------------------------
     // Read from a memory-mapped stream:
     //
@@ -95,9 +101,10 @@ class IStream
     // returned pointer remains valid until the stream
     // is closed.  If there are less than n byte left to
     // read in the stream or if the stream is not memory-
-    // mapped, readMemoryMapped(n) throws an exception.
+    // mapped, readMemoryMapped(n) throws an exception.  
     //---------------------------------------------------
 
+    IMF_EXPORT
     virtual char *     readMemoryMapped (int n);
 
 
@@ -122,6 +129,7 @@ class IStream
     // Clear error conditions after an operation has failed.
     //------------------------------------------------------
 
+    IMF_EXPORT
     virtual void       clear ();
 
 
@@ -129,10 +137,12 @@ class IStream
     // Get the name of the file associated with this stream.
     //------------------------------------------------------
 
+    IMF_EXPORT
     const char *       fileName () const;
 
   protected:
 
+    IMF_EXPORT
     IStream (const char fileName[]);
 
   private:
@@ -156,8 +166,9 @@ class OStream
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~OStream ();
-
+  
 
     //----------------------------------------------------------
     // Write to the stream:
@@ -192,10 +203,12 @@ class OStream
     // Get the name of the file associated with this stream.
     //------------------------------------------------------
 
+    IMF_EXPORT
     const char *       fileName () const;
 
   protected:
 
+    IMF_EXPORT
     OStream (const char fileName[]);
 
   private:
@@ -216,13 +229,13 @@ struct StreamIO
     static void
     writeChars (OStream &os, const char c[/*n*/], int n)
     {
-    os.write (c, n);
+        os.write (c, n);
     }
 
     static bool
     readChars (IStream &is, char c[/*n*/], int n)
     {
-    return is.read (c, n);
+        return is.read (c, n);
     }
 };
 
@@ -232,21 +245,20 @@ struct CharPtrIO
     static void
     writeChars (char *&op, const char c[/*n*/], int n)
     {
-    while (n--)
-        *op++ = *c++;
+        while (n--)
+            *op++ = *c++;
     }
 
     static bool
     readChars (const char *&ip, char c[/*n*/], int n)
     {
-    while (n--)
-        *c++ = *ip++;
+        while (n--)
+            *c++ = *ip++;
 
-    return true;
+        return true;
     }
 };
 
-
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 5f031b2..4aa885e 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfInputFile.h>
-#include <ImfScanLineInputFile.h>
-#include <ImfTiledInputFile.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfStdIO.h>
-#include <ImfVersion.h>
+#include "ImfInputFile.h"
+#include "ImfScanLineInputFile.h"
+#include "ImfTiledInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfStdIO.h"
+#include "ImfVersion.h"
+#include "ImfPartType.h"
+#include "ImfInputPartData.h"
+#include "ImfMultiPartInputFile.h"
+
+#include <ImfCompositeDeepScanLine.h>
+#include <ImfDeepScanLineInputFile.h>
+
 #include "ImathFun.h"
 #include "IlmThreadMutex.h"
 #include "Iex.h"
 #include "half.h"
+
 #include <fstream>
 #include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
-using IlmThread::Mutex;
-using IlmThread::Lock;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
 
 
 //
@@ -68,43 +77,60 @@ using IlmThread::Lock;
 // needed between calls to readPixels
 //
 
-struct InputFile::Data: public Mutex
+struct InputFile::Data : public Mutex
 {
     Header              header;
     int                 version;
-    IStream *          is;
-    bool               deleteStream;
+    bool                isTiled;
 
     TiledInputFile *   tFile;
     ScanLineInputFile *        sFile;
+    DeepScanLineInputFile * dsFile;
 
     LineOrder          lineOrder;      // the file's lineorder
     int                        minY;           // data window's min y coord
     int                        maxY;           // data window's max x coord
-
-    FrameBuffer                tFileBuffer;
+    
+    FrameBuffer                tFileBuffer; 
     FrameBuffer *      cachedBuffer;
-
+    CompositeDeepScanLine * compositor; // for loading deep files
+    
     int                        cachedTileY;
     int                 offset;
-
+    
     int                 numThreads;
 
-     Data (bool del, int numThreads);
+    int                 partNumber;
+    InputPartData*      part;
+
+    bool                multiPartBackwardSupport;
+    MultiPartInputFile* multiPartFile;
+    InputStreamMutex    * _streamData;
+    bool                _deleteStream;
+
+     Data (int numThreads);
     ~Data ();
 
     void               deleteCachedBuffer();
 };
 
 
-InputFile::Data::Data (bool del, int numThreads):
-    is (0),
-    deleteStream (del),
+InputFile::Data::Data (int numThreads):
+    isTiled (false),
     tFile (0),
     sFile (0),
+    dsFile(0),
     cachedBuffer (0),
+    compositor(0),
     cachedTileY (-1),
-    numThreads (numThreads)
+    numThreads (numThreads),
+    partNumber (-1),
+    part(NULL),
+    multiPartBackwardSupport (false),
+    multiPartFile (0),
+    _streamData(0),
+    _deleteStream(false)
+           
 {
     // empty
 }
@@ -112,17 +138,23 @@ InputFile::Data::Data (bool del, int numThreads):
 
 InputFile::Data::~Data ()
 {
-    delete tFile;
-    delete sFile;
-
-    if (deleteStream)
-    delete is;
+    if (tFile)
+        delete tFile;
+    if (sFile)
+        delete sFile;
+    if (dsFile)
+        delete dsFile;
+    if (compositor)
+        delete compositor;
 
     deleteCachedBuffer();
+
+    if (multiPartBackwardSupport && multiPartFile)
+        delete multiPartFile;
 }
 
 
-void
+void   
 InputFile::Data::deleteCachedBuffer()
 {
     //
@@ -132,37 +164,39 @@ InputFile::Data::deleteCachedBuffer()
 
     if (cachedBuffer)
     {
-    for (FrameBuffer::Iterator k = cachedBuffer->begin();
-         k != cachedBuffer->end();
-         ++k)
-    {
-        Slice &s = k.slice();
+       for (FrameBuffer::Iterator k = cachedBuffer->begin();
+            k != cachedBuffer->end();
+            ++k)
+       {
+           Slice &s = k.slice();
 
-        switch (s.type)
-        {
-          case UINT:
+           switch (s.type)
+           {
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
-        delete [] (((unsigned int *)s.base) + offset);
-        break;
+               delete [] (((unsigned int *)s.base) + offset);
+               break;
 
-          case HALF:
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-        delete [] ((half *)s.base + offset);
-        break;
+               delete [] ((half *)s.base + offset);
+               break;
 
-          case FLOAT:
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-        delete [] (((float *)s.base) + offset);
-        break;
-        }
-    }
+               delete [] (((float *)s.base) + offset);
+               break;
+              case NUM_PIXELTYPES :
+                  throw(IEX_NAMESPACE::ArgExc("Invalid pixel type"));
+           }                
+       }
 
-    //
-    // delete the cached frame buffer
-    //
+       //
+       // delete the cached frame buffer
+       //
 
-    delete cachedBuffer;
-    cachedBuffer = 0;
+       delete cachedBuffer;
+       cachedBuffer = 0;
     }
 }
 
@@ -184,8 +218,8 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
 
     if (minY < ifd->minY || maxY >  ifd->maxY)
     {
-        throw Iex::ArgExc ("Tried to read scan line outside "
-               "the image file's data window.");
+        throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
+                          "the image file's data window.");
     }
 
     //
@@ -220,7 +254,7 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
     //
 
     Box2i levelRange = ifd->tFile->dataWindowForLevel(0);
-
+    
     //
     // Read the tiles into our temporary framebuffer and copy them into
     // the user's buffer
@@ -259,24 +293,24 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
             char *fromPtr, *toPtr;
             int size = pixelTypeSize (toSlice.type);
 
-        int xStart = levelRange.min.x;
-        int yStart = minYThisRow;
+           int xStart = levelRange.min.x;
+           int yStart = minYThisRow;
 
-        while (modp (xStart, toSlice.xSampling) != 0)
-        ++xStart;
+           while (modp (xStart, toSlice.xSampling) != 0)
+               ++xStart;
 
-        while (modp (yStart, toSlice.ySampling) != 0)
-        ++yStart;
+           while (modp (yStart, toSlice.ySampling) != 0)
+               ++yStart;
 
             for (int y = yStart;
-         y <= maxYThisRow;
-         y += toSlice.ySampling)
+                y <= maxYThisRow;
+                y += toSlice.ySampling)
             {
-        //
+               //
                 // Set the pointers to the start of the y scanline in
                 // this row of tiles
-        //
-
+               //
+                
                 fromPtr = fromSlice.base +
                           (y - tileRange.min.y) * fromSlice.yStride +
                           xStart * fromSlice.xStride;
@@ -285,19 +319,19 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
                         divp (y, toSlice.ySampling) * toSlice.yStride +
                         divp (xStart, toSlice.xSampling) * toSlice.xStride;
 
-        //
+               //
                 // Copy all pixels for the scanline in this row of tiles
-        //
+               //
 
                 for (int x = xStart;
-             x <= levelRange.max.x;
-             x += toSlice.xSampling)
+                    x <= levelRange.max.x;
+                    x += toSlice.xSampling)
                 {
-            for (size_t i = 0; i < size; ++i)
-            toPtr[i] = fromPtr[i];
+                   for (int i = 0; i < size; ++i)
+                       toPtr[i] = fromPtr[i];
 
-            fromPtr += fromSlice.xStride * toSlice.xSampling;
-            toPtr += toSlice.xStride;
+                   fromPtr += fromSlice.xStride * toSlice.xSampling;
+                   toPtr += toSlice.xStride;
                 }
             }
         }
@@ -309,95 +343,278 @@ bufferedReadPixels (InputFile::Data* ifd, int scanLine1, int scanLine2)
 
 
 InputFile::InputFile (const char fileName[], int numThreads):
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads))
 {
+    _data->_streamData = NULL;
+    _data->_deleteStream=true;
+    
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is = 0;
     try
     {
-    _data->is = new StdIFStream (fileName);
-    initialize();
+        is = new StdIFStream (fileName);
+        readMagicNumberAndVersionField(*is, _data->version);
+
+        //
+        // compatibility to read multipart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(*is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            
+            // fix type attribute in single part regular image types
+            // (may be wrong if an old version of OpenEXR converts
+            // a tiled image to scanline or vice versa)
+            if(!isNonImage(_data->version)  && 
+               !isMultiPart(_data->version) && 
+               _data->header.hasType())
+            {
+                _data->header.setType(isTiled(_data->version) ? TILEDIMAGE : SCANLINEIMAGE);
+            }
+            
+            _data->header.sanityCheck (isTiled (_data->version));
+
+            initialize();
+        }
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        if (is)          delete is;
+         
+        if ( _data && !_data->multiPartBackwardSupport  && _data->_streamData)
+        {
+            delete _data->_streamData;
+            _data->_streamData=NULL;
+        }
+        
+        if (_data)       delete _data;
+        _data=NULL;
 
         REPLACE_EXC (e, "Cannot read image file "
-            "\"" << fileName << "\". " << e);
+                     "\"" << fileName << "\". " << e.what());
         throw;
     }
     catch (...)
     {
-    delete _data;
+        if (is)          delete is;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData)
+        {
+            delete _data->_streamData;
+        }
+        if (_data)       delete _data;
+
         throw;
     }
 }
 
 
-InputFile::InputFile (IStream &is, int numThreads):
-    _data (new Data (false, numThreads))
+InputFile::InputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
+    _data (new Data (numThreads))
 {
+    _data->_streamData=NULL;
+    _data->_deleteStream=false;
     try
     {
-    _data->is = &is;
-    initialize();
+        readMagicNumberAndVersionField(is, _data->version);
+
+        //
+        // Backward compatibility to read multpart file.
+        //
+        if (isMultiPart(_data->version))
+        {
+            compatibilityInitialize(is);
+        }
+        else
+        {
+            _data->_streamData = new InputStreamMutex();
+            _data->_streamData->is = &is;
+            _data->header.readFrom (*_data->_streamData->is, _data->version);
+            
+            // fix type attribute in single part regular image types
+            // (may be wrong if an old version of OpenEXR converts
+            // a tiled image to scanline or vice versa)
+            if(!isNonImage(_data->version)  && 
+               !isMultiPart(_data->version) &&  
+               _data->header.hasType())
+            {
+                _data->header.setType(isTiled(_data->version) ? TILEDIMAGE : SCANLINEIMAGE);
+            }
+            
+            _data->header.sanityCheck (isTiled (_data->version));
+
+            initialize();
+        }
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        if (_data && !_data->multiPartBackwardSupport && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+        _data=NULL; 
 
         REPLACE_EXC (e, "Cannot read image file "
-            "\"" << is.fileName() << "\". " << e);
+                     "\"" << is.fileName() << "\". " << e.what());
         throw;
     }
     catch (...)
     {
-    delete _data;
+        if (_data &&  !_data->multiPartBackwardSupport  && _data->_streamData) delete _data->_streamData;
+        if (_data)       delete _data;
+        _data=NULL;
         throw;
     }
 }
 
 
-void
-InputFile::initialize ()
+InputFile::InputFile (InputPartData* part) :
+    _data (new Data (part->numThreads))
 {
-    _data->header.readFrom (*_data->is, _data->version);
-    _data->header.sanityCheck (isTiled (_data->version));
+    _data->_deleteStream=false;
+    multiPartInitialize (part);
+}
 
-    if (isTiled (_data->version))
-    {
-    _data->lineOrder = _data->header.lineOrder();
+
+void
+InputFile::compatibilityInitialize (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
+{
+    is.seekg(0);
 
     //
-    // Save the dataWindow information
+    // Construct a MultiPartInputFile, initialize InputFile
+    // with the part 0 data.
+    // (TODO) may want to have a way to set the reconstruction flag.
     //
+    _data->multiPartBackwardSupport = true;
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    InputPartData* part = _data->multiPartFile->getPart(0);
+
+    multiPartInitialize (part);
+}
+
+
+void
+InputFile::multiPartInitialize (InputPartData* part)
+{
+    _data->_streamData = part->mutex;
+    _data->version = part->version;
+    _data->header = part->header;
+    _data->partNumber = part->partNumber;
+    _data->part = part;
+
+    initialize();
+}
 
-    const Box2i &dataWindow = _data->header.dataWindow();
-    _data->minY = dataWindow.min.y;
-    _data->maxY = dataWindow.max.y;
 
-    _data->tFile = new TiledInputFile (_data->header,
-                       _data->is,
-                       _data->version,
-                                           _data->numThreads);
+void
+InputFile::initialize ()
+{
+    if (!_data->part)
+    {
+        if(_data->header.hasType() && _data->header.type()==DEEPSCANLINE)
+        {
+            _data->isTiled=false;
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+            
+            _data->dsFile = new DeepScanLineInputFile (_data->header,
+                                               _data->_streamData->is,
+                                               _data->version,
+                                               _data->numThreads);
+            _data->compositor = new CompositeDeepScanLine;
+            _data->compositor->addSource(_data->dsFile);
+        }
+        
+        else if (isTiled (_data->version))
+        {
+            _data->isTiled = true;
+            _data->lineOrder = _data->header.lineOrder();
+
+            //
+            // Save the dataWindow information
+            //
+    
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+
+            _data->tFile = new TiledInputFile (_data->header,
+                                               _data->_streamData->is,
+                                               _data->version,
+                                               _data->numThreads);
+        }
+        
+        else if(!_data->header.hasType() || _data->header.type()==SCANLINEIMAGE)
+        {
+            _data->sFile = new ScanLineInputFile (_data->header,
+                                                  _data->_streamData->is,
+                                                  _data->numThreads);
+        }else{
+            // type set but not recognised
+            
+            THROW(IEX_NAMESPACE::ArgExc, "InputFile cannot handle parts of type " << _data->header.type());
+        }
     }
     else
     {
-    _data->sFile = new ScanLineInputFile (_data->header,
-                          _data->is,
-                                              _data->numThreads);
+        if(_data->header.hasType() && _data->header.type()==DEEPSCANLINE)
+        {
+            _data->isTiled=false;
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+            
+            _data->dsFile = new DeepScanLineInputFile (_data->part);
+            _data->compositor = new CompositeDeepScanLine;
+            _data->compositor->addSource(_data->dsFile);
+        }
+        else if (isTiled (_data->header.type()))
+        {
+            _data->isTiled = true;
+            _data->lineOrder = _data->header.lineOrder();
+
+            //
+            // Save the dataWindow information
+            //
+
+            const Box2i &dataWindow = _data->header.dataWindow();
+            _data->minY = dataWindow.min.y;
+            _data->maxY = dataWindow.max.y;
+
+            _data->tFile = new TiledInputFile (_data->part);
+        }
+        else if(!_data->header.hasType() || _data->header.type()==SCANLINEIMAGE)
+        {
+            _data->sFile = new ScanLineInputFile (_data->part);
+        }else{
+            THROW(IEX_NAMESPACE::ArgExc, "InputFile cannot handle parts of type " << _data->header.type());
+            
+        }
     }
 }
 
-
+#include <iostream>
 InputFile::~InputFile ()
 {
-    delete _data;
-}
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
 
+    // unless this file was opened via the multipart API,
+    // delete the streamData object too
+    if (_data->partNumber==-1 && _data->_streamData)
+        delete _data->_streamData;
+
+    if (_data)  delete _data;
+}
 
 const char *
 InputFile::fileName () const
 {
-    return _data->is->fileName();
+    return _data->_streamData->is->fileName();
 }
 
 
@@ -418,120 +635,123 @@ InputFile::version () const
 void
 InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    if (isTiled (_data->version))
+    if (_data->isTiled)
     {
-    Lock lock (*_data);
+       Lock lock (*_data);
 
-    //
+       //
         // We must invalidate the cached buffer if the new frame
-    // buffer has a different set of channels than the old
-    // frame buffer, or if the type of a channel has changed.
-    //
+       // buffer has a different set of channels than the old
+       // frame buffer, or if the type of a channel has changed.
+       //
 
-    const FrameBuffer &oldFrameBuffer = _data->tFileBuffer;
+       const FrameBuffer &oldFrameBuffer = _data->tFileBuffer;
 
-    FrameBuffer::ConstIterator i = oldFrameBuffer.begin();
-    FrameBuffer::ConstIterator j = frameBuffer.begin();
+       FrameBuffer::ConstIterator i = oldFrameBuffer.begin();
+       FrameBuffer::ConstIterator j = frameBuffer.begin();
 
-    while (i != oldFrameBuffer.end() && j != frameBuffer.end())
-    {
-        if (strcmp (i.name(), j.name()) || i.slice().type != j.slice().type)
-        break;
+       while (i != oldFrameBuffer.end() && j != frameBuffer.end())
+       {
+           if (strcmp (i.name(), j.name()) || i.slice().type != j.slice().type)
+               break;
 
-        ++i;
-        ++j;
-    }
+           ++i;
+           ++j;
+       }
 
-    if (i != oldFrameBuffer.end() || j != frameBuffer.end())
+       if (i != oldFrameBuffer.end() || j != frameBuffer.end())
         {
-        //
-        // Invalidate the cached buffer.
-        //
+           //
+           // Invalidate the cached buffer.
+           //
 
             _data->deleteCachedBuffer ();
-        _data->cachedTileY = -1;
-
-        //
-        // Create new a cached frame buffer.  It can hold a single
-        // row of tiles.  The cached buffer can be reused for each
-        // row of tiles because we set the yTileCoords parameter of
-        // each Slice to true.
-        //
-
-        const Box2i &dataWindow = _data->header.dataWindow();
-        _data->cachedBuffer = new FrameBuffer();
-        _data->offset = dataWindow.min.x;
-
-        int tileRowSize = (dataWindow.max.x - dataWindow.min.x + 1) *
-                  _data->tFile->tileYSize();
-
-        for (FrameBuffer::ConstIterator k = frameBuffer.begin();
-         k != frameBuffer.end();
-         ++k)
-        {
-        Slice s = k.slice();
-
-        switch (s.type)
-        {
-          case UINT:
-
-            _data->cachedBuffer->insert
-            (k.name(),
-             Slice (UINT,
-                (char *)(new unsigned int[tileRowSize] -
-                    _data->offset),
-                sizeof (unsigned int),
-                sizeof (unsigned int) *
-                    _data->tFile->levelWidth(0),
-                1, 1,
-                s.fillValue,
-                false, true));
-            break;
-
-          case HALF:
-
-            _data->cachedBuffer->insert
-            (k.name(),
-             Slice (HALF,
-                (char *)(new half[tileRowSize] -
-                    _data->offset),
-                sizeof (half),
-                sizeof (half) *
-                    _data->tFile->levelWidth(0),
-                1, 1,
-                s.fillValue,
-                false, true));
-            break;
-
-          case FLOAT:
-
-            _data->cachedBuffer->insert
-            (k.name(),
-             Slice (FLOAT,
-                (char *)(new float[tileRowSize] -
-                    _data->offset),
-                sizeof(float),
-                sizeof(float) *
-                    _data->tFile->levelWidth(0),
-                1, 1,
-                s.fillValue,
-                false, true));
-            break;
-
-          default:
-
-            throw Iex::ArgExc ("Unknown pixel data type.");
-        }
-        }
-
-        _data->tFile->setFrameBuffer (*_data->cachedBuffer);
+           _data->cachedTileY = -1;
+
+           //
+           // Create new a cached frame buffer.  It can hold a single
+           // row of tiles.  The cached buffer can be reused for each
+           // row of tiles because we set the yTileCoords parameter of
+           // each Slice to true.
+           //
+
+           const Box2i &dataWindow = _data->header.dataWindow();
+           _data->cachedBuffer = new FrameBuffer();
+           _data->offset = dataWindow.min.x;
+           
+           int tileRowSize = (dataWindow.max.x - dataWindow.min.x + 1) *
+                             _data->tFile->tileYSize();
+
+           for (FrameBuffer::ConstIterator k = frameBuffer.begin();
+                k != frameBuffer.end();
+                ++k)
+           {
+               Slice s = k.slice();
+
+               switch (s.type)
+               {
+                 case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                   _data->cachedBuffer->insert
+                       (k.name(),
+                        Slice (UINT,
+                               (char *)(new unsigned int[tileRowSize] - 
+                                       _data->offset),
+                               sizeof (unsigned int),
+                               sizeof (unsigned int) *
+                                   _data->tFile->levelWidth(0),
+                               1, 1,
+                               s.fillValue,
+                               false, true));
+                   break;
+
+                 case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                   _data->cachedBuffer->insert
+                       (k.name(),
+                        Slice (HALF,
+                               (char *)(new half[tileRowSize] - 
+                                       _data->offset),
+                               sizeof (half),
+                               sizeof (half) *
+                                   _data->tFile->levelWidth(0),
+                               1, 1,
+                               s.fillValue,
+                               false, true));
+                   break;
+
+                 case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                   _data->cachedBuffer->insert
+                       (k.name(),
+                        Slice (OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT,
+                               (char *)(new float[tileRowSize] - 
+                                       _data->offset),
+                               sizeof(float),
+                               sizeof(float) *
+                                   _data->tFile->levelWidth(0),
+                               1, 1,
+                               s.fillValue,
+                               false, true));
+                   break;
+
+                 default:
+
+                   throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+               }
+           }
+
+           _data->tFile->setFrameBuffer (*_data->cachedBuffer);
         }
 
-    _data->tFileBuffer = frameBuffer;
+       _data->tFileBuffer = frameBuffer;
     }
-    else
+    else if(_data->compositor)
     {
-        _data->sFile->setFrameBuffer (frameBuffer);
+        _data->compositor->setFrameBuffer(frameBuffer);
+    }else {
+        _data->sFile->setFrameBuffer(frameBuffer);
+        _data->tFileBuffer = frameBuffer;
     }
 }
 
@@ -539,14 +759,18 @@ InputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 InputFile::frameBuffer () const
 {
-    if (isTiled (_data->version))
+    if(_data->compositor)
+    {
+        return _data->compositor->frameBuffer();
+    }
+    else if(_data->isTiled)
     {
-    Lock lock (*_data);
-    return _data->tFileBuffer;
+       Lock lock (*_data);
+       return _data->tFileBuffer;
     }
     else
     {
-    return _data->sFile->frameBuffer();
+       return _data->sFile->frameBuffer();
     }
 }
 
@@ -554,19 +778,36 @@ InputFile::frameBuffer () const
 bool
 InputFile::isComplete () const
 {
-    if (isTiled (_data->version))
-    return _data->tFile->isComplete();
+    if (_data->dsFile)
+        return _data->dsFile->isComplete();
+    else if (_data->isTiled)
+       return _data->tFile->isComplete();
     else
-    return _data->sFile->isComplete();
+       return _data->sFile->isComplete();
+}
+
+bool
+InputFile::isOptimizationEnabled() const
+{
+   if(_data->sFile)
+   {
+       return _data->sFile->isOptimizationEnabled();
+   }else{
+       return false;
+   }
 }
 
 
 void
 InputFile::readPixels (int scanLine1, int scanLine2)
 {
-    if (isTiled (_data->version))
+    if (_data->compositor)
+    {
+        _data->compositor->readPixels(scanLine1,scanLine2);
+    }
+    else if (_data->isTiled)
     {
-    Lock lock (*_data);
+       Lock lock (*_data);
         bufferedReadPixels (_data, scanLine1, scanLine2);
     }
     else
@@ -585,49 +826,88 @@ InputFile::readPixels (int scanLine)
 
 void
 InputFile::rawPixelData (int firstScanLine,
-             const char *&pixelData,
-             int &pixelDataSize)
+                        const char *&pixelData,
+                        int &pixelDataSize)
 {
     try
     {
-    if (isTiled (_data->version))
-    {
-        throw Iex::ArgExc ("Tried to read a raw scanline "
-                   "from a tiled image.");
-    }
-
+        if (_data->dsFile)
+        {
+            throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
+            "from a deep image.");
+        }
+        
+       else if (_data->isTiled)
+       {
+           throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
+                              "from a tiled image.");
+       }
+        
         _data->sFile->rawPixelData (firstScanLine, pixelData, pixelDataSize);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error reading pixel data from image "
-                "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error reading pixel data from image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
 
+
+
 void
-InputFile::rawTileData (int &dx, int &dy,
-            int &lx, int &ly,
-            const char *&pixelData,
-            int &pixelDataSize)
+InputFile::rawPixelDataToBuffer (int scanLine,
+                                 char *pixelData,
+                                 int &pixelDataSize) const
 {
     try
     {
-    if (!isTiled (_data->version))
+        if (_data->dsFile)
+        {
+            throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
+                                         "from a deep image.");
+        }
+        
+        else if (_data->isTiled)
+        {
+            throw IEX_NAMESPACE::ArgExc ("Tried to read a raw scanline "
+                                         "from a tiled image.");
+        }
+        
+        _data->sFile->rawPixelDataToBuffer(scanLine, pixelData, pixelDataSize);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-        throw Iex::ArgExc ("Tried to read a raw tile "
-                   "from a scanline-based image.");
+        REPLACE_EXC (e, "Error reading pixel data from image "
+                     "file \"" << fileName() << "\". " << e.what());
+        throw;
     }
+}
+
 
+
+void
+InputFile::rawTileData (int &dx, int &dy,
+                       int &lx, int &ly,
+                       const char *&pixelData,
+                       int &pixelDataSize)
+{
+    try
+    {
+       if (!_data->isTiled)
+       {
+           throw IEX_NAMESPACE::ArgExc ("Tried to read a raw tile "
+                              "from a scanline-based image.");
+       }
+        
         _data->tFile->rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error reading tile data from image "
-                "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error reading tile data from image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -635,14 +915,14 @@ InputFile::rawTileData (int &dx, int &dy,
 TiledInputFile*
 InputFile::tFile()
 {
-    if (!isTiled (_data->version))
+    if (!_data->isTiled)
     {
-    throw Iex::ArgExc ("Cannot get a TiledInputFile pointer "
-               "from an InputFile that is not tiled.");
+       throw IEX_NAMESPACE::ArgExc ("Cannot get a TiledInputFile pointer "
+                          "from an InputFile that is not tiled.");
     }
 
     return _data->tFile;
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 76d5b60..cc524a2 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfTiledOutputFile.h>
-#include <string>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
 #include <fstream>
-#include <ImfThreading.h>
 
-namespace Imf {
 
-class TiledInputFile;
-class ScanLineInputFile;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class InputFile
+class InputFile : public GenericInputFile
 {
   public:
 
@@ -68,6 +70,7 @@ class InputFile
     // used to read the file (see ImfThreading.h).
     //-----------------------------------------------------------
 
+    IMF_EXPORT
     InputFile (const char fileName[], int numThreads = globalThreadCount());
 
 
@@ -80,13 +83,15 @@ class InputFile
     // used to read the file (see ImfThreading.h).
     //-------------------------------------------------------------
 
-    InputFile (IStream &is, int numThreads = globalThreadCount());
+    IMF_EXPORT
+    InputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount());
 
 
     //-----------
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~InputFile ();
 
 
@@ -94,6 +99,7 @@ class InputFile
     // Access to the file name
     //------------------------
 
+    IMF_EXPORT
     const char *       fileName () const;
 
 
@@ -101,6 +107,7 @@ class InputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &     header () const;
 
 
@@ -108,6 +115,7 @@ class InputFile
     // Access to the file format version
     //----------------------------------
 
+    IMF_EXPORT
     int                        version () const;
 
 
@@ -122,6 +130,7 @@ class InputFile
     // to readPixels().
     //-----------------------------------------------------------
 
+    IMF_EXPORT
     void               setFrameBuffer (const FrameBuffer &frameBuffer);
 
 
@@ -129,6 +138,7 @@ class InputFile
     // Access to the current frame buffer
     //-----------------------------------
 
+    IMF_EXPORT
     const FrameBuffer &        frameBuffer () const;
 
 
@@ -141,8 +151,33 @@ class InputFile
     // writing may have been aborted prematurely.)
     //---------------------------------------------------------------
 
+    IMF_EXPORT
     bool               isComplete () const;
 
+    
+    //---------------------------------------------------------------
+    // Check if SSE optimization is enabled
+    //
+    // Call after setFrameBuffer() to query whether optimized file decoding
+    // is available - decode times will be faster if returns true
+    //
+    // Optimization depends on:
+    //   the file type (only scanline data is supported),
+    //   the framebuffer channels (RGB/RGBA mono or stereo)
+    //   the framebuffer channel types (all channels half-float format only)
+    //   the file channels (RGB/RGBA mono or stereo)
+    //   the file channel types (all channel half-float format only)
+    //   whether SSE2 instruction support was detected at compile time
+    //
+    // Calling isOptimizationEnabled before setFrameBuffer will throw an exception
+    //
+    //---------------------------------------------------------------
+    
+    IMF_EXPORT
+    bool                isOptimizationEnabled () const;
+    
+    
+    
 
     //---------------------------------------------------------------
     // Read pixel data:
@@ -163,7 +198,9 @@ class InputFile
     //
     //---------------------------------------------------------------
 
+    IMF_EXPORT
     void               readPixels (int scanLine1, int scanLine2);
+    IMF_EXPORT
     void               readPixels (int scanLine);
 
 
@@ -173,9 +210,34 @@ class InputFile
     // used to implement OutputFile::copyPixels()).
     //----------------------------------------------
 
+    IMF_EXPORT
     void               rawPixelData (int firstScanLine,
-                      const char *&pixelData,
-                      int &pixelDataSize);
+                                     const char *&pixelData,
+                                     int &pixelDataSize);
+
+
+    //----------------------------------------------
+    // Read a scanline's worth of raw pixel data 
+    // from the file, without uncompressing it, and 
+    // store in an external buffer, pixelData. 
+    // pixelData should be pre-allocated with space 
+    // for pixelDataSize chars. 
+    //
+    // This function can be used to separate the 
+    // reading of a raw scan line from the 
+    // decompression of that scan line, for
+    // example to allow multiple scan lines to be
+    // decompressed in parallel by an application's
+    // own threads, where it is not convenient to 
+    // use the threading within the library.
+    //----------------------------------------------
+
+    IMF_EXPORT
+    void               rawPixelDataToBuffer (int scanLine,
+                                             char *pixelData,
+                                             int &pixelDataSize) const;   
+    
 
     //--------------------------------------------------
     // Read a tile of raw pixel data from the file,
@@ -183,27 +245,34 @@ class InputFile
     // used to implement TiledOutputFile::copyPixels()).
     //--------------------------------------------------
 
+    IMF_EXPORT
     void               rawTileData (int &dx, int &dy,
-                     int &lx, int &ly,
-                     const char *&pixelData,
-                     int &pixelDataSize);
+                                    int &lx, int &ly,
+                                    const char *&pixelData,
+                                    int &pixelDataSize);
 
     struct Data;
-
+    
   private:
 
+    InputFile (InputPartData* part);
     InputFile (const InputFile &);                     // not implemented
     InputFile & operator = (const InputFile &);                // not implemented
 
     void               initialize ();
+    void                multiPartInitialize(InputPartData* part);
+    void                compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is);
     TiledInputFile *   tFile ();
-
+    
     friend void TiledOutputFile::copyPixels (InputFile &);
-
+    
     Data *             _data;
+
+
+    friend class MultiPartInputFile;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfInputPart.cpp b/3rdparty/openexr/IlmImf/ImfInputPart.cpp
new file mode 100644 (file)
index 0000000..d548592
--- /dev/null
@@ -0,0 +1,122 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfInputPart.h"
+#include "ImfNamespace.h"
+
+#include "ImfMultiPartInputFile.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+InputPart::InputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<InputFile>(partNumber);
+}
+
+const char *
+InputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+InputPart::header () const
+{
+    return file->header();
+}
+
+int
+InputPart::version () const
+{
+    return file->version();
+}
+
+void
+InputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+InputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+bool
+InputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+bool
+InputPart::isOptimizationEnabled() const
+{
+   return file->isOptimizationEnabled();
+}
+
+void
+InputPart::readPixels (int scanLine1, int scanLine2)
+{
+    file->readPixels(scanLine1, scanLine2);
+}
+
+void
+InputPart::readPixels (int scanLine)
+{
+    file->readPixels(scanLine);
+}
+
+void
+InputPart::rawPixelData (int firstScanLine, const char *&pixelData, int &pixelDataSize)
+{
+    file->rawPixelData(firstScanLine, pixelData, pixelDataSize);
+}
+
+
+void
+InputPart::rawPixelDataToBuffer (int scanLine, char *pixelData, int &pixelDataSize) const
+{
+    file->rawPixelDataToBuffer(scanLine, pixelData, pixelDataSize);
+}
+
+
+void
+InputPart::rawTileData (int &dx, int &dy, int &lx, int &ly,
+             const char *&pixelData, int &pixelDataSize)
+{
+    file->rawTileData(dx, dy, lx, ly, pixelData, pixelDataSize);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfInputPart.h b/3rdparty/openexr/IlmImf/ImfInputPart.h
new file mode 100644 (file)
index 0000000..1afb86e
--- /dev/null
@@ -0,0 +1,104 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFINPUTPART_H_
+#define IMFINPUTPART_H_
+
+#include "ImfInputFile.h"
+#include "ImfOutputPart.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//-------------------------------------------------------------------
+// class InputPart:
+//
+// Same interface as InputFile. Please refer to InputFile.
+//-------------------------------------------------------------------
+
+class InputPart
+{
+    public:
+        IMF_EXPORT
+        InputPart(MultiPartInputFile& multiPartFile, int partNumber);
+
+        IMF_EXPORT
+        const char *        fileName () const;
+        IMF_EXPORT
+        const Header &      header () const;
+        IMF_EXPORT
+        int                 version () const;
+        IMF_EXPORT
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        IMF_EXPORT
+        const FrameBuffer & frameBuffer () const;
+        IMF_EXPORT
+        bool                isComplete () const;
+        IMF_EXPORT
+        bool                isOptimizationEnabled () const;
+        IMF_EXPORT
+        void                readPixels (int scanLine1, int scanLine2);
+        IMF_EXPORT
+        void                readPixels (int scanLine);
+        IMF_EXPORT
+        void                rawPixelData (int firstScanLine,
+                                          const char *&pixelData,
+                                          int &pixelDataSize);
+
+        IMF_EXPORT
+        void                rawPixelDataToBuffer (int scanLine,
+                                                  char *pixelData,
+                                                  int &pixelDataSize) const;
+
+
+        IMF_EXPORT
+        void                rawTileData (int &dx, int &dy,
+                                         int &lx, int &ly,
+                                         const char *&pixelData,
+                                         int &pixelDataSize);
+
+    private:
+        InputFile* file;
+    // for internal use - give OutputFile and TiledOutputFile access to file for copyPixels
+    friend void OutputFile::copyPixels(InputPart&);
+    friend void TiledOutputFile::copyPixels(InputPart&);
+    
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFINPUTPART_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfInputPartData.cpp b/3rdparty/openexr/IlmImf/ImfInputPartData.cpp
new file mode 100644 (file)
index 0000000..d241aed
--- /dev/null
@@ -0,0 +1,51 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfInputPartData.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+InputPartData::InputPartData(InputStreamMutex* mutex, const Header &header,
+                             int partNumber, int numThreads, int version):
+        header(header),
+        numThreads(numThreads),
+        partNumber(partNumber),
+        version(version),       
+        mutex(mutex),
+        completed(false)
+{
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfInputPartData.h b/3rdparty/openexr/IlmImf/ImfInputPartData.h
new file mode 100644 (file)
index 0000000..fb9f86e
--- /dev/null
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFINPUTPARTDATA_H_
+#define IMFINPUTPARTDATA_H_
+
+#include <vector>
+
+#include "ImfInputStreamMutex.h"
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+struct InputPartData
+{
+        Header                  header;
+        int                     numThreads;
+        int                     partNumber;
+        int                     version;
+        InputStreamMutex*       mutex;
+        std::vector<Int64>      chunkOffsets;
+        bool                    completed;
+
+        IMF_EXPORT
+        InputPartData(InputStreamMutex* mutex, const Header &header,
+                      int partNumber, int numThreads, int version);
+
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFINPUTPARTDATA_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfInputStreamMutex.h b/3rdparty/openexr/IlmImf/ImfInputStreamMutex.h
new file mode 100644 (file)
index 0000000..c491dbe
--- /dev/null
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFINPUTSTREAMMUTEX_H_
+#define IMFINPUTSTREAMMUTEX_H_
+
+#include "ImfIO.h"
+#include "IlmThreadMutex.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+using ILMTHREAD_NAMESPACE::Mutex;
+
+//
+// Used to wrap OPENEXR_IMF_INTERNAL_NAMESPACE::IStream as a Mutex.
+//
+struct InputStreamMutex : public Mutex
+{
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream* is;
+    Int64 currentPosition;
+
+    InputStreamMutex()
+    {
+        is = 0;
+        currentPosition = 0;
+    }
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFINPUTSTREAMMUTEX_H_ */
index 065df92..eca020c 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //----------------------------------------------------------------------------
 
 #include "ImathInt64.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+using IMATH_NAMESPACE::Int64;
+using IMATH_NAMESPACE::SInt64;
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-namespace Imf {
 
-using Imath::Int64;
 
-} // namespace Imf
 
-#endif
+#endif // INCLUDED_IMF_INT64_H
index 6537b4a..7486a2e 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,7 +43,7 @@
 #include <ImfIntAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 template <>
@@ -54,4 +54,4 @@ IntAttribute::staticTypeName ()
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 2f29ad6..3d271ca 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
+#include "ImfNamespace.h"
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<int> IntAttribute;
-template <> const char *IntAttribute::staticTypeName ();
-
+template <> IMF_EXPORT const char *IntAttribute::staticTypeName ();
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfIntAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index f2f726f..f90e433 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include <ImfKeyCode.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+   
 KeyCode::KeyCode (int filmMfcCode,
-          int filmType,
-          int prefix,
-          int count,
-          int perfOffset,
-          int perfsPerFrame,
-          int perfsPerCount)
+                 int filmType,
+                 int prefix,
+                 int count,
+                 int perfOffset,
+                 int perfsPerFrame,
+                 int perfsPerCount)
 {
     setFilmMfcCode (filmMfcCode);
     setFilmType (filmType);
@@ -90,95 +91,95 @@ KeyCode::operator = (const KeyCode &other)
 }
 
 
-int
+int            
 KeyCode::filmMfcCode () const
 {
     return _filmMfcCode;
 }
 
 
-void
+void   
 KeyCode::setFilmMfcCode (int filmMfcCode)
 {
     if (filmMfcCode < 0 || filmMfcCode > 99)
-    throw Iex::ArgExc ("Invalid key code film manufacturer code "
-               "(must be between 0 and 99).");
+       throw IEX_NAMESPACE::ArgExc ("Invalid key code film manufacturer code "
+                          "(must be between 0 and 99).");
 
     _filmMfcCode = filmMfcCode;
 }
 
-int
+int            
 KeyCode::filmType () const
 {
     return _filmType;
 }
 
 
-void
+void   
 KeyCode::setFilmType (int filmType)
 {
     if (filmType < 0 || filmType > 99)
-    throw Iex::ArgExc ("Invalid key code film type "
-               "(must be between 0 and 99).");
+       throw IEX_NAMESPACE::ArgExc ("Invalid key code film type "
+                          "(must be between 0 and 99).");
 
     _filmType = filmType;
 }
 
-int
+int            
 KeyCode::prefix () const
 {
     return _prefix;
 }
 
 
-void
+void   
 KeyCode::setPrefix (int prefix)
 {
     if (prefix < 0 || prefix > 999999)
-    throw Iex::ArgExc ("Invalid key code prefix "
-               "(must be between 0 and 999999).");
+       throw IEX_NAMESPACE::ArgExc ("Invalid key code prefix "
+                          "(must be between 0 and 999999).");
 
     _prefix = prefix;
 }
 
 
-int
+int            
 KeyCode::count () const
 {
     return _count;
 }
 
 
-void
+void   
 KeyCode::setCount (int count)
 {
     if (count < 0 || count > 9999)
-    throw Iex::ArgExc ("Invalid key code count "
-               "(must be between 0 and 9999).");
+       throw IEX_NAMESPACE::ArgExc ("Invalid key code count "
+                          "(must be between 0 and 9999).");
 
     _count = count;
 }
 
 
-int
+int            
 KeyCode::perfOffset () const
 {
     return _perfOffset;
 }
 
 
-void
+void   
 KeyCode::setPerfOffset (int perfOffset)
 {
     if (perfOffset < 0 || perfOffset > 119)
-    throw Iex::ArgExc ("Invalid key code perforation offset "
-               "(must be between 0 and 119).");
+       throw IEX_NAMESPACE::ArgExc ("Invalid key code perforation offset "
+                          "(must be between 0 and 119).");
 
     _perfOffset = perfOffset;
 }
 
 
-int
+int    
 KeyCode::perfsPerFrame () const
 {
     return _perfsPerFrame;
@@ -189,14 +190,14 @@ void
 KeyCode::setPerfsPerFrame (int perfsPerFrame)
 {
     if (perfsPerFrame < 1 || perfsPerFrame > 15)
-    throw Iex::ArgExc ("Invalid key code number of perforations per frame "
-               "(must be between 1 and 15).");
+       throw IEX_NAMESPACE::ArgExc ("Invalid key code number of perforations per frame "
+                          "(must be between 1 and 15).");
 
     _perfsPerFrame = perfsPerFrame;
 }
 
 
-int
+int    
 KeyCode::perfsPerCount () const
 {
     return _perfsPerCount;
@@ -207,10 +208,10 @@ void
 KeyCode::setPerfsPerCount (int perfsPerCount)
 {
     if (perfsPerCount < 20 || perfsPerCount > 120)
-    throw Iex::ArgExc ("Invalid key code number of perforations per count "
-               "(must be between 20 and 120).");
+       throw IEX_NAMESPACE::ArgExc ("Invalid key code number of perforations per count "
+                          "(must be between 20 and 120).");
 
     _perfsPerCount = perfsPerCount;
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index c619b1c..37f0ddd 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -39,7 +39,7 @@
 //-----------------------------------------------------------------------------
 //
 //     class KeyCode
-//
+//     
 //     A KeyCode object uniquely identifies a motion picture film frame.
 //     The following fields specifiy film manufacturer, film type, film
 //     roll and the frame's position within the roll:
@@ -61,7 +61,7 @@
 //                             zero-frame reference mark
 //                             range: 0 - 119
 //
-//         perfsPerFrame       number of perforations per frame
+//         perfsPerFrame       number of perforations per frame 
 //                             range: 1 - 15
 //
 //                             typical values:
@@ -70,7 +70,7 @@
 //                                 3, 4, or 8 for 35mm film
 //                                 5, 8 or 15 for 65mm film
 //
-//         perfsPerCount       number of perforations per count
+//         perfsPerCount       number of perforations per count 
 //                             range: 20 - 120
 //
 //                             typical values:
 //                     Latent Image Identification Information
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
+   
 class KeyCode
 {
   public:
@@ -107,15 +109,18 @@ class KeyCode
     // Constructors and assignment operator
     //-------------------------------------
 
+    IMF_EXPORT
     KeyCode (int filmMfcCode = 0,
-         int filmType = 0,
-         int prefix = 0,
-         int count = 0,
-         int perfOffset = 0,
-         int perfsPerFrame = 4,
-         int perfsPerCount = 64);
-
+            int filmType = 0,
+            int prefix = 0,
+            int count = 0,
+            int perfOffset = 0,
+            int perfsPerFrame = 4,
+            int perfsPerCount = 64);
+
+    IMF_EXPORT
     KeyCode (const KeyCode &other);
+    IMF_EXPORT
     KeyCode & operator = (const KeyCode &other);
 
 
@@ -123,25 +128,39 @@ class KeyCode
     // Access to individual fields
     //----------------------------
 
+    IMF_EXPORT
     int                filmMfcCode () const;
+    IMF_EXPORT
     void       setFilmMfcCode (int filmMfcCode);
 
+    IMF_EXPORT
     int                filmType () const;
+    IMF_EXPORT
     void       setFilmType (int filmType);
 
+    IMF_EXPORT
     int                prefix () const;
+    IMF_EXPORT
     void       setPrefix (int prefix);
 
+    IMF_EXPORT
     int                count () const;
+    IMF_EXPORT
     void       setCount (int count);
 
+    IMF_EXPORT
     int                perfOffset () const;
+    IMF_EXPORT
     void       setPerfOffset (int perfOffset);
 
+    IMF_EXPORT
     int                perfsPerFrame () const;
+    IMF_EXPORT
     void       setPerfsPerFrame (int perfsPerFrame);
 
+    IMF_EXPORT
     int                perfsPerCount () const;
+    IMF_EXPORT
     void       setPerfsPerCount (int perfsPerCount);
 
   private:
@@ -156,6 +175,10 @@ class KeyCode
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index 6880274..06c666b 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -41,8 +41,9 @@
 
 #include <ImfKeyCodeAttribute.h>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -54,7 +55,7 @@ KeyCodeAttribute::staticTypeName ()
 
 template <>
 void
-KeyCodeAttribute::writeValueTo (OStream &os, int) const
+KeyCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.filmMfcCode());
     Xdr::write <StreamIO> (os, _value.filmType());
@@ -68,7 +69,7 @@ KeyCodeAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-KeyCodeAttribute::readValueFrom (IStream &is, int, int)
+KeyCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     int tmp;
 
@@ -95,4 +96,4 @@ KeyCodeAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 551d7d3..00d4ece 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfKeyCode.h>
+#include "ImfAttribute.h"
+#include "ImfKeyCode.h"
+#include "ImfExport.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-typedef TypedAttribute<KeyCode> KeyCodeAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::KeyCode> KeyCodeAttribute;
 
 template <>
+IMF_EXPORT
 const char *KeyCodeAttribute::staticTypeName ();
 
 template <>
-void KeyCodeAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void KeyCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                     int) const;
 
 template <>
-void KeyCodeAttribute::readValueFrom (IStream &, int, int);
+IMF_EXPORT
+void KeyCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                      int, int);
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfKeyCodeAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index fd3d223..8f30bed 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,8 +42,9 @@
 //     enum LineOrder
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 enum LineOrder
@@ -53,12 +54,16 @@ enum LineOrder
     DECREASING_Y = 1,  // first scan line has highest y coordinate
 
     RANDOM_Y = 2,       // only for tiled files; tiles are written
-                // in random order
+                       // in random order
 
     NUM_LINEORDERS     // number of different line orders
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index 9ce58c2..aebbac7 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfLineOrderAttribute.h>
+#include "ImfLineOrderAttribute.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -57,7 +58,7 @@ LineOrderAttribute::staticTypeName ()
 
 template <>
 void
-LineOrderAttribute::writeValueTo (OStream &os, int) const
+LineOrderAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     unsigned char tmp = _value;
     Xdr::write <StreamIO> (os, tmp);
@@ -66,7 +67,7 @@ LineOrderAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-LineOrderAttribute::readValueFrom (IStream &is, int, int)
+LineOrderAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned char tmp;
     Xdr::read <StreamIO> (is, tmp);
@@ -74,4 +75,4 @@ LineOrderAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index fd84b15..342c3d0 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfLineOrder.h>
+#include "ImfAttribute.h"
+#include "ImfLineOrder.h"
+#include "ImfExport.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::LineOrder> LineOrderAttribute;
 
-typedef TypedAttribute<LineOrder> LineOrderAttribute;
-template <> const char *LineOrderAttribute::staticTypeName ();
-template <> void LineOrderAttribute::writeValueTo (OStream &, int) const;
-template <> void LineOrderAttribute::readValueFrom (IStream &, int, int);
+template <> 
+IMF_EXPORT 
+const char *LineOrderAttribute::staticTypeName ();
 
+template <> 
+IMF_EXPORT 
+void LineOrderAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                       int) const;
 
-} // namespace Imf
+template <> 
+IMF_EXPORT 
+void LineOrderAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                        int, int);
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfLineOrderAttribute.cpp>
-#endif
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 4c4ce8c..3209abc 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -45,8 +45,9 @@
 #include <ImfLut.h>
 #include <math.h>
 #include <assert.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 void
@@ -54,15 +55,15 @@ HalfLut::apply (half *data, int nData, int stride) const
 {
     while (nData)
     {
-    *data = _lut (*data);
-    data += stride;
-    nData -= 1;
+       *data = _lut (*data);
+       data += stride;
+       nData -= 1;
     }
 }
 
 
 void
-HalfLut::apply (const Slice &data, const Imath::Box2i &dataWindow) const
+HalfLut::apply (const Slice &data, const IMATH_NAMESPACE::Box2i &dataWindow) const
 {
     assert (data.type == HALF);
     assert (dataWindow.min.x % data.xSampling == 0);
@@ -71,24 +72,24 @@ HalfLut::apply (const Slice &data, const Imath::Box2i &dataWindow) const
     assert ((dataWindow.max.y - dataWindow.min.y + 1) % data.ySampling == 0);
 
     char *base = data.base + data.yStride *
-         (dataWindow.min.y / data.ySampling);
+                (dataWindow.min.y / data.ySampling);
 
     for (int y = dataWindow.min.y;
-     y <= dataWindow.max.y;
-     y += data.ySampling)
-    {
-    char *pixel = base + data.xStride *
-              (dataWindow.min.x / data.xSampling);
-
-    for (int x = dataWindow.min.x;
-         x <= dataWindow.max.x;
-         x += data.xSampling)
+        y <= dataWindow.max.y;
+        y += data.ySampling)
     {
-        *(half *)pixel = _lut (*(half *)pixel);
-        pixel += data.xStride;
-    }
-
-    base += data.yStride;
+       char *pixel = base + data.xStride *
+                     (dataWindow.min.x / data.xSampling);
+
+       for (int x = dataWindow.min.x;
+            x <= dataWindow.max.x;
+            x += data.xSampling)
+       {
+           *(half *)pixel = _lut (*(half *)pixel);
+           pixel += data.xStride;
+       }
+
+       base += data.yStride;
     }
 }
 
@@ -98,53 +99,53 @@ RgbaLut::apply (Rgba *data, int nData, int stride) const
 {
     while (nData)
     {
-    if (_chn & WRITE_R)
-        data->r = _lut (data->r);
+       if (_chn & WRITE_R)
+           data->r = _lut (data->r);
 
-    if (_chn & WRITE_G)
-        data->g = _lut (data->g);
+       if (_chn & WRITE_G)
+           data->g = _lut (data->g);
 
-    if (_chn & WRITE_B)
-        data->b = _lut (data->b);
+       if (_chn & WRITE_B)
+           data->b = _lut (data->b);
 
-    if (_chn & WRITE_A)
-        data->a = _lut (data->a);
+       if (_chn & WRITE_A)
+           data->a = _lut (data->a);
 
-    data += stride;
-    nData -= 1;
+       data += stride;
+       nData -= 1;
     }
 }
 
 
 void
 RgbaLut::apply (Rgba *base,
-        int xStride, int yStride,
-        const Imath::Box2i &dataWindow) const
+               int xStride, int yStride,
+               const IMATH_NAMESPACE::Box2i &dataWindow) const
 {
     base += dataWindow.min.y * yStride;
 
     for (int y = dataWindow.min.y; y <= dataWindow.max.y; ++y)
     {
-    Rgba *pixel = base + dataWindow.min.x * xStride;
+       Rgba *pixel = base + dataWindow.min.x * xStride;
 
-    for (int x = dataWindow.min.x; x <= dataWindow.max.x; ++x)
-    {
-        if (_chn & WRITE_R)
-        pixel->r = _lut (pixel->r);
+       for (int x = dataWindow.min.x; x <= dataWindow.max.x; ++x)
+       {
+           if (_chn & WRITE_R)
+               pixel->r = _lut (pixel->r);
 
-        if (_chn & WRITE_G)
-        pixel->g = _lut (pixel->g);
+           if (_chn & WRITE_G)
+               pixel->g = _lut (pixel->g);
 
-        if (_chn & WRITE_B)
-        pixel->b = _lut (pixel->b);
+           if (_chn & WRITE_B)
+               pixel->b = _lut (pixel->b);
 
-        if (_chn & WRITE_A)
-        pixel->a = _lut (pixel->a);
+           if (_chn & WRITE_A)
+               pixel->a = _lut (pixel->a);
 
-        pixel += xStride;
-    }
+           pixel += xStride;
+       }
 
-    base += yStride;
+       base += yStride;
     }
 }
 
@@ -157,20 +158,21 @@ round12log (half x)
 
     if (x <= 0)
     {
-    return 0;
+       return 0;
     }
     else
     {
-    int12log = int (2000.5 + 200.0 * log (x / middleval) / log (2.0));
+       int12log = int (2000.5 + 200.0 * log (x / middleval) / log (2.0));
 
-    if (int12log > 4095)
-        int12log = 4095;
+       if (int12log > 4095)
+           int12log = 4095;
 
-    if (int12log < 1)
-        int12log = 1;
+       if (int12log < 1)
+           int12log = 1;
     }
 
     return middleval * pow (2.0, (int12log - 2000.0) / 200.0);
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
index 6ad7384..c59beab 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRgbaFile.h>
-#include <ImfFrameBuffer.h>
+#include "ImfRgbaFile.h"
+#include "ImfFrameBuffer.h"
 #include "ImathBox.h"
 #include "halfFunction.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // Lookup table for individual half channels.
@@ -72,17 +74,19 @@ class HalfLut
     // Apply the table to data[0], data[stride] ... data[(nData-1) * stride]
     //----------------------------------------------------------------------
 
+    IMF_EXPORT
     void apply (half *data,
-        int nData,
-        int stride = 1) const;
+               int nData,
+               int stride = 1) const;
 
 
     //---------------------------------------------------------------
     // Apply the table to a frame buffer slice (see ImfFrameBuffer.h)
     //---------------------------------------------------------------
 
+    IMF_EXPORT
     void apply (const Slice &data,
-        const Imath::Box2i &dataWindow) const;
+               const IMATH_NAMESPACE::Box2i &dataWindow) const;
 
   private:
 
@@ -110,19 +114,21 @@ class RgbaLut
     // Apply the table to data[0], data[stride] ... data[(nData-1) * stride]
     //----------------------------------------------------------------------
 
+    IMF_EXPORT
     void apply (Rgba *data,
-        int nData,
-        int stride = 1) const;
+               int nData,
+               int stride = 1) const;
 
 
     //-----------------------------------------------------------------------
     // Apply the table to a frame buffer (see RgbaOutpuFile.setFrameBuffer())
     //-----------------------------------------------------------------------
 
+    IMF_EXPORT
     void apply (Rgba *base,
-        int xStride,
-        int yStride,
-        const Imath::Box2i &dataWindow) const;
+               int xStride,
+               int yStride,
+               const IMATH_NAMESPACE::Box2i &dataWindow) const;
 
   private:
 
@@ -139,6 +145,7 @@ class RgbaLut
 // the center [2000] and that number is near 0.18.
 //
 
+IMF_EXPORT 
 half round12log (half x);
 
 
@@ -164,7 +171,7 @@ struct roundNBit
 template <class Function>
 HalfLut::HalfLut (Function f):
     _lut(f, -HALF_MAX, HALF_MAX, half (0),
-     half::posInf(), half::negInf(), half::qNan())
+        half::posInf(), half::negInf(), half::qNan())
 {
     // empty
 }
@@ -173,13 +180,13 @@ HalfLut::HalfLut (Function f):
 template <class Function>
 RgbaLut::RgbaLut (Function f, RgbaChannels chn):
     _lut(f, -HALF_MAX, HALF_MAX, half (0),
-     half::posInf(), half::negInf(), half::qNan()),
+        half::posInf(), half::negInf(), half::qNan()),
     _chn(chn)
 {
     // empty
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 0010e20..84efe7e 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfMatrixAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 
 template <>
@@ -59,7 +62,7 @@ M33fAttribute::staticTypeName ()
 
 template <>
 void
-M33fAttribute::writeValueTo (OStream &os, int) const
+M33fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -77,7 +80,7 @@ M33fAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-M33fAttribute::readValueFrom (IStream &is, int, int)
+M33fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -103,7 +106,7 @@ M33dAttribute::staticTypeName ()
 
 template <>
 void
-M33dAttribute::writeValueTo (OStream &os, int) const
+M33dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -121,7 +124,7 @@ M33dAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-M33dAttribute::readValueFrom (IStream &is, int, int)
+M33dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -147,7 +150,7 @@ M44fAttribute::staticTypeName ()
 
 template <>
 void
-M44fAttribute::writeValueTo (OStream &os, int) const
+M44fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -173,7 +176,7 @@ M44fAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-M44fAttribute::readValueFrom (IStream &is, int, int)
+M44fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -207,7 +210,7 @@ M44dAttribute::staticTypeName ()
 
 template <>
 void
-M44dAttribute::writeValueTo (OStream &os, int) const
+M44dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value[0][0]);
     Xdr::write <StreamIO> (os, _value[0][1]);
@@ -233,7 +236,7 @@ M44dAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-M44dAttribute::readValueFrom (IStream &is, int, int)
+M44dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value[0][0]);
     Xdr::read <StreamIO> (is, _value[0][1]);
@@ -257,4 +260,4 @@ M44dAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 7337254..31f1466 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 #include "ImathMatrix.h"
+#include "ImfExport.h"
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-typedef TypedAttribute<Imath::M33f> M33fAttribute;
-template <> const char *M33fAttribute::staticTypeName ();
-template <> void M33fAttribute::writeValueTo (OStream &, int) const;
-template <> void M33fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M33f> M33fAttribute;
+template <> IMF_EXPORT const char *M33fAttribute::staticTypeName ();
+template <> IMF_EXPORT void M33fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M33fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::M33d> M33dAttribute;
-template <> const char *M33dAttribute::staticTypeName ();
-template <> void M33dAttribute::writeValueTo (OStream &, int) const;
-template <> void M33dAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M33d> M33dAttribute;
+template <> IMF_EXPORT const char *M33dAttribute::staticTypeName ();
+template <> IMF_EXPORT void M33dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M33dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::M44f> M44fAttribute;
-template <> const char *M44fAttribute::staticTypeName ();
-template <> void M44fAttribute::writeValueTo (OStream &, int) const;
-template <> void M44fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M44f> M44fAttribute;
+template <> IMF_EXPORT const char *M44fAttribute::staticTypeName ();
+template <> IMF_EXPORT void M44fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M44fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::M44d> M44dAttribute;
-template <> const char *M44dAttribute::staticTypeName ();
-template <> void M44dAttribute::writeValueTo (OStream &, int) const;
-template <> void M44dAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::M44d> M44dAttribute;
+template <> IMF_EXPORT const char *M44dAttribute::staticTypeName ();
+template <> IMF_EXPORT void M44dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void M44dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfMatrixAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 27f4caf..4622c41 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,6 +42,7 @@
 
 #include <ImfMisc.h>
 #include <ImfHeader.h>
+#include <ImfAttribute.h>
 #include <ImfCompressor.h>
 #include <ImfChannelList.h>
 #include <ImfXdr.h>
 #include <Iex.h>
 #include <ImfStdIO.h>
 #include <ImfConvert.h>
+#include <ImfPartType.h>
+#include <ImfTileDescription.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
 using std::vector;
 
 int
@@ -64,24 +68,24 @@ pixelTypeSize (PixelType type)
 
     switch (type)
     {
-      case UINT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+       
+       size = Xdr::size <unsigned int> ();
+       break;
 
-    size = Xdr::size <unsigned int> ();
-    break;
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-      case HALF:
+       size = Xdr::size <half> ();
+       break;
 
-    size = Xdr::size <half> ();
-    break;
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-      case FLOAT:
-
-    size = Xdr::size <float> ();
-    break;
+       size = Xdr::size <float> ();
+       break;
 
       default:
 
-    throw Iex::ArgExc ("Unknown pixel type.");
+       throw IEX_NAMESPACE::ArgExc ("Unknown pixel type.");
     }
 
     return size;
@@ -99,7 +103,7 @@ numSamples (int s, int a, int b)
 
 size_t
 bytesPerLineTable (const Header &header,
-           vector<size_t> &bytesPerLine)
+                  vector<size_t> &bytesPerLine)
 {
     const Box2i &dataWindow = header.dataWindow();
     const ChannelList &channels = header.channels();
@@ -107,48 +111,143 @@ bytesPerLineTable (const Header &header,
     bytesPerLine.resize (dataWindow.max.y - dataWindow.min.y + 1);
 
     for (ChannelList::ConstIterator c = channels.begin();
-     c != channels.end();
-     ++c)
+        c != channels.end();
+        ++c)
     {
-    int nBytes = pixelTypeSize (c.channel().type) *
-             (dataWindow.max.x - dataWindow.min.x + 1) /
-             c.channel().xSampling;
+       int nBytes = pixelTypeSize (c.channel().type) *
+                    (dataWindow.max.x - dataWindow.min.x + 1) /
+                    c.channel().xSampling;
 
-    for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
-        if (modp (y, c.channel().ySampling) == 0)
-        bytesPerLine[i] += nBytes;
+       for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
+           if (modp (y, c.channel().ySampling) == 0)
+               bytesPerLine[i] += nBytes;
     }
 
     size_t maxBytesPerLine = 0;
 
     for (int y = dataWindow.min.y, i = 0; y <= dataWindow.max.y; ++y, ++i)
-    if (maxBytesPerLine < bytesPerLine[i])
-        maxBytesPerLine = bytesPerLine[i];
+       if (maxBytesPerLine < bytesPerLine[i])
+           maxBytesPerLine = bytesPerLine[i];
 
     return maxBytesPerLine;
 }
 
+static int
+roundToNextMultiple(int n, int d)
+{
+    return ((n + d - 1) / d) * d;
+}
+
+static int
+roundToPrevMultiple(int n, int d)
+{
+    return (n / d) * d;
+}
+
+size_t
+bytesPerDeepLineTable (const Header &header,
+                       int minY, int maxY,
+                       const char* base,
+                       int xStride,
+                       int yStride,
+                       vector<size_t> &bytesPerLine)
+{
+    const Box2i &dataWindow = header.dataWindow();
+    const ChannelList &channels = header.channels();
+
+    for (ChannelList::ConstIterator c = channels.begin();
+         c != channels.end();
+         ++c)
+    {
+        const int ySampling = abs(c.channel().ySampling);
+        const int xSampling = abs(c.channel().xSampling);
+        const int pixelSize = pixelTypeSize (c.channel().type);
+
+        // Here we transform from the domain over all pixels into the domain
+        // of actual samples.  We want to sample points in [minY, maxY] where
+        // (y % ySampling) == 0.  However, doing this by rejecting samples
+        // requires O(height*width) modulo computations, which were a
+        // significant bottleneck in the previous implementation of this
+        // function.  For the low, low price of 4 divisions per channel, we
+        // can tighten the y & x ranges to the least and greatest roots of the
+        // sampling function and then stride by the sampling rate.
+        const int sampleMinY = roundToNextMultiple(minY, ySampling);
+        const int sampleMaxY = roundToPrevMultiple(maxY, ySampling);
+        const int sampleMinX = roundToNextMultiple(dataWindow.min.x, xSampling);
+        const int sampleMaxX = roundToPrevMultiple(dataWindow.max.x, xSampling);
+
+        for (int y = sampleMinY; y <= sampleMaxY; y+=ySampling)
+        {
+            int nBytes = 0;
+            for (int x = sampleMinX; x <= sampleMaxX; x += xSampling)
+            {
+                nBytes += pixelSize *
+                          sampleCount(base, xStride, yStride, x, y);
+            }
+            bytesPerLine[y - dataWindow.min.y] += nBytes;
+        }
+    }
+
+    size_t maxBytesPerLine = 0;
+
+    for (int y = minY; y <= maxY; ++y)
+        if (maxBytesPerLine < bytesPerLine[y - dataWindow.min.y])
+            maxBytesPerLine = bytesPerLine[y - dataWindow.min.y];
+
+    return maxBytesPerLine;
+}
+
+
+size_t
+bytesPerDeepLineTable (const Header &header,
+                       char* base,
+                       int xStride,
+                       int yStride,
+                       vector<size_t> &bytesPerLine)
+{
+    return bytesPerDeepLineTable(header,
+                                 header.dataWindow().min.y,
+                                 header.dataWindow().max.y,
+                                 base,
+                                 xStride,
+                                 yStride,
+                                 bytesPerLine);
+}
+
 
 void
 offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
-             int linesInLineBuffer,
-             vector<size_t> &offsetInLineBuffer)
+                         int scanline1, int scanline2,
+                         int linesInLineBuffer,
+                         vector<size_t> &offsetInLineBuffer)
 {
     offsetInLineBuffer.resize (bytesPerLine.size());
 
     size_t offset = 0;
 
-    for (int i = 0; i < bytesPerLine.size(); ++i)
+    for (int i = scanline1; i <= scanline2; ++i)
     {
-    if (i % linesInLineBuffer == 0)
-        offset = 0;
+        if (i % linesInLineBuffer == 0)
+            offset = 0;
 
-    offsetInLineBuffer[i] = offset;
-    offset += bytesPerLine[i];
+        offsetInLineBuffer[i] = offset;
+        offset += bytesPerLine[i];
     }
 }
 
 
+void
+offsetInLineBufferTable (const vector<size_t> &bytesPerLine,
+                        int linesInLineBuffer,
+                        vector<size_t> &offsetInLineBuffer)
+{
+    offsetInLineBufferTable (bytesPerLine,
+                             0, bytesPerLine.size() - 1,
+                             linesInLineBuffer,
+                             offsetInLineBuffer);
+}
+
+
 int
 lineBufferMinY (int y, int minY, int linesInLineBuffer)
 {
@@ -179,11 +278,11 @@ numLinesInBuffer (Compressor * compressor)
 
 void
 copyIntoFrameBuffer (const char *& readPtr,
-             char * writePtr,
-             char * endPtr,
+                    char * writePtr,
+                    char * endPtr,
                      size_t xStride,
-             bool fill,
-             double fillValue,
+                    bool fill,
+                    double fillValue,
                      Compressor::Format format,
                      PixelType typeInFrameBuffer,
                      PixelType typeInFile)
@@ -202,8 +301,8 @@ copyIntoFrameBuffer (const char *& readPtr,
 
         switch (typeInFrameBuffer)
         {
-      case UINT:
-
+         case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+            
             {
                 unsigned int fillVal = (unsigned int) (fillValue);
 
@@ -215,7 +314,7 @@ copyIntoFrameBuffer (const char *& readPtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             {
                 half fillVal = half (fillValue);
@@ -228,7 +327,7 @@ copyIntoFrameBuffer (const char *& readPtr,
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             {
                 float fillVal = float (fillValue);
@@ -243,7 +342,7 @@ copyIntoFrameBuffer (const char *& readPtr,
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else if (format == Compressor::XDR)
@@ -258,11 +357,11 @@ copyIntoFrameBuffer (const char *& readPtr,
 
         switch (typeInFrameBuffer)
         {
-          case UINT:
-
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+    
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -271,7 +370,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -282,7 +381,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -292,14 +391,17 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+                
+              default:                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -309,8 +411,8 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
-
-              case HALF:
+                
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -319,7 +421,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -329,14 +431,17 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -347,7 +452,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -358,7 +463,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -366,12 +471,15 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else
@@ -383,11 +491,11 @@ copyIntoFrameBuffer (const char *& readPtr,
 
         switch (typeInFrameBuffer)
         {
-          case UINT:
-
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+    
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -399,7 +507,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -410,7 +518,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -424,14 +532,18 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+                
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -446,17 +558,25 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
-
-                while (writePtr <= endPtr)
-                {
-                    *(half *) writePtr = *(half *)readPtr;
-                    readPtr += sizeof (half);
-                    writePtr += xStride;
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                // If we're tightly packed, just memcpy
+                if (xStride == sizeof(half)) {
+                    int numBytes = endPtr-writePtr+sizeof(half);
+                    memcpy(writePtr, readPtr, numBytes);
+                    readPtr  += numBytes;
+                    writePtr += numBytes;                    
+                } else {
+                    while (writePtr <= endPtr)
+                    {
+                        *(half *) writePtr = *(half *)readPtr;
+                        readPtr += sizeof (half);
+                        writePtr += xStride;
+                    }
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -470,14 +590,17 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             switch (typeInFile)
             {
-              case UINT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
                 while (writePtr <= endPtr)
                 {
@@ -492,7 +615,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case HALF:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
                 while (writePtr <= endPtr)
                 {
@@ -503,7 +626,7 @@ copyIntoFrameBuffer (const char *& readPtr,
                 }
                 break;
 
-              case FLOAT:
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
                 while (writePtr <= endPtr)
                 {
@@ -514,12 +637,716 @@ copyIntoFrameBuffer (const char *& readPtr,
                     writePtr += xStride;
                 }
                 break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+}
+
+void
+copyIntoDeepFrameBuffer (const char *& readPtr,
+                         char * base,
+                         const char* sampleCountBase,
+                         ptrdiff_t sampleCountXStride,
+                         ptrdiff_t sampleCountYStride,
+                         int y, int minX, int maxX,
+                         int xOffsetForSampleCount,
+                         int yOffsetForSampleCount,
+                         int xOffsetForData,
+                         int yOffsetForData,
+                         ptrdiff_t sampleStride,
+                         ptrdiff_t xPointerStride,
+                         ptrdiff_t yPointerStride,
+                         bool fill,
+                         double fillValue,
+                         Compressor::Format format,
+                         PixelType typeInFrameBuffer,
+                         PixelType typeInFile)
+{
+    //
+    // Copy a horizontal row of pixels from an input
+    // file's line or tile buffer to a frame buffer.
+    //
+
+    if (fill)
+    {
+        //
+        // The file contains no data for this channel.
+        // Store a default value in the frame buffer.
+        //
+
+        switch (typeInFrameBuffer)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            {
+                unsigned int fillVal = (unsigned int) (fillValue);
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    if(writePtr)
+                    {
+                        int count = sampleCount(sampleCountBase,
+                                                sampleCountXStride,
+                                                sampleCountYStride,
+                                                x - xOffsetForSampleCount,
+                                                y - yOffsetForSampleCount);
+                        for (int i = 0; i < count; i++)
+                        {
+                            *(unsigned int *) writePtr = fillVal;
+                            writePtr += sampleStride;
+                        }
+                    }
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            {
+                half fillVal = half (fillValue);
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    if(writePtr)
+                    {                            
+                        int count = sampleCount(sampleCountBase,
+                                                sampleCountXStride,
+                                                sampleCountYStride,
+                                                x - xOffsetForSampleCount,
+                                                y - yOffsetForSampleCount);
+                        for (int i = 0; i < count; i++)
+                        {
+                            *(half *) writePtr = fillVal;
+                           writePtr += sampleStride;
+                       }
+                    }
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            {
+                float fillVal = float (fillValue);
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    if(writePtr)
+                    {
+                        int count = sampleCount(sampleCountBase,
+                                                sampleCountXStride,
+                                                sampleCountYStride,
+                                                x - xOffsetForSampleCount,
+                                                y - yOffsetForSampleCount);
+                        for (int i = 0; i < count; i++)
+                        {
+                            *(float *) writePtr = fillVal;
+                            writePtr += sampleStride;
+                        }
+                    }
+                }
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+    else if (format == Compressor::XDR)
+    {
+        //
+        // The the line or tile buffer is in XDR format.
+        //
+        // Convert the pixels from the file's machine-
+        // independent representation, and store the
+        // results in the frame buffer.
+        //
+
+        switch (typeInFrameBuffer)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                   
+                        for (int i = 0; i < count; i++)
+                        {
+                            Xdr::read <CharPtrIO> (readPtr, *(unsigned int *) writePtr);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+
+                        for (int i = 0; i < count; i++)
+                        {
+                            half h;
+                            Xdr::read <CharPtrIO> (readPtr, h);
+                           *(unsigned int *) writePtr = halfToUint (h);
+                           writePtr += sampleStride;
+                       }
+                    }else{
+                       Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                                                                        
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            float f;
+                            Xdr::read <CharPtrIO> (readPtr, f);
+                            *(unsigned int *)writePtr = floatToUint (f);
+                            writePtr += sampleStride;
+                        } 
+                     }else{
+                       Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
+                     }
+                
+                }
+                break;
+              default:
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+
+                        for (int i = 0; i < count; i++)
+                        {
+                            unsigned int ui;
+                            Xdr::read <CharPtrIO> (readPtr, ui);
+                            *(half *) writePtr = uintToHalf (ui);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                    
+                        for (int i = 0; i < count; i++)
+                        {
+                            Xdr::read <CharPtrIO> (readPtr, *(half *) writePtr);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **) (base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            float f;
+                            Xdr::read <CharPtrIO> (readPtr, f);
+                            *(half *) writePtr = floatToHalf (f);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            unsigned int ui;
+                            Xdr::read <CharPtrIO> (readPtr, ui);
+                            *(float *) writePtr = float (ui);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<unsigned int>());
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+
+                        for (int i = 0; i < count; i++)
+                        {
+                            half h;
+                            Xdr::read <CharPtrIO> (readPtr, h);
+                            *(float *) writePtr = float (h);
+                            writePtr += sampleStride;
+                        }
+                    
+                   }else{
+                      Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<half>());
+                   }               
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                    if(writePtr)
+                    {
+                    
+                        for (int i = 0; i < count; i++)
+                        {
+                            Xdr::read <CharPtrIO> (readPtr, *(float *) writePtr);
+                            writePtr += sampleStride;
+                        }
+                    } else{
+                        Xdr::skip <CharPtrIO> (readPtr,count*Xdr::size<float>());
+                    }      
+                    
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+    else
+    {
+        //
+        // The the line or tile buffer is in NATIVE format.
+        // Copy the results into the frame buffer.
+        //
+
+        switch (typeInFrameBuffer)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             for (size_t i = 0; i < sizeof (unsigned int); ++i)
+                                 writePtr[i] = readPtr[i];
+
+                             readPtr += sizeof (unsigned int);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(unsigned int)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                        for (int i = 0; i < count; i++)
+                        {
+                            half h = *(half *) readPtr;
+                            *(unsigned int *) writePtr = halfToUint (h);
+                            readPtr += sizeof (half);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        readPtr+=sizeof(half)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                    
+                        for (int i = 0; i < count; i++)
+                        {
+                            float f;
+
+                            for (size_t i = 0; i < sizeof (float); ++i)
+                                ((char *)&f)[i] = readPtr[i];
+
+                            *(unsigned int *)writePtr = floatToUint (f);
+                            readPtr += sizeof (float);
+                            writePtr += sampleStride;
+                        }
+                    }else{
+                        readPtr+=sizeof(float)*count;
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             unsigned int ui;
+                             for (size_t i = 0; i < sizeof (unsigned int); ++i)
+                                 ((char *)&ui)[i] = readPtr[i];
+  
+                             *(half *) writePtr = uintToHalf (ui);
+                             readPtr += sizeof (unsigned int);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(unsigned int)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             *(half *) writePtr = *(half *)readPtr;
+                             readPtr += sizeof (half);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(half)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                            float f;
+
+                             for (size_t i = 0; i < sizeof (float); ++i)
+                                 ((char *)&f)[i] = readPtr[i];
+
+                            *(half *) writePtr = floatToHalf (f);
+                            readPtr += sizeof (float);
+                            writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(float)*count;
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            switch (typeInFile)
+            {
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                              unsigned int ui;
+                              for (size_t i = 0; i < sizeof (unsigned int); ++i)
+                                  ((char *)&ui)[i] = readPtr[i];
+
+                              *(float *) writePtr = float (ui);
+                              readPtr += sizeof (unsigned int);
+                              writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(unsigned int)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                             half h = *(half *) readPtr;
+                             *(float *) writePtr = float (h);
+                             readPtr += sizeof (half);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(half)*count;
+                    }
+                }
+                break;
+
+              case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+                for (int x = minX; x <= maxX; x++)
+                {
+                    char* writePtr = *(char **)(base+(y-yOffsetForData)*yPointerStride + (x-xOffsetForData)*xPointerStride);
+                    
+                    int count = sampleCount(sampleCountBase,
+                                            sampleCountXStride,
+                                            sampleCountYStride,
+                                            x - xOffsetForSampleCount,
+                                            y - yOffsetForSampleCount);
+                                            
+                    if(writePtr)
+                    {
+                         for (int i = 0; i < count; i++)
+                         {
+                              for (size_t i = 0; i < sizeof (float); ++i)
+                                  writePtr[i] = readPtr[i];
+
+                             readPtr += sizeof (float);
+                             writePtr += sampleStride;
+                         }
+                    }else{
+                        readPtr+=sizeof(float)*count;
+                    }
+                }
+                break;
+              default:
+                  
+                  throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
             }
             break;
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
 }
@@ -528,28 +1355,28 @@ copyIntoFrameBuffer (const char *& readPtr,
 void
 skipChannel (const char *& readPtr,
              PixelType typeInFile,
-         size_t xSize)
+            size_t xSize)
 {
     switch (typeInFile)
     {
-      case UINT:
-
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+        
         Xdr::skip <CharPtrIO> (readPtr, Xdr::size <unsigned int> () * xSize);
         break;
 
-      case HALF:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
         Xdr::skip <CharPtrIO> (readPtr, Xdr::size <half> () * xSize);
         break;
 
-      case FLOAT:
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
         Xdr::skip <CharPtrIO> (readPtr, Xdr::size <float> () * xSize);
         break;
 
       default:
 
-        throw Iex::ArgExc ("Unknown pixel data type.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
     }
 }
 
@@ -557,52 +1384,52 @@ skipChannel (const char *& readPtr,
 void
 convertInPlace (char *& writePtr,
                 const char *& readPtr,
-        PixelType type,
+               PixelType type,
                 size_t numPixels)
 {
     switch (type)
     {
-      case UINT:
-
-        for (int j = 0; j < numPixels; ++j)
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+    
+        for (size_t j = 0; j < numPixels; ++j)
         {
             Xdr::write <CharPtrIO> (writePtr, *(const unsigned int *) readPtr);
             readPtr += sizeof(unsigned int);
         }
         break;
-
-      case HALF:
-
-        for (int j = 0; j < numPixels; ++j)
-        {
+    
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+    
+        for (size_t j = 0; j < numPixels; ++j)
+        {               
             Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
             readPtr += sizeof(half);
         }
         break;
-
-      case FLOAT:
-
-        for (int j = 0; j < numPixels; ++j)
+    
+      case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+    
+        for (size_t j = 0; j < numPixels; ++j)
         {
             Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
             readPtr += sizeof(float);
         }
         break;
-
+    
       default:
-
-        throw Iex::ArgExc ("Unknown pixel data type.");
+    
+        throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
     }
 }
 
 
 void
 copyFromFrameBuffer (char *& writePtr,
-             const char *& readPtr,
+                    const char *& readPtr,
                      const char * endPtr,
-             size_t xStride,
+                    size_t xStride,
                      Compressor::Format format,
-             PixelType type)
+                    PixelType type)
 {
     //
     // Copy a horizontal row of pixels from a frame
@@ -617,7 +1444,7 @@ copyFromFrameBuffer (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
             while (readPtr <= endPtr)
             {
@@ -627,7 +1454,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             while (readPtr <= endPtr)
             {
@@ -636,7 +1463,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             while (readPtr <= endPtr)
             {
@@ -647,7 +1474,7 @@ copyFromFrameBuffer (char *& writePtr,
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else
@@ -658,7 +1485,7 @@ copyFromFrameBuffer (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
             while (readPtr <= endPtr)
             {
@@ -669,7 +1496,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
             while (readPtr <= endPtr)
             {
@@ -679,7 +1506,7 @@ copyFromFrameBuffer (char *& writePtr,
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
             while (readPtr <= endPtr)
             {
@@ -689,10 +1516,189 @@ copyFromFrameBuffer (char *& writePtr,
                 readPtr += xStride;
             }
             break;
+            
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+}
+
+void
+copyFromDeepFrameBuffer (char *& writePtr,
+                         const char * base,
+                         char* sampleCountBase,
+                         ptrdiff_t sampleCountXStride,
+                         ptrdiff_t sampleCountYStride,
+                         int y, int xMin, int xMax,
+                         int xOffsetForSampleCount,
+                         int yOffsetForSampleCount,
+                         int xOffsetForData,
+                         int yOffsetForData,
+                         ptrdiff_t sampleStride,
+                         ptrdiff_t dataXStride,
+                         ptrdiff_t dataYStride,
+                         Compressor::Format format,
+                         PixelType type)
+{
+    //
+    // Copy a horizontal row of pixels from a frame
+    // buffer to an output file's line or tile buffer.
+    //
+
+    if (format == Compressor::XDR)
+    {
+        //
+        // The the line or tile buffer is in XDR format.
+        //
+
+        switch (type)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    Xdr::write <CharPtrIO> (writePtr,
+                                            *(const unsigned int *) readPtr);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    Xdr::write <CharPtrIO> (writePtr, *(const half *) readPtr);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                   
+                                   
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    Xdr::write <CharPtrIO> (writePtr, *(const float *) readPtr);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
 
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
+        }
+    }
+    else
+    {
+        //
+        // The the line or tile buffer is in NATIVE format.
+        //
+
+        switch (type)
+        {
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                                   
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                                                      
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    for (size_t j = 0; j < sizeof (unsigned int); ++j)
+                        *writePtr++ = readPtr[j];
+
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                   
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    *(half *) writePtr = *(const half *) readPtr;
+                    writePtr += sizeof (half);
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
+
+            for (int x = xMin; x <= xMax; x++)
+            {
+                unsigned int count =
+                        sampleCount(sampleCountBase,
+                                   sampleCountXStride,
+                                   sampleCountYStride,
+                                   x - xOffsetForSampleCount,
+                                   y - yOffsetForSampleCount);
+                                   
+                const char* ptr = base + (y-yOffsetForData) * dataYStride + (x-xOffsetForData) * dataXStride;                                   
+                const char* readPtr = ((const char**) ptr)[0];
+                for (unsigned int i = 0; i < count; i++)
+                {
+                    for (size_t j = 0; j < sizeof (float); ++j)
+                        *writePtr++ = readPtr[j];
+
+                    readPtr += sampleStride;
+                }
+            }
+            break;
+
+          default:
+
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
 }
@@ -700,9 +1706,9 @@ copyFromFrameBuffer (char *& writePtr,
 
 void
 fillChannelWithZeroes (char *& writePtr,
-               Compressor::Format format,
-               PixelType type,
-               size_t xSize)
+                      Compressor::Format format,
+                      PixelType type,
+                      size_t xSize)
 {
     if (format == Compressor::XDR)
     {
@@ -712,30 +1718,30 @@ fillChannelWithZeroes (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
                 Xdr::write <CharPtrIO> (writePtr, (unsigned int) 0);
 
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
                 Xdr::write <CharPtrIO> (writePtr, (half) 0);
 
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
                 Xdr::write <CharPtrIO> (writePtr, (float) 0);
 
             break;
-
+            
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
     else
@@ -746,9 +1752,9 @@ fillChannelWithZeroes (char *& writePtr,
 
         switch (type)
         {
-          case UINT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
             {
                 static const unsigned int ui = 0;
 
@@ -757,18 +1763,18 @@ fillChannelWithZeroes (char *& writePtr,
             }
             break;
 
-          case HALF:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
             {
                 *(half *) writePtr = half (0);
                 writePtr += sizeof (half);
             }
             break;
 
-          case FLOAT:
+          case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-            for (int j = 0; j < xSize; ++j)
+            for (size_t j = 0; j < xSize; ++j)
             {
                 static const float f = 0;
 
@@ -776,12 +1782,98 @@ fillChannelWithZeroes (char *& writePtr,
                     *writePtr++ = ((char *) &f)[i];
             }
             break;
-
+            
           default:
 
-            throw Iex::ArgExc ("Unknown pixel data type.");
+            throw IEX_NAMESPACE::ArgExc ("Unknown pixel data type.");
         }
     }
 }
 
-} // namespace Imf
+bool
+usesLongNames (const Header &header)
+{
+    //
+    // If an OpenEXR file contains any attribute names, attribute type names
+    // or channel names longer than 31 characters, then the file cannot be
+    // read by older versions of the IlmImf library (up to OpenEXR 1.6.1).
+    // Before writing the file header, we check if the header contains
+    // any names longer than 31 characters; if it does, then we set the
+    // LONG_NAMES_FLAG in the file version number.  Older versions of the
+    // IlmImf library will refuse to read files that have the LONG_NAMES_FLAG
+    // set.  Without the flag, older versions of the library would mis-
+    // interpret the file as broken.
+    //
+
+    for (Header::ConstIterator i = header.begin();
+         i != header.end();
+         ++i)
+    {
+        if (strlen (i.name()) >= 32 || strlen (i.attribute().typeName()) >= 32)
+            return true;
+    }
+
+    const ChannelList &channels = header.channels();
+
+    for (ChannelList::ConstIterator i = channels.begin();
+         i != channels.end();
+         ++i)
+    {
+        if (strlen (i.name()) >= 32)
+            return true;
+    }
+
+    return false;
+}
+
+int
+getScanlineChunkOffsetTableSize(const Header& header)
+{
+    const Box2i &dataWindow = header.dataWindow();
+
+    vector<size_t> bytesPerLine;
+    size_t maxBytesPerLine = bytesPerLineTable (header,
+                                                bytesPerLine);
+
+    Compressor* compressor = newCompressor(header.compression(),
+                                           maxBytesPerLine,
+                                           header);
+
+    int linesInBuffer = numLinesInBuffer (compressor);
+
+    int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
+                          linesInBuffer) / linesInBuffer;
+
+    delete compressor;
+
+    return lineOffsetSize;
+}
+
+//
+// Located in ImfTiledMisc.cpp
+//
+int
+getTiledChunkOffsetTableSize(const Header& header);
+
+int
+getChunkOffsetTableSize(const Header& header,bool ignore_attribute)
+{
+    if(!ignore_attribute && header.hasChunkCount())
+    {
+        return header.chunkCount();
+    }
+    
+    if(header.hasType()  && !isSupportedType(header.type()))
+    {
+        throw IEX_NAMESPACE::ArgExc ("unsupported header type to "
+        "get chunk offset table size");
+    }
+    if (isTiled(header.type()) == false)
+        return getScanlineChunkOffsetTableSize(header);
+    else
+        return getTiledChunkOffsetTableSize(header);
+    
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 3a464a0..c0d90ea 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfPixelType.h>
+#include "ImfPixelType.h"
+#include "ImfCompressor.h"
+#include "ImfArray.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
+
+#include <cstddef>
 #include <vector>
-#include <ImfCompressor.h>
 
-namespace Imf {
 
-class Header;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
 
 //
 // Return the size of a single value of the indicated type,
 // in the machine's native format.
 //
 
+IMF_EXPORT
 int    pixelTypeSize (PixelType type);
 
 
@@ -67,6 +74,7 @@ int   pixelTypeSize (PixelType type);
 // interval [2, 6].
 //
 
+IMF_EXPORT
 int    numSamples (int s, int a, int b);
 
 
@@ -77,22 +85,91 @@ int numSamples (int s, int a, int b);
 // the pixel data are tightly packed).
 //
 
+IMF_EXPORT
 size_t bytesPerLineTable (const Header &header,
-                   std::vector<size_t> &bytesPerLine);
+                          std::vector<size_t> &bytesPerLine);
+
+
+//
+// Get the sample count for pixel (x, y) using the array base
+// pointer, xStride and yStride.
+//
+
+inline
+int&
+sampleCount(char* base, int xStride, int yStride, int x, int y)
+{
+    char* ptr = base + y * yStride + x * xStride;
+    int* intPtr = (int*) ptr;
+
+    return *intPtr;
+}
+
+
+inline
+const int&
+sampleCount(const char* base, int xStride, int yStride, int x, int y)
+{
+    const char* ptr = base + y * yStride + x * xStride;
+    int* intPtr = (int*) ptr;
+    
+    return *intPtr;
+}
+
+//
+// Build a table that lists, for each scanline in a DEEP file's
+// data window, how many bytes are required to store all
+// pixels in all channels in scanlines ranged in [minY, maxY]
+// (assuming that the pixel data are tightly packed).
+//
+
+IMF_EXPORT
+size_t bytesPerDeepLineTable (const Header &header,
+                              int minY, int maxY,
+                              const char* base,
+                              int xStride,
+                              int yStride,
+                              std::vector<size_t> &bytesPerLine);
+
+
+//
+// Build a table that lists, for each scanline in a DEEP file's
+// data window, how many bytes are required to store all
+// pixels in all channels in every scanline (assuming that
+// the pixel data are tightly packed).
+//
+
+IMF_EXPORT
+size_t bytesPerDeepLineTable (const Header &header,
+                              char* base,
+                              int xStride,
+                              int yStride,
+                              std::vector<size_t> &bytesPerLine);
+
 
 //
 // For scanline-based files, pixels are read or written in
 // in multi-scanline blocks.  Internally, class OutputFile
 // and class ScanLineInputFile store a block of scan lines
 // in a "line buffer".  Function offsetInLineBufferTable()
-// builds a table that lists, for each scan line in a file's
-// data window, the location of the pixel data for the scanline
-// relative to the beginning of the line buffer.
+// builds a table that lists, scanlines within range
+// [scanline1, scanline2], the location of the pixel data
+// for the scanline relative to the beginning of the line buffer,
+// where scanline1 = 0 represents the first line in the DATA WINDOW.
+// The one without specifying the range will make scanline1 = 0
+// and scanline2 = bytesPerLine.size().
 //
 
+IMF_EXPORT
+void    offsetInLineBufferTable (const std::vector<size_t> &bytesPerLine,
+                                 int scanline1, int scanline2,
+                                 int linesInLineBuffer,
+                                 std::vector<size_t> &offsetInLineBuffer);
+
+IMF_EXPORT
 void   offsetInLineBufferTable (const std::vector<size_t> &bytesPerLine,
-                 int linesInLineBuffer,
-                 std::vector<size_t> &offsetInLineBuffer);
+                                int linesInLineBuffer,
+                                std::vector<size_t> &offsetInLineBuffer);
 
 //
 // For a scanline-based file, compute the range of scanlines
@@ -100,8 +177,8 @@ void        offsetInLineBufferTable (const std::vector<size_t> &bytesPerLine,
 // (minY is the minimum y coordinate of the file's data window.)
 //
 
-int    lineBufferMinY (int y, int minY, int linesInLineBuffer);
-int    lineBufferMaxY (int y, int minY, int linesInLineBuffer);
+IMF_EXPORT int lineBufferMinY (int y, int minY, int linesInLineBuffer);
+IMF_EXPORT int lineBufferMaxY (int y, int minY, int linesInLineBuffer);
 
 
 //
@@ -109,6 +186,7 @@ int lineBufferMaxY (int y, int minY, int linesInLineBuffer);
 // If compressor is 0, return Compressor::XDR.
 //
 
+IMF_EXPORT
 Compressor::Format defaultFormat (Compressor *compressor);
 
 
@@ -117,6 +195,7 @@ Compressor::Format defaultFormat (Compressor *compressor);
 // or uncompress at once.  If compressor is 0, return 1.
 //
 
+IMF_EXPORT
 int     numLinesInBuffer (Compressor *compressor);
 
 
@@ -146,16 +225,79 @@ int     numLinesInBuffer (Compressor *compressor);
 //    typeInFile        the pixel data type in the input file's channel
 //
 
+IMF_EXPORT
 void    copyIntoFrameBuffer (const char *&readPtr,
-                 char *writePtr,
+                            char *writePtr,
                              char *endPtr,
-                 size_t xStride,
-                 bool fill,
+                            size_t xStride,
+                            bool fill,
                              double fillValue,
-                 Compressor::Format format,
+                            Compressor::Format format,
                              PixelType typeInFrameBuffer,
                              PixelType typeInFile);
 
+
+//
+// Copy a single channel of a horizontal row of pixels from an
+// input file's internal line buffer or tile buffer into a
+// frame buffer slice.  If necessary, perform on-the-fly data
+// type conversion.
+//
+//    readPtr             initially points to the beginning of the
+//                        data in the line or tile buffer. readPtr
+//                        is advanced as the pixel data are copied;
+//                        when copyIntoFrameBuffer() returns,
+//                        readPtr points just past the end of the
+//                        copied data.
+//
+//    base                point to each pixel in the framebuffer
+//
+//    sampleCountBase,    provide the number of samples in each pixel
+//    sampleCountXStride,
+//    sampleCountYStride
+//
+//    y                   the scanline to copy. The coordinate is
+//                        relative to the datawindow.min.y.
+//
+//    minX, maxX          used to indicate which pixels in the scanline
+//                        will be copied.
+//
+//    xOffsetForSampleCount,    used to offset the sample count array
+//    yOffsetForSampleCount,    and the base array.
+//    xOffsetForData,
+//    yOffsetForData
+//
+//    xStride             the xStride for the frame buffer slice
+//
+//    format              indicates if the line or tile buffer is
+//                        in NATIVE or XDR format.
+//
+//    typeInFrameBuffer   the pixel data type of the frame buffer slice
+//
+//    typeInFile          the pixel data type in the input file's channel
+//
+
+IMF_EXPORT
+void    copyIntoDeepFrameBuffer (const char *& readPtr,
+                                 char * base,
+                                 const char* sampleCountBase,
+                                 ptrdiff_t sampleCountXStride,
+                                 ptrdiff_t sampleCountYStride,
+                                 int y, int minX, int maxX,
+                                 int xOffsetForSampleCount,
+                                 int yOffsetForSampleCount,
+                                 int xOffsetForData,
+                                 int yOffsetForData,
+                                 ptrdiff_t xStride,
+                                 ptrdiff_t xPointerStride,
+                                 ptrdiff_t yPointerStride,
+                                 bool fill,
+                                 double fillValue,
+                                 Compressor::Format format,
+                                 PixelType typeInFrameBuffer,
+                                 PixelType typeInFile);
+
+
 //
 // Given a pointer into a an input file's line buffer or tile buffer,
 // skip over the data for xSize pixels of type typeInFile.
@@ -164,9 +306,10 @@ void    copyIntoFrameBuffer (const char *&readPtr,
 // skipped data.
 //
 
+IMF_EXPORT
 void    skipChannel (const char *&readPtr,
-             PixelType typeInFile,
-             size_t xSize);
+                    PixelType typeInFile,
+                    size_t xSize);
 
 //
 // Convert an array of pixel data from the machine's native
@@ -185,11 +328,12 @@ void    skipChannel (const char *&readPtr,
 //    type             the pixel data type
 //
 //    numPixels                number of pixels in the input and output arrays
-//
+// 
 
+IMF_EXPORT
 void    convertInPlace (char *&toPtr,
-            const char *&fromPtr,
-            PixelType type,
+                       const char *&fromPtr,
+                       PixelType type,
                         size_t numPixels);
 
 //
@@ -218,12 +362,76 @@ void    convertInPlace (char *&toPtr,
 //                     data type conversion)
 //
 
+IMF_EXPORT
 void    copyFromFrameBuffer (char *&writePtr,
-                 const char *&readPtr,
+                            const char *&readPtr,
                              const char *endPtr,
-                 size_t xStride,
+                            size_t xStride,
                              Compressor::Format format,
-                 PixelType type);
+                            PixelType type);
+
+//
+// Copy a single channel of a horizontal row of pixels from a
+// a frame buffer in a deep data file into an output file's
+// internal line buffer or tile buffer.
+//
+//    writePtr                  initially points to the beginning of the
+//                              data in the line or tile buffer. writePtr
+//                              is advanced as the pixel data are copied;
+//                              when copyFromDeepFrameBuffer() returns,
+//                              writePtr points just past the end of the
+//                              copied data.
+//
+//    base                      the start pointer of each pixel in this channel.
+//                              It points to the real data in FrameBuffer.
+//                              It is different for different channels.
+//                              dataWindowMinX and dataWindowMinY are involved in
+//                              locating for base.
+//
+//    sampleCountBase,          used to locate the position to get
+//    sampleCountXStride,       the number of samples for each pixel.
+//    sampleCountYStride        Used to determine how far we should
+//                              read based on the pointer provided by base.
+//
+//    y                         the scanline to copy. If we are dealing
+//                              with a tiled deep file, then probably a portion
+//                              of the scanline is copied.
+//
+//    xMin, xMax                used to indicate which pixels in the scanline
+//                              will be copied.
+//
+//    xOffsetForSampleCount,    used to offset the sample count array
+//    yOffsetForSampleCount,    and the base array.
+//    xOffsetForData,
+//    yOffsetForData
+//
+//    xStride                   the xStride for the frame buffer slice
+//
+//    format                    indicates if the line or tile buffer is
+//                              in NATIVE or XDR format.
+//
+//    type                      the pixel data type in the frame buffer
+//                              and in the output file's channel (function
+//                              copyFromFrameBuffer() doesn't do on-the-fly
+//                              data type conversion)
+//
+
+IMF_EXPORT
+void    copyFromDeepFrameBuffer (char *& writePtr,
+                                 const char * base,
+                                 char* sampleCountBase,
+                                 ptrdiff_t sampleCountXStride,
+                                 ptrdiff_t sampleCountYStride,
+                                 int y, int xMin, int xMax,
+                                 int xOffsetForSampleCount,
+                                 int yOffsetForSampleCount,
+                                 int xOffsetForData,
+                                 int yOffsetForData,
+                                 ptrdiff_t sampleStride,
+                                 ptrdiff_t xStrideForData,
+                                 ptrdiff_t yStrideForData,
+                                 Compressor::Format format,
+                                 PixelType type);
 
 //
 // Fill part of an output file's line buffer or tile buffer with
@@ -245,11 +453,26 @@ void    copyFromFrameBuffer (char *&writePtr,
 //    xSize             number of pixels to be filled with zeroes.
 //
 
+IMF_EXPORT
 void    fillChannelWithZeroes (char *&writePtr,
-                   Compressor::Format format,
-                   PixelType type,
-                   size_t xSize);
+                              Compressor::Format format,
+                              PixelType type,
+                              size_t xSize);
+
+IMF_EXPORT
+bool usesLongNames (const Header &header);
+
+
+//
+// compute size of chunk offset table - if ignore_attribute set to true
+// will compute from the image size and layout, rather than the attribute
+// The default behaviour is to read the attribute
+//
+
+IMF_EXPORT
+int getChunkOffsetTableSize(const Header& header,bool ignore_attribute=false);
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imf
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfMultiPartInputFile.cpp b/3rdparty/openexr/IlmImf/ImfMultiPartInputFile.cpp
new file mode 100644 (file)
index 0000000..55bdcaa
--- /dev/null
@@ -0,0 +1,783 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfMultiPartInputFile.h"
+
+#include "ImfTimeCodeAttribute.h"
+#include "ImfChromaticitiesAttribute.h"
+#include "ImfBoxAttribute.h"
+#include "ImfFloatAttribute.h"
+#include "ImfStdIO.h"
+#include "ImfTileOffsets.h"
+#include "ImfMisc.h"
+#include "ImfTiledMisc.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+#include "ImfPartType.h"
+#include "ImfInputFile.h"
+#include "ImfScanLineInputFile.h"
+#include "ImfTiledInputFile.h"
+#include "ImfDeepScanLineInputFile.h"
+#include "ImfDeepTiledInputFile.h"
+#include "ImfVersion.h"
+
+#include <OpenEXRConfig.h>
+#include <IlmThread.h>
+#include <IlmThreadMutex.h>
+
+#include <Iex.h>
+#include <map>
+#include <set>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using IMATH_NAMESPACE::Box2i;
+
+using std::vector;
+using std::map;
+using std::set;
+using std::string;
+
+namespace
+{
+    // Controls whether we error out in the event of shared attribute
+    // inconsistency in the input file
+    static const bool strictSharedAttribute = true;
+}
+
+struct MultiPartInputFile::Data: public InputStreamMutex
+{
+    int                         version;        // Version of this file.
+    bool                        deleteStream;   // If we should delete the stream during destruction.
+    vector<InputPartData*>      parts;          // Data to initialize Output files.
+    int                         numThreads;     // Number of threads
+    bool                        reconstructChunkOffsetTable;    // If we should reconstruct
+                                                                // the offset table if it's broken.
+    std::map<int,GenericInputFile*> _inputFiles;
+    std::vector<Header>             _headers;
+
+    
+    void                    chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, const std::vector<InputPartData*>& parts);
+                                                      
+    void                    readChunkOffsetTables(bool reconstructChunkOffsetTable);
+                                                      
+    bool                    checkSharedAttributesValues(const Header & src,
+                                                        const Header & dst,
+                                                        std::vector<std::string> & conflictingAttributes) const;
+                                                                                                          
+   TileOffsets*            createTileOffsets(const Header& header);
+   
+   InputPartData*          getPart(int partNumber);
+   
+    Data (bool deleteStream, int numThreads, bool reconstructChunkOffsetTable):
+        InputStreamMutex(),
+        deleteStream (deleteStream),
+        numThreads (numThreads),
+        reconstructChunkOffsetTable(reconstructChunkOffsetTable)
+    {
+    }
+
+    ~Data()
+    {
+        if (deleteStream) delete is;
+
+        for (size_t i = 0; i < parts.size(); i++)
+            delete parts[i];
+    }
+    
+    template <class T>
+    T*    createInputPartT(int partNumber)
+    {
+
+    }
+};
+
+MultiPartInputFile::MultiPartInputFile(const char fileName[],
+                           int numThreads,
+                           bool reconstructChunkOffsetTable):
+    _data(new Data(true, numThreads, reconstructChunkOffsetTable))
+{
+    try
+    {
+        _data->is = new StdIFStream (fileName);
+        initialize();
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot read image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+MultiPartInputFile::MultiPartInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is,
+                                        int numThreads,
+                                        bool reconstructChunkOffsetTable):
+    _data(new Data(false, numThreads, reconstructChunkOffsetTable))
+{
+    try
+    {
+        _data->is = &is;
+        initialize();
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot read image file "
+                     "\"" << is.fileName() << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+template<class T>
+T*
+MultiPartInputFile::getInputPart(int partNumber)
+{
+    Lock lock(*_data);
+            if (_data->_inputFiles.find(partNumber) == _data->_inputFiles.end())
+        {
+            T* file = new T(_data->getPart(partNumber));
+            _data->_inputFiles.insert(std::make_pair(partNumber, (GenericInputFile*) file));
+            return file;
+        }
+        else return (T*) _data->_inputFiles[partNumber];
+}
+
+
+template InputFile* MultiPartInputFile::getInputPart<InputFile>(int);
+template TiledInputFile* MultiPartInputFile::getInputPart<TiledInputFile>(int);
+template DeepScanLineInputFile* MultiPartInputFile::getInputPart<DeepScanLineInputFile>(int);
+template DeepTiledInputFile* MultiPartInputFile::getInputPart<DeepTiledInputFile>(int);
+
+InputPartData*
+MultiPartInputFile::getPart(int partNumber)
+{
+    return _data->getPart(partNumber);
+}
+
+
+
+const Header &
+ MultiPartInputFile::header(int n) const
+{
+    return _data->_headers[n];
+}
+
+
+
+MultiPartInputFile::~MultiPartInputFile()
+{
+    for (map<int, GenericInputFile*>::iterator it = _data->_inputFiles.begin();
+         it != _data->_inputFiles.end(); it++)
+    {
+        delete it->second;
+    }
+
+    delete _data;
+}
+
+
+bool
+MultiPartInputFile::Data::checkSharedAttributesValues(const Header & src,
+                                                const Header & dst,
+                                                vector<string> & conflictingAttributes) const
+{
+    conflictingAttributes.clear();
+
+    bool conflict = false;
+
+    //
+    // Display Window
+    //
+    if (src.displayWindow() != dst.displayWindow())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("displayWindow");
+    }
+
+
+    //
+    // Pixel Aspect Ratio
+    //
+    if (src.pixelAspectRatio() != dst.pixelAspectRatio())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("pixelAspectRatio");
+    }
+
+
+    //
+    // Timecode
+    //
+    const TimeCodeAttribute * srcTimeCode = src.findTypedAttribute<
+          TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+    const TimeCodeAttribute * dstTimeCode = dst.findTypedAttribute<
+          TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+
+    if (dstTimeCode)
+    {
+        if  ( (srcTimeCode && (srcTimeCode->value() != dstTimeCode->value())) ||
+              (!srcTimeCode))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (TimeCodeAttribute::staticTypeName());
+        }
+    }
+
+    //
+    // Chromaticities
+    //
+    const ChromaticitiesAttribute * srcChrom =  src.findTypedAttribute<
+          ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+    const ChromaticitiesAttribute * dstChrom =  dst.findTypedAttribute<
+          ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+
+    if (dstChrom)
+    {
+        if ( (srcChrom && (srcChrom->value() != dstChrom->value())) ||
+             (!srcChrom))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (ChromaticitiesAttribute::staticTypeName());
+        }
+    }
+
+
+    return conflict;
+}
+
+
+void
+MultiPartInputFile::initialize()
+{
+    readMagicNumberAndVersionField(*_data->is, _data->version);
+    
+    bool multipart = isMultiPart(_data->version);
+    bool tiled = isTiled(_data->version);
+
+    //
+    // Multipart files don't have and shouldn't have the tiled bit set.
+    //
+
+    if (tiled && multipart)
+        throw IEX_NAMESPACE::InputExc ("Multipart files cannot have the tiled bit set");
+
+    
+    int pos = 0;
+    while (true)
+    {
+        Header header;
+        header.readFrom(*_data->is, _data->version);
+
+        //
+        // If we read nothing then we stop reading.
+        //
+
+        if (header.readsNothing())
+        {
+            pos++;
+            break;
+        }
+
+        _data->_headers.push_back(header);
+        
+        if(multipart == false)
+          break;
+    }
+
+    //
+    // Perform usual check on headers.
+    //
+
+    for (size_t i = 0; i < _data->_headers.size(); i++)
+    {
+        //
+        // Silently invent a type if the file is a single part regular image.
+        //
+
+        if( _data->_headers[i].hasType() == false )
+        {
+            if(multipart)
+
+                throw IEX_NAMESPACE::ArgExc ("Every header in a multipart file should have a type");
+          
+            _data->_headers[i].setType(tiled ? TILEDIMAGE : SCANLINEIMAGE);
+        }
+        else
+        {
+            
+            //
+            // Silently fix the header type if it's wrong
+            // (happens when a regular Image file written by EXR_2.0 is rewritten by an older library,
+            //  so doesn't effect deep image types)
+            //
+
+            if(!multipart && !isNonImage(_data->version))
+            {
+                _data->_headers[i].setType(tiled ? TILEDIMAGE : SCANLINEIMAGE);
+            }
+        }
+         
+
+        
+        if( _data->_headers[i].hasName() == false )
+        {
+            if(multipart)
+                throw IEX_NAMESPACE::ArgExc ("Every header in a multipart file should have a name");
+        }
+        
+        if (isTiled(_data->_headers[i].type()))
+            _data->_headers[i].sanityCheck(true, multipart);
+        else
+            _data->_headers[i].sanityCheck(false, multipart);
+    }
+
+    //
+    // Check name uniqueness.
+    //
+
+    if (multipart)
+    {
+        set<string> names;
+        for (size_t i = 0; i < _data->_headers.size(); i++)
+        {
+        
+            if (names.find(_data->_headers[i].name()) != names.end())
+            {
+                throw IEX_NAMESPACE::InputExc ("Header name " + _data->_headers[i].name() +
+                                   " is not a unique name.");
+            }
+            names.insert(_data->_headers[i].name());
+        }
+    }
+    
+    //
+    // Check shared attributes compliance.
+    //
+
+    if (multipart && strictSharedAttribute)
+    {
+        for (size_t i = 1; i < _data->_headers.size(); i++)
+        {
+            vector <string> attrs;
+            if (_data->checkSharedAttributesValues (_data->_headers[0], _data->_headers[i], attrs))
+            {
+                string attrNames;
+                for (size_t j=0; j<attrs.size(); j++)
+                    attrNames += " " + attrs[j];
+                throw IEX_NAMESPACE::InputExc ("Header name " + _data->_headers[i].name() +
+                                     " has non-conforming shared attributes: "+
+                                     attrNames);
+            }
+        }
+    }
+
+    //
+    // Create InputParts and read chunk offset tables.
+    //
+        
+    for (size_t i = 0; i < _data->_headers.size(); i++)
+        _data->parts.push_back(
+                new InputPartData(_data, _data->_headers[i], i, _data->numThreads, _data->version));
+
+    _data->readChunkOffsetTables(_data->reconstructChunkOffsetTable);
+}
+
+TileOffsets*
+MultiPartInputFile::Data::createTileOffsets(const Header& header)
+{
+    //
+    // Get the dataWindow information
+    //
+
+    const Box2i &dataWindow = header.dataWindow();
+    int minX = dataWindow.min.x;
+    int maxX = dataWindow.max.x;
+    int minY = dataWindow.min.y;
+    int maxY = dataWindow.max.y;
+
+    //
+    // Precompute level and tile information
+    //
+
+    int* numXTiles;
+    int* numYTiles;
+    int numXLevels, numYLevels;
+    TileDescription tileDesc = header.tileDescription();
+    precalculateTileInfo (tileDesc,
+                          minX, maxX,
+                          minY, maxY,
+                          numXTiles, numYTiles,
+                          numXLevels, numYLevels);
+
+    TileOffsets* tileOffsets = new TileOffsets (tileDesc.mode,
+                                                numXLevels,
+                                                numYLevels,
+                                                numXTiles,
+                                                numYTiles);
+    delete [] numXTiles;
+    delete [] numYTiles;
+
+    return tileOffsets;
+}
+
+
+void
+MultiPartInputFile::Data::chunkOffsetReconstruction(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is, const vector<InputPartData*>& parts)
+{
+    //
+    // Reconstruct broken chunk offset tables. Stop once we received any exception.
+    //
+
+    Int64 position = is.tellg();
+
+    
+    //
+    // check we understand all the parts available: if not, we cannot continue
+    // exceptions thrown here should trickle back up to the constructor
+    //
+    
+    for (size_t i = 0; i < parts.size(); i++)
+    {
+        Header& header=parts[i]->header;
+        
+        //
+        // do we have a valid type entry?
+        // we only need them for true multipart files or single part non-image (deep) files
+        //
+        if(!header.hasType() && (isMultiPart(version) || isNonImage(version)))
+        {
+            throw IEX_NAMESPACE::ArgExc("cannot reconstruct incomplete file: part with missing type");
+        }
+        if(!isSupportedType(header.type()))
+        {
+            throw IEX_NAMESPACE::ArgExc("cannot reconstruct incomplete file: part with unknown type "+header.type());
+        }
+    }
+    
+    
+    // how many chunks should we read? We should stop when we reach the end
+    size_t total_chunks = 0;
+        
+    // for tiled-based parts, array of (pointers to) tileOffsets objects
+    // to create mapping between tile coordinates and chunk table indices
+    
+    
+    vector<TileOffsets*> tileOffsets(parts.size());
+    
+    // for scanline-based parts, number of scanlines in each part
+    vector<int> rowsizes(parts.size());
+        
+    for(size_t i = 0 ; i < parts.size() ; i++)
+    {
+        total_chunks += parts[i]->chunkOffsets.size();
+        if (isTiled(parts[i]->header.type()))
+        {
+            tileOffsets[i] = createTileOffsets(parts[i]->header);
+        }else{
+            tileOffsets[i] = NULL;
+            // (TODO) fix this so that it doesn't need to be revised for future compression types.
+            switch(parts[i]->header.compression())
+            {
+                case DWAB_COMPRESSION :
+                    rowsizes[i] = 256;
+                    break;
+                case PIZ_COMPRESSION :
+                case B44_COMPRESSION :
+                case B44A_COMPRESSION :
+                case DWAA_COMPRESSION :
+                    rowsizes[i]=32;
+                    break;
+                case ZIP_COMPRESSION :
+                case PXR24_COMPRESSION :
+                    rowsizes[i]=16;
+                    break;
+                case ZIPS_COMPRESSION :
+                case RLE_COMPRESSION :
+                case NO_COMPRESSION :
+                    rowsizes[i]=1;
+                    break;
+                default :
+                    throw(IEX_NAMESPACE::ArgExc("Unknown compression method in chunk offset reconstruction"));
+            }
+        }
+     }
+        
+     try
+     {
+            
+        //
+        // 
+        //
+        
+        Int64 chunk_start = position;
+        for (size_t i = 0; i < total_chunks ; i++)
+        {
+            //
+            // do we have a part number?
+            //
+            
+            int partNumber = 0;
+            if(isMultiPart(version))
+            {
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, partNumber);
+            }
+            
+            
+            
+            if(partNumber<0 || partNumber>int(parts.size()))
+            {
+                // bail here - bad part number
+                throw int();
+            }
+            
+            Header& header = parts[partNumber]->header;
+
+            // size of chunk NOT including multipart field
+            
+            Int64 size_of_chunk=0;
+
+            if (isTiled(header.type()))
+            {
+                //
+                // 
+                //
+                int tilex,tiley,levelx,levely;
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tilex);
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tiley);
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelx);
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levely);
+                
+                //std::cout << "chunk_start for " << tilex <<',' << tiley << ',' << levelx << ' ' << levely << ':' << chunk_start << std::endl;
+                    
+                
+                if(!tileOffsets[partNumber])
+                {
+                    // this shouldn't actually happen - we should have allocated a valid
+                    // tileOffsets for any part which isTiled
+                    throw int();
+                    
+                }
+                
+                if(!tileOffsets[partNumber]->isValidTile(tilex,tiley,levelx,levely))
+                {
+                    //std::cout << "invalid tile : aborting\n";
+                    throw int();
+                }
+                
+                (*tileOffsets[partNumber])(tilex,tiley,levelx,levely)=chunk_start;
+                
+                // compute chunk sizes - different procedure for deep tiles and regular
+                // ones
+                if(header.type()==DEEPTILE)
+                {
+                    Int64 packed_offset;
+                    Int64 packed_sample;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
+                    
+                    //add 40 byte header to packed sizes (tile coordinates, packed sizes, unpacked size)
+                    size_of_chunk=packed_offset+packed_sample+40;
+                }
+                else
+                {
+                    
+                    // regular image has 20 bytes of header, 4 byte chunksize;
+                    int chunksize;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, chunksize);
+                    size_of_chunk=chunksize+20;
+                }
+            }
+            else
+            {
+                int y_coordinate;
+                OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, y_coordinate);
+                
+                y_coordinate -= header.dataWindow().min.y;
+                y_coordinate /= rowsizes[partNumber];   
+                
+                if(y_coordinate < 0 || y_coordinate >= int(parts[partNumber]->chunkOffsets.size()))
+                {
+                    //std::cout << "aborting reconstruction: bad data " << y_coordinate << endl;
+                    //bail to exception catcher: broken scanline
+                    throw int();
+                }
+                
+                parts[partNumber]->chunkOffsets[y_coordinate]=chunk_start;
+                //std::cout << "chunk_start for " << y_coordinate << ':' << chunk_start << std::endl;
+                
+                if(header.type()==DEEPSCANLINE)
+                {
+                    Int64 packed_offset;
+                    Int64 packed_sample;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset);
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample);
+                    
+                    
+                    size_of_chunk=packed_offset+packed_sample+28;
+                }
+                else
+                {
+                    int chunksize;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, chunksize);   
+                    size_of_chunk=chunksize+8;
+                }
+                
+            }
+            
+            if(isMultiPart(version))
+            {
+                chunk_start+=4;
+            }
+            
+            chunk_start+=size_of_chunk;
+            
+            //std::cout << " next chunk +"<<size_of_chunk << " = " << chunk_start << std::endl;
+            
+            is.seekg(chunk_start);
+            
+        }
+        
+    }
+    catch (...)
+    {
+        //
+        // Suppress all exceptions.  This functions is
+        // called only to reconstruct the line offset
+        // table for incomplete files, and exceptions
+        // are likely.
+        //
+    }
+
+    // copy tiled part data back to chunk offsets
+    
+    for(size_t partNumber=0;partNumber<parts.size();partNumber++)
+    {
+        if(tileOffsets[partNumber])
+        {
+            size_t pos=0;
+            vector<vector<vector <Int64> > > offsets = tileOffsets[partNumber]->getOffsets();
+            for (size_t l = 0; l < offsets.size(); l++)
+                for (size_t y = 0; y < offsets[l].size(); y++)
+                    for (size_t x = 0; x < offsets[l][y].size(); x++)
+                    {
+                        parts[ partNumber ]->chunkOffsets[pos] = offsets[l][y][x];
+                        pos++;
+                    }
+           delete tileOffsets[partNumber];
+        }
+    }
+
+    is.clear();
+    is.seekg (position);
+}
+
+InputPartData*
+MultiPartInputFile::Data::getPart(int partNumber)
+{
+    if (partNumber < 0 || partNumber >= (int) parts.size())
+        throw IEX_NAMESPACE::ArgExc ("Part number is not in valid range.");
+    return parts[partNumber];
+}
+
+
+
+void
+MultiPartInputFile::Data::readChunkOffsetTables(bool reconstructChunkOffsetTable)
+{
+    bool brokenPartsExist = false;
+
+    for (size_t i = 0; i < parts.size(); i++)
+    {
+        int chunkOffsetTableSize = getChunkOffsetTableSize(parts[i]->header,false);
+        parts[i]->chunkOffsets.resize(chunkOffsetTableSize);
+
+        for (int j = 0; j < chunkOffsetTableSize; j++)
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*is, parts[i]->chunkOffsets[j]);
+
+        //
+        // Check chunk offsets, reconstruct if broken.
+        // At first we assume the table is complete.
+        //
+        parts[i]->completed = true;
+        for (int j = 0; j < chunkOffsetTableSize; j++)
+        {
+            if (parts[i]->chunkOffsets[j] <= 0)
+            {
+                brokenPartsExist = true;
+                parts[i]->completed = false;
+                break;
+            }
+        }
+    }
+
+    if (brokenPartsExist && reconstructChunkOffsetTable)
+        chunkOffsetReconstruction(*is, parts);
+}
+
+int 
+MultiPartInputFile::version() const
+{
+    return _data->version;
+}
+
+bool 
+MultiPartInputFile::partComplete(int part) const
+{
+  return _data->parts[part]->completed;
+}
+
+int 
+MultiPartInputFile::parts() const
+{
+   return int(_data->_headers.size());
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfMultiPartInputFile.h b/3rdparty/openexr/IlmImf/ImfMultiPartInputFile.h
new file mode 100644 (file)
index 0000000..67ac5a4
--- /dev/null
@@ -0,0 +1,134 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFMULTIPARTINPUTFILE_H_
+#define IMFMULTIPARTINPUTFILE_H_
+
+#include "ImfGenericInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfThreading.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+class MultiPartInputFile : public GenericInputFile
+{
+  public:
+    IMF_EXPORT
+    MultiPartInputFile(const char fileName[],
+                       int numThreads = globalThreadCount(),
+                       bool reconstructChunkOffsetTable = true);
+
+    IMF_EXPORT
+    MultiPartInputFile(IStream& is,
+                       int numThreads = globalThreadCount(),
+                       bool reconstructChunkOffsetTable = true);
+
+    IMF_EXPORT
+    virtual ~MultiPartInputFile();
+
+    // ----------------------
+    // Count of number of parts in file
+    // ---------------------
+    IMF_EXPORT
+    int parts() const;
+    
+    
+    //----------------------
+    // Access to the headers
+    //----------------------
+
+    IMF_EXPORT
+    const Header &  header(int n) const;
+    
+
+    //----------------------------------
+    // Access to the file format version
+    //----------------------------------
+
+    IMF_EXPORT
+    int                            version () const;
+
+
+    // =----------------------------------------
+    // Check whether the entire chunk offset
+    // table for the part is written correctly
+    // -----------------------------------------
+    IMF_EXPORT
+    bool partComplete(int part) const;
+
+
+    struct Data;
+
+
+  private:
+    Data*                           _data;
+
+    MultiPartInputFile(const MultiPartInputFile &); // not implemented
+
+    
+    //
+    // used internally by 'Part' types to access individual parts of the multipart file
+    //
+    template<class T> T*    getInputPart(int partNumber);
+    InputPartData*          getPart(int);
+    
+    void                    initialize();
+
+
+    
+
+    friend class InputPart;
+    friend class ScanLineInputPart;
+    friend class TiledInputPart;
+    friend class DeepScanLineInputPart;
+    friend class DeepTiledInputPart;
+
+    //
+    // For backward compatibility.
+    //
+
+    friend class InputFile;
+    friend class TiledInputFile;
+    friend class ScanLineInputFile;
+    friend class DeepScanLineInputFile;
+    friend class DeepTiledInputFile;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFMULTIPARTINPUTFILE_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfMultiPartOutputFile.cpp b/3rdparty/openexr/IlmImf/ImfMultiPartOutputFile.cpp
new file mode 100644 (file)
index 0000000..8260cd2
--- /dev/null
@@ -0,0 +1,519 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfMultiPartOutputFile.h"
+#include "ImfBoxAttribute.h"
+#include "ImfFloatAttribute.h"
+#include "ImfTimeCodeAttribute.h"
+#include "ImfChromaticitiesAttribute.h"
+#include "ImfOutputPartData.h"
+#include "ImfPartType.h"
+#include "ImfOutputFile.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfThreading.h"
+#include "IlmThreadMutex.h"
+#include "ImfMisc.h"
+#include "ImfStdIO.h"
+#include "ImfDeepScanLineOutputFile.h"
+#include "ImfDeepTiledOutputFile.h"
+#include "ImfOutputStreamMutex.h"
+
+#include "ImfNamespace.h"
+#include <Iex.h>
+
+
+#include <set>
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using ILMTHREAD_NAMESPACE::Lock;
+    
+
+using std::vector;
+using std::map;
+using std::set;
+
+
+struct MultiPartOutputFile::Data: public OutputStreamMutex
+{
+        vector<OutputPartData*>         parts;        // Contains data to initialize Output files.
+        bool                            deleteStream; // If we should delete the stream when destruction.
+        int                             numThreads;   // The number of threads.
+        std::map<int, GenericOutputFile*>    _outputFiles;
+        std::vector<Header>                  _headers;
+        
+        
+        void                    headerNameUniquenessCheck (const std::vector<Header> &headers);
+        
+        void                    writeHeadersToFile (const std::vector<Header> &headers); 
+        
+        void                    writeChunkTableOffsets (std::vector<OutputPartData*> &parts);
+        
+        
+        //-------------------------------------
+        // ensure that _headers is valid: called by constructors
+        //-------------------------------------
+        void                    do_header_sanity_checks(bool overrideSharedAttributes);
+        
+        // ------------------------------------------------
+        // Given a source header, we copy over all the 'shared attributes' to
+        // the destination header and remove any conflicting ones.
+        // ------------------------------------------------
+        void                    overrideSharedAttributesValues (const Header & src,
+                                                                Header & dst);
+                                                                
+        // ------------------------------------------------
+        // Given a source header, we check the destination header for any
+        // attributes that are part of the shared attribute set. For attributes
+        // present in both we check the values. For attribute present in 
+        // destination but absent in source we return false.
+        // For attributes present in src but missing from dst we return false
+        // and add the attribute to dst.
+        // We return false for all other cases.
+        // If we return true then we also populate the conflictingAttributes
+        // vector with the names of the attributes that failed the above.
+        // ------------------------------------------------
+        bool                    checkSharedAttributesValues (const Header & src,
+                                                             const Header & dst, 
+                                                             std::vector<std::string> & conflictingAttributes) const;
+        Data (bool deleteStream, int numThreads):
+            OutputStreamMutex(),
+            deleteStream (deleteStream),
+            numThreads (numThreads)
+        {
+        }
+        
+
+        ~Data()
+        {
+            if (deleteStream) delete os;
+
+            for (size_t i = 0; i < parts.size(); i++)
+                delete parts[i];
+        }
+};
+
+void
+MultiPartOutputFile::Data::do_header_sanity_checks(bool overrideSharedAttributes)
+{
+    size_t parts = _headers.size();
+    if (parts == 0) 
+        throw IEX_NAMESPACE::ArgExc ("Empty header list.");
+    
+    bool isMultiPart = (parts > 1); 
+    
+    //
+    // Do part 0 checks first.
+    //
+    
+    _headers[0].sanityCheck (_headers[0].hasTileDescription(), isMultiPart);
+        
+    
+    if (isMultiPart)
+    {
+        // multipart files must contain a chunkCount attribute
+        _headers[0].setChunkCount(getChunkOffsetTableSize(_headers[0],true));
+        
+        for (size_t i = 1; i < parts; i++)
+        {
+            if (_headers[i].hasType() == false)
+                throw IEX_NAMESPACE::ArgExc ("Every header in a multipart file should have a type");
+            
+            
+            _headers[i].setChunkCount(getChunkOffsetTableSize(_headers[i],true));
+            _headers[i].sanityCheck (_headers[i].hasTileDescription(), isMultiPart);
+            
+            
+            if (overrideSharedAttributes)
+                overrideSharedAttributesValues(_headers[0],_headers[i]);
+            else
+            {
+                std::vector<std::string> conflictingAttributes;
+                bool valid =checkSharedAttributesValues (_headers[0],
+                                                         _headers[i], 
+                                                         conflictingAttributes);
+                if (valid)
+                {
+                    string excMsg("Conflicting attributes found for header :: ");
+                    excMsg += _headers[i].name();
+                    for (size_t i=0; i<conflictingAttributes.size(); i++)
+                        excMsg += " '" + conflictingAttributes[i] + "' ";
+                                                             
+                    THROW (IEX_NAMESPACE::ArgExc, excMsg);
+                }
+            }
+        }
+        
+        headerNameUniquenessCheck(_headers);
+        
+    }else{
+        
+        // add chunk count offset to single part data (if not an image)
+        
+        if (_headers[0].hasType() && isImage(_headers[0].type()) == false)
+        {
+            _headers[0].setChunkCount(getChunkOffsetTableSize(_headers[0],true));
+        }
+        
+    }
+}
+
+    
+MultiPartOutputFile::MultiPartOutputFile (const char fileName[],
+                                          const Header * headers,
+                                          int parts,
+                                          bool overrideSharedAttributes,
+                                          int numThreads)
+:
+    _data (new Data (true, numThreads))
+{
+    // grab headers
+    _data->_headers.resize(parts);
+    
+    for(int i=0;i<parts;i++)
+    {
+       _data->_headers[i]=headers[i];
+    }
+    try
+    {
+  
+         _data->do_header_sanity_checks(overrideSharedAttributes);
+
+        //
+        // Build parts and write headers and offset tables to file.
+        //
+
+        _data->os = new StdOFStream (fileName);
+        for (size_t i = 0; i < _data->_headers.size(); i++)
+            _data->parts.push_back( new OutputPartData(_data, _data->_headers[i], i, numThreads, parts>1 ) );
+
+        writeMagicNumberAndVersionField(*_data->os, &_data->_headers[0],_data->_headers.size());
+        _data->writeHeadersToFile(_data->_headers);
+        _data->writeChunkTableOffsets(_data->parts);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+MultiPartOutputFile::MultiPartOutputFile(OStream& os, 
+                                         const Header* headers, 
+                                         int parts, 
+                                         bool overrideSharedAttributes, 
+                                         int numThreads): 
+                                         _data(new Data(false,numThreads))
+{
+    // grab headers
+    _data->_headers.resize(parts);
+    _data->os=&os;
+    
+    for(int i=0;i<parts;i++)
+    {
+        _data->_headers[i]=headers[i];
+    }
+    try
+    {
+        
+        _data->do_header_sanity_checks(overrideSharedAttributes);
+        
+        //
+        // Build parts and write headers and offset tables to file.
+        //
+        
+        for (size_t i = 0; i < _data->_headers.size(); i++)
+            _data->parts.push_back( new OutputPartData(_data, _data->_headers[i], i, numThreads, parts>1 ) );
+        
+        writeMagicNumberAndVersionField(*_data->os, &_data->_headers[0],_data->_headers.size());
+        _data->writeHeadersToFile(_data->_headers);
+        _data->writeChunkTableOffsets(_data->parts);
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+        
+        REPLACE_EXC (e, "Cannot open image stream "
+                     "\"" << os.fileName() << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
+
+
+const Header &
+MultiPartOutputFile::header(int n) const
+{
+    if(n<0 || n>int(_data->_headers.size()))
+    {
+        throw IEX_NAMESPACE::ArgExc("MultiPartOutputFile::header called with invalid part number");
+    }
+    return _data->_headers[n];
+}
+
+int
+MultiPartOutputFile::parts() const
+{
+   return _data->_headers.size();
+}
+
+
+MultiPartOutputFile::~MultiPartOutputFile ()
+{
+    for (map<int, GenericOutputFile*>::iterator it = _data->_outputFiles.begin();
+         it != _data->_outputFiles.end(); it++)
+    {
+        delete it->second;
+    }
+
+    delete _data;
+}
+
+template <class T>
+T*
+MultiPartOutputFile::getOutputPart(int partNumber)
+{
+    Lock lock(*_data);
+    if (_data->_outputFiles.find(partNumber) == _data->_outputFiles.end())
+    {
+        T* file = new T(_data->parts[partNumber]);
+        _data->_outputFiles.insert(std::make_pair(partNumber, (GenericOutputFile*) file));
+        return file;
+    }
+    else return (T*) _data->_outputFiles[partNumber];
+}
+
+// instance above function for all four types
+template OutputFile* MultiPartOutputFile::getOutputPart<OutputFile>(int);
+template TiledOutputFile * MultiPartOutputFile::getOutputPart<TiledOutputFile>(int);
+template DeepScanLineOutputFile * MultiPartOutputFile::getOutputPart<DeepScanLineOutputFile> (int);
+template DeepTiledOutputFile * MultiPartOutputFile::getOutputPart<DeepTiledOutputFile> (int);
+
+
+
+void 
+MultiPartOutputFile::Data::overrideSharedAttributesValues(const Header & src, Header & dst)
+{
+    //
+    // Display Window
+    //
+    const Box2iAttribute * displayWindow = 
+    src.findTypedAttribute<Box2iAttribute> ("displayWindow");
+    
+    if (displayWindow)
+        dst.insert ("displayWindow", *displayWindow);
+    else 
+        dst.erase ("displayWindow");
+    
+    
+    //
+    // Pixel Aspect Ratio
+    //
+    const FloatAttribute * pixelAspectRatio = 
+    src.findTypedAttribute<FloatAttribute> ("pixelAspectRatio");
+    
+    if (pixelAspectRatio)
+        dst.insert ("pixelAspectRatio", *pixelAspectRatio);
+    else 
+        dst.erase ("pixelAspectRatio");
+    
+    
+    //
+    // Timecode
+    //
+    const TimeCodeAttribute * timeCode = 
+    src.findTypedAttribute<TimeCodeAttribute> ("timecode");
+    
+    if (timeCode)
+        dst.insert ("timecode", *timeCode);
+    else 
+        dst.erase ("timecode");
+    
+    
+    //
+    // Chromaticities
+    //
+    const ChromaticitiesAttribute * chromaticities = 
+    src.findTypedAttribute<ChromaticitiesAttribute> ("chromaticities");
+    
+    if (chromaticities)
+        dst.insert ("chromaticities", *chromaticities);
+    else 
+        dst.erase ("chromaticities");
+    
+}
+
+
+bool 
+MultiPartOutputFile::Data::checkSharedAttributesValues(const Header & src,
+        const Header & dst,
+        vector<string> & conflictingAttributes) const
+{
+    bool conflict = false;
+
+    //
+    // Display Window
+    //
+    if (src.displayWindow() != dst.displayWindow())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("displayWindow");
+    }
+
+
+    //
+    // Pixel Aspect Ratio
+    //
+    if (src.pixelAspectRatio() != dst.pixelAspectRatio())
+    {
+        conflict = true;
+        conflictingAttributes.push_back ("pixelAspectRatio");
+    }
+
+
+    //
+    // Timecode
+    //
+    const TimeCodeAttribute * srcTimeCode = src.findTypedAttribute<
+                                            TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+    const TimeCodeAttribute * dstTimeCode = dst.findTypedAttribute<
+                                            TimeCodeAttribute> (TimeCodeAttribute::staticTypeName());
+
+    if (dstTimeCode)
+    {
+        if ((srcTimeCode && (srcTimeCode->value() != dstTimeCode->value())) ||
+                (!srcTimeCode))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (TimeCodeAttribute::staticTypeName());
+        }
+    }
+
+    //
+    // Chromaticities
+    //
+    const ChromaticitiesAttribute * srcChrom =  src.findTypedAttribute<
+            ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+    const ChromaticitiesAttribute * dstChrom =  dst.findTypedAttribute<
+            ChromaticitiesAttribute> (ChromaticitiesAttribute::staticTypeName());
+
+    if (dstChrom)
+    {
+        if ( (srcChrom && (srcChrom->value() != dstChrom->value())) ||
+                (!srcChrom))
+        {
+            conflict = true;
+            conflictingAttributes.push_back (ChromaticitiesAttribute::staticTypeName());
+        }
+    }
+
+    return conflict;
+}
+                                                      
+
+void
+MultiPartOutputFile::Data::headerNameUniquenessCheck (const vector<Header> &headers)
+{
+    set<string> names;
+    for (size_t i = 0; i < headers.size(); i++)
+    {
+        if (names.find(headers[i].name()) != names.end())
+            throw IEX_NAMESPACE::ArgExc ("Each part should have a unique name.");
+        names.insert(headers[i].name());
+    }
+}
+
+void
+MultiPartOutputFile::Data::writeHeadersToFile (const vector<Header> &headers)
+{
+    for (size_t i = 0; i < headers.size(); i++)
+    {
+
+        // (TODO) consider deep files' preview images here.
+        if (headers[i].type() == TILEDIMAGE)
+            parts[i]->previewPosition = headers[i].writeTo(*os, true);
+        else
+            parts[i]->previewPosition = headers[i].writeTo(*os, false);
+    }
+
+    //
+    // If a multipart file, write zero-length attribute name to mark the end of all headers.
+    //
+
+    if (headers.size() !=1)
+         OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*os, "");
+}
+
+void
+MultiPartOutputFile::Data::writeChunkTableOffsets (vector<OutputPartData*> &parts)
+{
+    for (size_t i = 0; i < parts.size(); i++)
+    {
+        int chunkTableSize = getChunkOffsetTableSize(parts[i]->header,false);
+
+        Int64 pos = os->tellp();
+
+        if (pos == -1)
+            IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
+
+        parts[i]->chunkOffsetTablePosition = os->tellp();
+
+        //
+        // Fill in empty data for now. We'll write actual offsets during destruction.
+        //
+
+        for (int j = 0; j < chunkTableSize; j++)
+        {
+            Int64 empty = 0;
+            OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*os, empty);
+        }
+    }
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfMultiPartOutputFile.h b/3rdparty/openexr/IlmImf/ImfMultiPartOutputFile.h
new file mode 100644 (file)
index 0000000..f8269f1
--- /dev/null
@@ -0,0 +1,122 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// Portions (c) 2012 Weta Digital Ltd
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef MULTIPARTOUTPUTFILE_H_
+#define MULTIPARTOUTPUTFILE_H_
+
+#include "ImfHeader.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfForward.h"
+#include "ImfThreading.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+//
+// Class responsible for handling the writing of multipart images.
+//
+// Note: Certain attributes are 'common' to all parts. Notably:
+// * Display Window
+// * Pixel Aspect Ratio
+// * Time Code
+// * Chromaticities
+// The first header forms the basis for the set of attributes that are shared 
+// across the constituent parts.
+//
+// Parameters
+//  headers - pointer to array of headers; one for each part of the image file
+//  parts - count of number of parts
+//  overrideSharedAttributes - toggle for the handling of shared attributes.
+//                             set false to check for inconsistencies, true
+//                             to copy the values over from the first header.
+//  numThreads - number of threads that should be used in encoding the data.
+//
+    
+class MultiPartOutputFile : public GenericOutputFile
+{
+    public:
+        IMF_EXPORT
+        MultiPartOutputFile(const char fileName[],
+                            const Header * headers,
+                            int parts,
+                            bool overrideSharedAttributes = false,
+                            int numThreads = globalThreadCount());
+                            
+        IMF_EXPORT
+        MultiPartOutputFile(OStream & os,
+                            const Header * headers,
+                            int parts,
+                            bool overrideSharedAttributes = false,
+                            int numThreads = globalThreadCount());                            
+
+        //
+        // return number of parts in file
+        //
+        IMF_EXPORT
+        int parts() const;
+        
+        //
+        // return header for part n
+        // (note: may have additional attributes compared to that passed to constructor)
+        //
+        IMF_EXPORT
+        const Header & header(int n) const;
+                            
+        IMF_EXPORT
+        ~MultiPartOutputFile();
+
+        struct Data;
+
+    private:
+        Data*                           _data;
+
+        MultiPartOutputFile(const MultiPartOutputFile &); // not implemented
+        
+        template<class T>         T*  getOutputPart(int partNumber);
+
+    
+    friend class OutputPart;
+    friend class TiledOutputPart;
+    friend class DeepScanLineOutputPart;
+    friend class DeepTiledOutputPart;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* MULTIPARTOUTPUTFILE_H_ */
index 23879b7..acca3fe 100644 (file)
@@ -1,9 +1,9 @@
 ///////////////////////////////////////////////////////////////////////////
 //
 // Copyright (c) 2007, Weta Digital Ltd
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -15,8 +15,8 @@
 // distribution.
 // *       Neither the name of Weta Digital nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfMultiView.h>
 
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 StringVector
@@ -56,35 +58,35 @@ parseString (string name, char c = '.')
     StringVector r;
 
     while (name.size() > 0)
-    {
-    size_t s = name.find (c);
-    string sec = name.substr (0, s);
+    {  
+       size_t s = name.find (c);
+       string sec = name.substr (0, s);
 
-    //
-    // Strip spaces from beginning
-    //
+       //
+       // Strip spaces from beginning
+       //
 
-    while (sec.size() > 0 && sec[0] == ' ')
-        sec.erase (0, 1);
+       while (sec.size() > 0 && sec[0] == ' ')
+           sec.erase (0, 1);
 
-    //
-    // Strip spaces from end
-    //
+       //
+       // Strip spaces from end
+       //
 
-    while (sec.size() > 0 && sec[sec.size() - 1] == ' ')
-        sec.erase (sec.size() - 1);
+       while (sec.size() > 0 && sec[sec.size() - 1] == ' ')
+           sec.erase (sec.size() - 1);
 
-    r.push_back (sec);
+       r.push_back (sec);
 
-    //
-    // Strip off name including ending 'c'
-    //
+       //
+       // Strip off name including ending 'c'
+       //
 
-    if (s == name.npos)
-        name = "";
-    else
-        name = name.substr (s + 1);
-    }
+       if (s == name.npos)
+           name = "";
+       else
+           name = name.substr (s + 1);
+    } 
 
     return r;
 }
@@ -101,10 +103,10 @@ viewNum (const string &view, const StringVector &multiView)
     // otherwise, it's some other (valid) view
     //
 
-    for (int i = 0; i < multiView.size(); ++i)
+    for (size_t i = 0; i < multiView.size(); ++i)
     {
-    if (multiView[i] == view)
-        return i;
+       if (multiView[i] == view)
+           return i;
     }
 
     return -1;
@@ -117,15 +119,15 @@ string
 defaultViewName (const StringVector &multiView)
 {
     if (multiView.size() > 0)
-    return multiView[0];
+       return multiView[0];
     else
-    return "";
+       return "";
 }
 
 
 string
 viewFromChannelName (const string &channel,
-             const StringVector &multiView)
+                    const StringVector &multiView)
 {
     //
     // Given the name of a channel, return the name of the view to
@@ -139,41 +141,41 @@ viewFromChannelName (const string &channel,
     StringVector s = parseString (channel, '.');
 
     if (s.size() == 0)
-    return ""; // nothing in, nothing out
+       return ""; // nothing in, nothing out
 
     if (s.size() == 1)
     {
-    //
-    // Return default view name.
-    // The rules say ALL channels with no periods
-    // in the name belong to the default view.
-    //
+       //
+       // Return default view name.
+       // The rules say ALL channels with no periods
+       // in the name belong to the default view.
+       //
 
-    return multiView[0];
+       return multiView[0];
     }
     else
-    {
-    //
-    // size >= 2 - the last part is the channel name,
-    // the next-to-last part is the view name.
-    // Check if that part of the name really is
-    // a valid view and, if it is, return it.
-    //
-
-    const string &viewName = s[s.size() - 2];
-
-    if (viewNum (viewName, multiView) >= 0)
-        return viewName;
-    else
-        return ""; // not associated with any particular view
+    { 
+       //
+       // size >= 2 - the last part is the channel name,
+       // the next-to-last part is the view name.
+       // Check if that part of the name really is
+       // a valid view and, if it is, return it.
+       //
+
+       const string &viewName = s[s.size() - 2];
+
+       if (viewNum (viewName, multiView) >= 0)
+           return viewName;
+       else
+           return ""; // not associated with any particular view
     }
 }
 
 
 ChannelList
 channelsInView (const string & viewName,
-            const ChannelList & channelList,
-        const StringVector & multiView)
+               const ChannelList & channelList,
+               const StringVector & multiView)
 {
     //
     // Return a list of all channels belonging to view viewName.
@@ -182,22 +184,22 @@ channelsInView (const string & viewName,
     ChannelList q;
 
     for (ChannelList::ConstIterator i = channelList.begin();
-     i != channelList.end();
-     ++i)
+        i != channelList.end();
+        ++i)
     {
-    //
-    // Get view name for this channel
-    //
+       //
+       // Get view name for this channel
+       //
 
-    string view = viewFromChannelName (i.name(), multiView);
+       string view = viewFromChannelName (i.name(), multiView);
 
 
-    //
-    // Insert channel into q if it's a member of view viewName
-    //
+       //
+       // Insert channel into q if it's a member of view viewName
+       //
 
-    if (view == viewName)
-       q.insert (i.name(), i.channel());
+       if (view == viewName)
+          q.insert (i.name(), i.channel());
     }
 
     return q;
@@ -206,21 +208,21 @@ channelsInView (const string & viewName,
 
 ChannelList
 channelsInNoView (const ChannelList &channelList,
-          const StringVector &multiView)
+                 const StringVector &multiView)
 {
     //
     // Return a list of channels not associated with any named view.
     //
 
-    return channelsInView ("", channelList, multiView);
+    return channelsInView ("", channelList, multiView); 
 }
 
 
 
 bool
-areCounterparts (const string &channel1,
-             const string &channel2,
-         const StringVector &multiView)
+areCounterparts (const string &channel1, 
+                const string &channel2,
+                const StringVector &multiView)
 {
     //
     // Given two channels, return true if they are the same
@@ -228,55 +230,55 @@ areCounterparts (const string &channel1,
     //
 
     StringVector chan1 = parseString (channel1);
-    unsigned int size1 = chan1.size(); // number of SECTIONS in string
-                        // name (not string length)
+    size_t size1 = chan1.size();       // number of SECTIONS in string
+                                       // name (not string length)
 
     StringVector chan2 = parseString (channel2);
-    unsigned int size2 = chan2.size();
+    size_t size2 = chan2.size();
 
     if (size1 == 0 || size2 == 0)
-    return false;
-
+       return false;
+     
     //
     // channel1 and channel2 can't be counterparts
     // if either channel is in no view.
     //
 
     if (size1 > 1 && viewNum (chan1[size1 - 2], multiView) == -1)
-    return false;
+       return false;
 
     if (size2 > 1 && viewNum (chan2[size2 - 2], multiView) == -1)
-    return false;
+       return false; 
 
     if (viewFromChannelName (channel1, multiView) ==
-    viewFromChannelName (channel2, multiView))
+       viewFromChannelName (channel2, multiView))
     {
-    //
-    // channel1 and channel2 are not counterparts
-    // if they are in the same view.
-    //
+       //
+       // channel1 and channel2 are not counterparts
+       // if they are in the same view.
+       //
 
-    return false;
+       return false;
     }
 
     if (size1 == 1)
-    {
-    //
-    // channel1 is a default channel - the channels will only be
-    // counterparts if channel2 is of the form <view>.<channel1>
-    //
+    { 
+       //
+       // channel1 is a default channel - the channels will only be
+       // counterparts if channel2 is of the form <view>.<channel1>
+       //
 
-    return size2 == 2 && chan1[0] == chan2[1];
+       return size2 == 2 && chan1[0] == chan2[1];
     }
 
     if (size2 == 1)
     {
-    //
-    // channel2 is a default channel - the channels will only be
-    // counterparts if channel1 is of the form <view>.<channel2>
-    //
+       //
+       // channel2 is a default channel - the channels will only be
+       // counterparts if channel1 is of the form <view>.<channel2>
+       //
 
-    return size1 == 2 && chan2[0] == chan1[1];
+       return size1 == 2 && chan2[0] == chan1[1];
     }
 
     //
@@ -286,12 +288,12 @@ areCounterparts (const string &channel1,
     //
 
     if (size1 != size2)
-    return false;
+       return false;
 
-    for(int i = 0; i < size1; ++i)
+    for(size_t i = 0; i < size1; ++i)
     {
-    if (i != size1 - 2 && chan1[i] != chan2[i])
-        return false;
+       if (i != size1 - 2 && chan1[i] != chan2[i])
+           return false;
     }
 
     return true;
@@ -300,8 +302,8 @@ areCounterparts (const string &channel1,
 
 ChannelList
 channelInAllViews (const string &channelName,
-           const ChannelList &channelList,
-           const StringVector &multiView)
+                  const ChannelList &channelList,
+                  const StringVector &multiView)
 {
     //
     // Given the name of a channel, return a
@@ -311,14 +313,14 @@ channelInAllViews (const string &channelName,
     ChannelList q;
 
     for (ChannelList::ConstIterator i=channelList.begin();
-     i != channelList.end();
-     ++i)
+        i != channelList.end();
+        ++i)
     {
-    if (i.name() == channelName ||
-        areCounterparts (i.name(), channelName, multiView))
-    {
-        q.insert (i.name(), i.channel());
-    }
+       if (i.name() == channelName ||
+           areCounterparts (i.name(), channelName, multiView))
+       {
+           q.insert (i.name(), i.channel());
+       }
     }
 
     return q;
@@ -327,9 +329,9 @@ channelInAllViews (const string &channelName,
 
 string
 channelInOtherView (const string &channelName,
-            const ChannelList &channelList,
-            const StringVector &multiView,
-            const string &otherViewName)
+                   const ChannelList &channelList,
+                   const StringVector &multiView,
+                   const string &otherViewName)
 {
     //
     // Given the name of a channel in one view, return the
@@ -337,14 +339,14 @@ channelInOtherView (const string &channelName,
     //
 
     for (ChannelList::ConstIterator i=channelList.begin();
-     i != channelList.end();
-     ++i)
+        i != channelList.end();
+        ++i)
     {
-    if (viewFromChannelName (i.name(), multiView) == otherViewName &&
-        areCounterparts (i.name(), channelName, multiView))
-    {
-        return i.name();
-    }
+       if (viewFromChannelName (i.name(), multiView) == otherViewName &&
+           areCounterparts (i.name(), channelName, multiView))
+       {
+           return i.name(); 
+       }
     }
 
     return "";
@@ -353,8 +355,8 @@ channelInOtherView (const string &channelName,
 
 string
 insertViewName (const string &channel,
-        const StringVector &multiView,
-        int i)
+               const StringVector &multiView,
+               int i)
 {
     //
     // Insert multiView[i] into the channel name if appropriate.
@@ -363,16 +365,16 @@ insertViewName (const string &channel,
     StringVector s = parseString (channel, '.');
 
     if (s.size() == 0)
-    return ""; // nothing in, nothing out
+       return ""; // nothing in, nothing out
 
     if (s.size() == 1 && i == 0)
     {
-    //
-    // Channel in the default view, with no periods in its name.
-    // Do not insert view name.
-    //
+       //
+       // Channel in the default view, with no periods in its name.
+       // Do not insert view name.
+       //
 
-    return channel;
+       return channel;
     }
 
     //
@@ -381,16 +383,53 @@ insertViewName (const string &channel,
 
     string newName;
 
-    for (int j = 0; j < s.size(); ++j)
+    for (size_t j = 0; j < s.size(); ++j)
     {
-    if (j < s.size() - 1)
-        newName += s[j] + ".";
-    else
-        newName += multiView[i] + "." + s[j];
+       if (j < s.size() - 1)
+           newName += s[j] + ".";
+       else
+           newName += multiView[i] + "." + s[j];
     }
 
     return newName;
 }
 
 
-} // namespace Imf
+string
+removeViewName(const string & channel,const string & view)
+{
+    StringVector s = parseString (channel, '.');
+
+    if (s.size() == 0)
+       return ""; // nothing in, nothing out
+
+    if (s.size() == 1)
+    {
+       //
+       // Channel in the default view, since no periods in its name.
+       // No viewname to remove
+       //
+
+       return channel;
+    }
+
+    string newName;
+    for( size_t j = 0 ; j < s.size() ; ++j)
+    {
+           // only add the penultimate string part
+           // if it doesn't match the view name
+           if(j+2!=s.size() || s[j]!=view)
+           {
+                  newName += s[j];
+                 if(j+1!=s.size())
+                 {
+                      newName  += ".";
+                 }
+           }
+    }
+
+    return newName;
+
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index f4df4b3..127f97d 100644 (file)
@@ -1,9 +1,9 @@
 ///////////////////////////////////////////////////////////////////////////
 //
 // Copyright (c) 2007, Weta Digital Ltd
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -15,8 +15,8 @@
 // distribution.
 // *       Neither the name of Weta Digital nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #ifndef INCLUDED_IMF_MULTIVIEW_H
 #define INCLUDED_IMF_MULTIVIEW_H
 
-#include <ImfChannelList.h>
-#include <ImfStringVectorAttribute.h>
+#include "ImfChannelList.h"
+#include "ImfStringVectorAttribute.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
 //-----------------------------------------------------------------------------
 //
@@ -80,7 +82,7 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // Return the name of the default view given a multi-view string vector,
@@ -88,6 +90,7 @@ namespace Imf {
 // vector is empty, return "".
 //
 
+IMF_EXPORT
 std::string defaultViewName (const StringVector &multiView);
 
 
@@ -97,6 +100,7 @@ std::string defaultViewName (const StringVector &multiView);
 // is not a member of any named view.
 //
 
+IMF_EXPORT
 std::string viewFromChannelName (const std::string &channel,
                                  const StringVector &multiView);
 
@@ -107,6 +111,7 @@ std::string viewFromChannelName (const std::string &channel,
 // belongs to no view or if both channels belong to the same view.)
 //
 
+IMF_EXPORT
 bool areCounterparts (const std::string &channel1,
                       const std::string &channel2,
                       const StringVector &multiView);
@@ -115,6 +120,7 @@ bool areCounterparts (const std::string &channel1,
 // Return a list of all channels belonging to view viewName.
 //
 
+IMF_EXPORT
 ChannelList channelsInView (const std::string &viewName,
                             const ChannelList &channelList,
                             const StringVector &multiView);
@@ -123,6 +129,7 @@ ChannelList channelsInView (const std::string &viewName,
 // Return a list of channels not associated with any view.
 //
 
+IMF_EXPORT
 ChannelList channelsInNoView (const ChannelList &channelList,
                               const StringVector &multiView);
 
@@ -132,6 +139,7 @@ ChannelList channelsInNoView (const ChannelList &channelList,
 // X.right.Y, X.centre.Y, etc.).
 //
 
+IMF_EXPORT
 ChannelList channelInAllViews (const std::string &channame,
                                const ChannelList &channelList,
                                const StringVector &multiView);
@@ -143,6 +151,7 @@ ChannelList channelInAllViews (const std::string &channame,
 // exist.
 //
 
+IMF_EXPORT
 std::string channelInOtherView (const std::string &channel,
                                 const ChannelList &channelList,
                                 const StringVector &multiView,
@@ -155,10 +164,24 @@ std::string channelInOtherView (const std::string &channel,
 // not insert the view name.
 //
 
+IMF_EXPORT
 std::string insertViewName (const std::string &channel,
-                const StringVector &multiView,
-                int i);
+                           const StringVector &multiView,
+                           int i);
+
+//
+// Given a channel name that does may include a view name, return
+// string without the view name. If the string does not contain
+// the view name, return the string unaltered.
+// (Will only remove the viewname if it is in the correct position 
+//  in the string)
+//
+
+IMF_EXPORT
+std::string removeViewName (const std::string &channel,
+                           const std::string &view);
+
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index f443ee7..17fa33a 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include <string.h>
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class Name
@@ -57,7 +59,9 @@ class Name
     // Constructors
     //-------------
 
+    IMF_EXPORT
     Name ();
+    IMF_EXPORT
     Name (const char text[]);
 
 
@@ -65,6 +69,7 @@ class Name
     // Assignment operator
     //--------------------
 
+    IMF_EXPORT
     Name &             operator = (const char text[]);
 
 
@@ -72,7 +77,9 @@ class Name
     // Access to the string
     //---------------------
 
+    IMF_EXPORT
     const char *       text () const           {return _text;}
+    IMF_EXPORT
     const char *       operator * () const     {return _text;}
 
     //---------------
@@ -88,8 +95,11 @@ class Name
 };
 
 
+IMF_EXPORT
 bool operator == (const Name &x, const Name &y);
+IMF_EXPORT
 bool operator != (const Name &x, const Name &y);
+IMF_EXPORT
 bool operator < (const Name &x, const Name &y);
 
 
@@ -141,6 +151,9 @@ operator < (const Name &x, const Name &y)
 }
 
 
-} // namespace IMF
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfNamespace.h b/3rdparty/openexr/IlmImf/ImfNamespace.h
new file mode 100644 (file)
index 0000000..c36a31e
--- /dev/null
@@ -0,0 +1,115 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMFNAMESPACE_H
+#define INCLUDED_IMFNAMESPACE_H
+
+//
+// The purpose of this file is to have all of the Imath symbols defined within 
+// the OPENEXR_IMF_INTERNAL_NAMESPACE namespace rather than the standard Imath
+// namespace. Those symbols are made available to client code through the 
+// OPENEXR_IMF_NAMESPACE in addition to the OPENEXR_IMF_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the OPENEXR_IMF_NAMESPACE defaults to
+// Imath and then "using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;" brings all
+// of the declarations from the OPENEXR_IMF_INTERNAL_NAMESPACE into the
+// OPENEXR_IMF_NAMESPACE.
+// This means that client code can continue to use syntax like
+// Imf::Header, but at link time it will resolve to a
+// mangled symbol based on the OPENEXR_IMF_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of Imath and
+// have it run alongside an older version in the same application, it is now
+// possible to use an internal namespace to prevent collisions between the
+// older versions of Imath symbols and the newer ones.  To do this, the
+// following could be defined at build time:
+//
+// OPENEXR_IMF_INTERNAL_NAMESPACE = Imf_v2
+//
+// This means that declarations inside Imath headers look like this (after
+// the preprocessor has done its work):
+//
+// namespace Imf_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace Imf {
+//     using namespace IMF_NAMESPACE_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the OpenEXRConfig.h file
+// for the configure time options.
+//
+#include "OpenEXRConfig.h"
+
+
+#ifndef OPENEXR_IMF_NAMESPACE
+#define OPENEXR_IMF_NAMESPACE Imf
+#endif
+
+#ifndef OPENEXR_IMF_INTERNAL_NAMESPACE
+#define OPENEXR_IMF_INTERNAL_NAMESPACE OPENEXR_IMF_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// OPENEXR_IMF_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// OPENEXR_IMF_NAMESPACE and pulls the internal symbols into the public
+// namespace.
+//
+
+namespace OPENEXR_IMF_INTERNAL_NAMESPACE {}
+namespace OPENEXR_IMF_NAMESPACE {
+     using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER namespace OPENEXR_IMF_INTERNAL_NAMESPACE {
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER namespace OPENEXR_IMF_INTERNAL_NAMESPACE {
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+
+#endif /* INCLUDED_IMFNAMESPACE_H */
index ccb37e5..4a473ef 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,8 +43,9 @@
 #include <ImfOpaqueAttribute.h>
 #include "Iex.h"
 #include <string.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 OpaqueAttribute::OpaqueAttribute (const char typeName[]):
@@ -79,22 +80,22 @@ OpaqueAttribute::typeName () const
 }
 
 
-Attribute *
+Attribute *    
 OpaqueAttribute::copy () const
 {
     return new OpaqueAttribute (*this);
 }
 
 
-void
-OpaqueAttribute::writeValueTo (OStream &os, int) const
+void   
+OpaqueAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _data, _dataSize);
 }
 
 
-void
-OpaqueAttribute::readValueFrom (IStream &is, int size, int)
+void   
+OpaqueAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     _data.resizeErase (size);
     _dataSize = size;
@@ -102,18 +103,18 @@ OpaqueAttribute::readValueFrom (IStream &is, int size, int)
 }
 
 
-void
+void   
 OpaqueAttribute::copyValueFrom (const Attribute &other)
 {
     const OpaqueAttribute *oa = dynamic_cast <const OpaqueAttribute *> (&other);
 
     if (oa == 0 || strcmp (_typeName, oa->_typeName))
     {
-    THROW (Iex::TypeExc, "Cannot copy the value of an "
-                 "image file attribute of type "
-                 "\"" << other.typeName() << "\" "
-                 "to an attribute of type "
-                 "\"" << _typeName << "\".");
+       THROW (IEX_NAMESPACE::TypeExc, "Cannot copy the value of an "
+                            "image file attribute of type "
+                            "\"" << other.typeName() << "\" "
+                            "to an attribute of type "
+                            "\"" << _typeName << "\".");
     }
 
     _data.resizeErase (oa->_dataSize);
@@ -122,4 +123,4 @@ OpaqueAttribute::copyValueFrom (const Attribute &other)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index b8593b0..9340ee9 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfArray.h>
+#include "ImfAttribute.h"
+#include "ImfArray.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class OpaqueAttribute: public Attribute
@@ -63,8 +64,11 @@ class OpaqueAttribute: public Attribute
     // Constructors and destructor
     //----------------------------
 
+    IMF_EXPORT
     OpaqueAttribute (const char typeName[]);
+    IMF_EXPORT
     OpaqueAttribute (const OpaqueAttribute &other);
+    IMF_EXPORT
     virtual ~OpaqueAttribute ();
 
 
@@ -72,13 +76,15 @@ class OpaqueAttribute: public Attribute
     // Get this attribute's type name
     //-------------------------------
 
+    IMF_EXPORT
     virtual const char *       typeName () const;
-
+    
 
     //------------------------------
     // Make a copy of this attribute
     //------------------------------
 
+    IMF_EXPORT
     virtual Attribute *                copy () const;
 
 
@@ -86,13 +92,16 @@ class OpaqueAttribute: public Attribute
     // I/O and copying
     //----------------
 
-    virtual void               writeValueTo (OStream &os,
-                          int version) const;
+    IMF_EXPORT
+    virtual void               writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                                             int version) const;
 
-    virtual void               readValueFrom (IStream &is,
-                           int size,
-                           int version);
+    IMF_EXPORT
+    virtual void               readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                              int size,
+                                              int version);
 
+    IMF_EXPORT
     virtual void               copyValueFrom (const Attribute &other);
 
 
@@ -104,11 +113,6 @@ class OpaqueAttribute: public Attribute
 };
 
 
-} // namespace Imf
-
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfOpaqueAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfOptimizedPixelReading.h b/3rdparty/openexr/IlmImf/ImfOptimizedPixelReading.h
new file mode 100644 (file)
index 0000000..d0bc857
--- /dev/null
@@ -0,0 +1,646 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Autodesk, Inc.
+// 
+// All rights reserved.
+//
+// Implementation of IIF-specific file format and speed optimizations 
+// provided by Innobec Technologies inc on behalf of Autodesk.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#pragma once
+
+#ifndef INCLUDED_IMF_OPTIMIZED_PIXEL_READING_H
+#define INCLUDED_IMF_OPTIMIZED_PIXEL_READING_H
+
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include <iostream>
+#include "ImfChannelList.h"
+#include "ImfFrameBuffer.h"
+#include "ImfStringVectorAttribute.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class OptimizationMode
+{
+public:
+
+
+    bool _optimizable;
+    int _ySampling;
+    OptimizationMode() : _optimizable(false) {}
+    
+};
+
+
+#ifdef IMF_HAVE_SSE2
+
+
+//------------------------------------------------------------------------
+// Test for SSE pointer alignemnt
+//------------------------------------------------------------------------
+EXR_FORCEINLINE
+bool
+isPointerSSEAligned (const void* EXR_RESTRICT pPointer)
+{
+    uintptr_t trailingBits = ((uintptr_t)pPointer) & 15;
+    return trailingBits == 0;
+}
+
+//------------------------------------------------------------------------
+// Load SSE from address into register
+//------------------------------------------------------------------------
+template<bool IS_ALIGNED>
+EXR_FORCEINLINE
+__m128i loadSSE (__m128i*& loadAddress)
+{
+    // throw exception :: this is not accepted
+    return _mm_loadu_si128 (loadAddress);
+}
+
+template<>
+EXR_FORCEINLINE
+__m128i loadSSE<false> (__m128i*& loadAddress)
+{
+    return _mm_loadu_si128 (loadAddress);
+}
+
+template<>
+EXR_FORCEINLINE
+__m128i loadSSE<true> (__m128i*& loadAddress)
+{
+    return _mm_load_si128 (loadAddress);
+}
+
+//------------------------------------------------------------------------
+// Store SSE from register into address
+//------------------------------------------------------------------------
+template<bool IS_ALIGNED>
+EXR_FORCEINLINE
+void storeSSE (__m128i*& storeAddress, __m128i& dataToStore)
+{
+
+}
+
+template<>
+EXR_FORCEINLINE
+void
+storeSSE<false> (__m128i*& storeAddress, __m128i& dataToStore)
+{
+    _mm_storeu_si128 (storeAddress, dataToStore);
+}
+
+template<>
+EXR_FORCEINLINE
+void
+storeSSE<true> (__m128i*& storeAddress, __m128i& dataToStore)
+{
+    _mm_stream_si128 (storeAddress, dataToStore);
+}
+
+
+
+//------------------------------------------------------------------------
+//
+// Write to RGBA
+//
+//------------------------------------------------------------------------
+
+//
+// Using SSE intrinsics
+//
+template<bool READ_PTR_ALIGNED, bool WRITE_PTR_ALIGNED>
+EXR_FORCEINLINE 
+void writeToRGBASSETemplate 
+    (__m128i*& readPtrSSERed,
+     __m128i*& readPtrSSEGreen,
+     __m128i*& readPtrSSEBlue,
+     __m128i*& readPtrSSEAlpha,
+     __m128i*& writePtrSSE,
+     const size_t& lPixelsToCopySSE)
+{
+    for (size_t i = 0; i < lPixelsToCopySSE; ++i)
+    {
+        __m128i redRegister   = loadSSE<READ_PTR_ALIGNED> (readPtrSSERed);
+        __m128i greenRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEGreen);
+        __m128i blueRegister  = loadSSE<READ_PTR_ALIGNED> (readPtrSSEBlue);
+        __m128i alphaRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEAlpha);
+
+        __m128i redGreenRegister  = _mm_unpacklo_epi16 (redRegister,
+                                                        greenRegister);
+        __m128i blueAlphaRegister = _mm_unpacklo_epi16 (blueRegister,
+                                                        alphaRegister);
+
+        __m128i pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+        __m128i pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        redGreenRegister  = _mm_unpackhi_epi16 (redRegister, greenRegister);
+        blueAlphaRegister = _mm_unpackhi_epi16 (blueRegister, alphaRegister);
+
+        pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+        pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+        
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        ++readPtrSSEAlpha;
+        ++readPtrSSEBlue;
+        ++readPtrSSEGreen;
+        ++readPtrSSERed;
+    }
+}
+
+//
+// Not using SSE intrinsics.  This is still faster than the alternative
+// because we have multiple read pointers and therefore we are able to
+// take advantage of data locality for write operations.
+//
+EXR_FORCEINLINE 
+void writeToRGBANormal (unsigned short*& readPtrRed,
+                        unsigned short*& readPtrGreen,
+                        unsigned short*& readPtrBlue,
+                        unsigned short*& readPtrAlpha,
+                        unsigned short*& writePtr,
+                        const size_t& lPixelsToCopy)
+{
+    for (size_t i = 0; i < lPixelsToCopy; ++i)
+    {
+        *(writePtr++) = *(readPtrRed++);
+        *(writePtr++) = *(readPtrGreen++);
+        *(writePtr++) = *(readPtrBlue++);
+        *(writePtr++) = *(readPtrAlpha++);
+    }
+}
+
+//
+// Determine which (template) version to use by checking whether pointers
+// are aligned
+//
+EXR_FORCEINLINE 
+void optimizedWriteToRGBA (unsigned short*& readPtrRed,
+                           unsigned short*& readPtrGreen,
+                           unsigned short*& readPtrBlue,
+                           unsigned short*& readPtrAlpha,
+                           unsigned short*& writePtr,
+                           const size_t& pixelsToCopySSE,
+                           const size_t& pixelsToCopyNormal)
+{
+    bool readPtrAreAligned = true;
+
+    readPtrAreAligned &= isPointerSSEAligned(readPtrRed);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrGreen);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrBlue);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrAlpha);
+
+    bool writePtrIsAligned = isPointerSSEAligned(writePtr);
+
+    if (!readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<false, false> ((__m128i*&)readPtrRed,
+                                              (__m128i*&)readPtrGreen,
+                                              (__m128i*&)readPtrBlue,
+                                              (__m128i*&)readPtrAlpha,
+                                              (__m128i*&)writePtr,
+                                              pixelsToCopySSE);
+    }
+    else if (!readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<false, true> ((__m128i*&)readPtrRed,
+                                             (__m128i*&)readPtrGreen,
+                                             (__m128i*&)readPtrBlue,
+                                             (__m128i*&)readPtrAlpha,
+                                             (__m128i*&)writePtr,
+                                             pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<true, false> ((__m128i*&)readPtrRed,
+                                             (__m128i*&)readPtrGreen,
+                                             (__m128i*&)readPtrBlue,
+                                             (__m128i*&)readPtrAlpha,
+                                             (__m128i*&)writePtr,
+                                             pixelsToCopySSE);
+    }
+    else if(readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBASSETemplate<true, true> ((__m128i*&)readPtrRed,
+                                            (__m128i*&)readPtrGreen,
+                                            (__m128i*&)readPtrBlue,
+                                            (__m128i*&)readPtrAlpha,
+                                            (__m128i*&)writePtr,
+                                            pixelsToCopySSE);
+    }
+
+    writeToRGBANormal (readPtrRed, readPtrGreen, readPtrBlue, readPtrAlpha,
+                       writePtr, pixelsToCopyNormal);
+}
+
+
+
+//------------------------------------------------------------------------
+//
+// Write to RGBA Fill A
+//
+//------------------------------------------------------------------------
+
+//
+// Using SSE intrinsics
+//
+template<bool READ_PTR_ALIGNED, bool WRITE_PTR_ALIGNED>
+EXR_FORCEINLINE 
+void
+writeToRGBAFillASSETemplate (__m128i*& readPtrSSERed,
+                             __m128i*& readPtrSSEGreen,
+                             __m128i*& readPtrSSEBlue,
+                             const unsigned short& alphaFillValue,
+                             __m128i*& writePtrSSE,
+                             const size_t& pixelsToCopySSE)
+{
+    const __m128i dummyAlphaRegister = _mm_set_epi16 (alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue,
+                                                      alphaFillValue);
+
+    for (size_t pixelCounter = 0; pixelCounter < pixelsToCopySSE; ++pixelCounter)
+    {
+        __m128i redRegister   = loadSSE<READ_PTR_ALIGNED> (readPtrSSERed);
+        __m128i greenRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEGreen);
+        __m128i blueRegister  = loadSSE<READ_PTR_ALIGNED> (readPtrSSEBlue);
+
+        __m128i redGreenRegister  = _mm_unpacklo_epi16 (redRegister,
+                                                        greenRegister);
+        __m128i blueAlphaRegister = _mm_unpacklo_epi16 (blueRegister,
+                                                        dummyAlphaRegister);
+
+        __m128i pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+        __m128i pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                        blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        redGreenRegister  = _mm_unpackhi_epi16 (redRegister,
+                                                greenRegister);
+        blueAlphaRegister = _mm_unpackhi_epi16 (blueRegister,
+                                                dummyAlphaRegister);
+
+        pixel12Register   = _mm_unpacklo_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+        pixel34Register   = _mm_unpackhi_epi32 (redGreenRegister,
+                                                blueAlphaRegister);
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel12Register);
+        ++writePtrSSE;
+
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, pixel34Register);
+        ++writePtrSSE;
+
+        ++readPtrSSEBlue;
+        ++readPtrSSEGreen;
+        ++readPtrSSERed;
+    }
+}
+
+//
+// Not using SSE intrinsics.  This is still faster than the alternative
+// because we have multiple read pointers and therefore we are able to
+// take advantage of data locality for write operations.
+//
+EXR_FORCEINLINE
+void
+writeToRGBAFillANormal (unsigned short*& readPtrRed,
+                        unsigned short*& readPtrGreen,
+                        unsigned short*& readPtrBlue,
+                        const unsigned short& alphaFillValue,
+                        unsigned short*& writePtr,
+                        const size_t& pixelsToCopy)
+{
+    for (size_t i = 0; i < pixelsToCopy; ++i)
+    {
+        *(writePtr++) = *(readPtrRed++);
+        *(writePtr++) = *(readPtrGreen++);
+        *(writePtr++) = *(readPtrBlue++);
+        *(writePtr++) = alphaFillValue;
+    }
+}
+
+//
+// Determine which (template) version to use by checking whether pointers
+// are aligned.
+//
+EXR_FORCEINLINE 
+void
+optimizedWriteToRGBAFillA (unsigned short*& readPtrRed,
+                           unsigned short*& readPtrGreen,
+                           unsigned short*& readPtrBlue,
+                           const unsigned short& alphaFillValue,
+                           unsigned short*& writePtr,
+                           const size_t& pixelsToCopySSE,
+                           const size_t& pixelsToCopyNormal)
+{
+    bool readPtrAreAligned = true;
+
+    readPtrAreAligned &= isPointerSSEAligned (readPtrRed);
+    readPtrAreAligned &= isPointerSSEAligned (readPtrGreen);
+    readPtrAreAligned &= isPointerSSEAligned (readPtrBlue);
+
+    bool writePtrIsAligned = isPointerSSEAligned (writePtr);
+
+    if (!readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<false, false> ((__m128i*&)readPtrRed,
+                                                   (__m128i*&)readPtrGreen,
+                                                   (__m128i*&)readPtrBlue,
+                                                   alphaFillValue,
+                                                   (__m128i*&)writePtr,
+                                                   pixelsToCopySSE);
+    }
+    else if (!readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<false, true> ((__m128i*&)readPtrRed,
+                                                  (__m128i*&)readPtrGreen,
+                                                  (__m128i*&)readPtrBlue,
+                                                  alphaFillValue,
+                                                  (__m128i*&)writePtr,
+                                                  pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<true, false> ((__m128i*&)readPtrRed,
+                                                  (__m128i*&)readPtrGreen,
+                                                  (__m128i*&)readPtrBlue,
+                                                  alphaFillValue,
+                                                  (__m128i*&)writePtr,
+                                                  pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBAFillASSETemplate<true, true> ((__m128i*&)readPtrRed,
+                                                 (__m128i*&)readPtrGreen,
+                                                 (__m128i*&)readPtrBlue,
+                                                 alphaFillValue,
+                                                 (__m128i*&)writePtr,
+                                                 pixelsToCopySSE);
+    }
+
+    writeToRGBAFillANormal (readPtrRed,
+                            readPtrGreen, readPtrBlue, alphaFillValue,
+                            writePtr, pixelsToCopyNormal);
+}
+
+
+
+//------------------------------------------------------------------------
+//
+// Write to RGB
+//
+//------------------------------------------------------------------------
+
+//
+// Using SSE intrinsics
+//
+template<bool READ_PTR_ALIGNED, bool WRITE_PTR_ALIGNED>
+EXR_FORCEINLINE 
+void
+writeToRGBSSETemplate (__m128i*& readPtrSSERed,
+                       __m128i*& readPtrSSEGreen,
+                       __m128i*& readPtrSSEBlue,
+                       __m128i*& writePtrSSE,
+                       const size_t& pixelsToCopySSE)
+{
+
+    for (size_t pixelCounter = 0; pixelCounter < pixelsToCopySSE; ++pixelCounter)
+    {
+        //
+        // Need to shuffle and unpack pointers to obtain my first register
+        // We must save 8 pixels at a time, so we must have the following three registers at the end:
+        // 1) R1 G1 B1 R2 G2 B2 R3 G3
+        // 2) B3 R4 G4 B4 R5 G5 B5 R6
+        // 3) G6 B6 R7 G7 B7 R8 G8 B8
+        //
+        __m128i redRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSERed);
+        __m128i greenRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEGreen);
+        __m128i blueRegister = loadSSE<READ_PTR_ALIGNED> (readPtrSSEBlue);
+
+        //
+        // First register: R1 G1 B1 R2 G2 B2 R3 G3
+        // Construct 2 registers and then unpack them to obtain our final result:
+        //
+        __m128i redGreenRegister  = _mm_unpacklo_epi16 (redRegister,
+                                                        greenRegister);
+        __m128i redBlueRegister   = _mm_unpacklo_epi16 (redRegister,
+                                                        blueRegister);
+        __m128i greenBlueRegister = _mm_unpacklo_epi16 (greenRegister,
+                                                        blueRegister);
+
+        // Left Part (R1 G1 B1 R2)
+        __m128i quarterRight = _mm_shufflelo_epi16 (redBlueRegister,
+                                                    _MM_SHUFFLE(3,0,2,1));
+        __m128i halfLeft     = _mm_unpacklo_epi32 (redGreenRegister,
+                                                   quarterRight);
+
+        // Right Part (G2 B2 R3 G3)
+        __m128i quarterLeft  = _mm_shuffle_epi32 (greenBlueRegister,
+                                                 _MM_SHUFFLE(3,2,0,1));
+        quarterRight         = _mm_shuffle_epi32 (redGreenRegister,
+                                                 _MM_SHUFFLE(3,0,1,2));
+        __m128i halfRight    = _mm_unpacklo_epi32 (quarterLeft, quarterRight);
+
+        __m128i fullRegister = _mm_unpacklo_epi64 (halfLeft, halfRight);
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, fullRegister);
+        ++writePtrSSE;
+
+        //
+        // Second register: B3 R4 G4 B4 R5 G5 B5 R6
+        //
+
+        // Left Part (B3, R4, G4, B4)
+        quarterLeft  = _mm_shufflehi_epi16 (redBlueRegister,
+                                            _MM_SHUFFLE(0, 3, 2, 1));
+        quarterRight = _mm_shufflehi_epi16 (greenBlueRegister,
+                                            _MM_SHUFFLE(1, 0, 3, 2));
+        halfLeft     = _mm_unpackhi_epi32 (quarterLeft, quarterRight);
+
+        // Update the registers
+        redGreenRegister  = _mm_unpackhi_epi16 (redRegister, greenRegister);
+        redBlueRegister   = _mm_unpackhi_epi16 (redRegister, blueRegister);
+        greenBlueRegister = _mm_unpackhi_epi16 (greenRegister, blueRegister);
+
+        // Right Part (R5 G5 B5 R6)
+        quarterRight = _mm_shufflelo_epi16 (redBlueRegister,
+                                            _MM_SHUFFLE(3,0,2,1));
+        halfRight    = _mm_unpacklo_epi32 (redGreenRegister, quarterRight);
+
+        fullRegister = _mm_unpacklo_epi64 (halfLeft, halfRight);
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, fullRegister);
+        ++writePtrSSE;
+
+        //
+        // Third register: G6 B6 R7 G7 B7 R8 G8 B8
+        //
+
+        // Left part (G6 B6 R7 G7)
+        quarterLeft  = _mm_shuffle_epi32 (greenBlueRegister,
+                                          _MM_SHUFFLE(3,2,0,1));
+        quarterRight = _mm_shuffle_epi32 (redGreenRegister,
+                                          _MM_SHUFFLE(3,0,1,2));
+        halfLeft     = _mm_unpacklo_epi32 (quarterLeft, quarterRight);
+
+        // Right part (B7 R8 G8 B8)
+        quarterLeft  = _mm_shufflehi_epi16 (redBlueRegister,
+                                            _MM_SHUFFLE(0, 3, 2, 1));
+        quarterRight = _mm_shufflehi_epi16 (greenBlueRegister,
+                                            _MM_SHUFFLE(1, 0, 3, 2));
+        halfRight    = _mm_unpackhi_epi32 (quarterLeft, quarterRight);
+
+        fullRegister = _mm_unpacklo_epi64 (halfLeft, halfRight);
+        storeSSE<WRITE_PTR_ALIGNED> (writePtrSSE, fullRegister);
+        ++writePtrSSE;
+
+        //
+        // Increment read pointers
+        //
+        ++readPtrSSEBlue;
+        ++readPtrSSEGreen;
+        ++readPtrSSERed;
+    }
+}
+
+//
+// Not using SSE intrinsics.  This is still faster than the alternative
+// because we have multiple read pointers and therefore we are able to
+// take advantage of data locality for write operations.
+//
+EXR_FORCEINLINE 
+void
+writeToRGBNormal (unsigned short*& readPtrRed,
+                  unsigned short*& readPtrGreen,
+                  unsigned short*& readPtrBlue,
+                  unsigned short*& writePtr,
+                  const size_t& pixelsToCopy)
+{
+    for (size_t i = 0; i < pixelsToCopy; ++i)
+    {
+        *(writePtr++) = *(readPtrRed++);
+        *(writePtr++) = *(readPtrGreen++);
+        *(writePtr++) = *(readPtrBlue++);
+    }
+}
+
+//
+// Determine which (template) version to use by checking whether pointers
+// are aligned
+//
+EXR_FORCEINLINE 
+void optimizedWriteToRGB (unsigned short*& readPtrRed,
+                          unsigned short*& readPtrGreen,
+                          unsigned short*& readPtrBlue,
+                          unsigned short*& writePtr,
+                          const size_t& pixelsToCopySSE,
+                          const size_t& pixelsToCopyNormal)
+{
+    bool readPtrAreAligned = true;
+
+    readPtrAreAligned &= isPointerSSEAligned(readPtrRed);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrGreen);
+    readPtrAreAligned &= isPointerSSEAligned(readPtrBlue);
+
+    bool writePtrIsAligned = isPointerSSEAligned(writePtr);
+
+    if (!readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<false, false> ((__m128i*&)readPtrRed,
+                                             (__m128i*&)readPtrGreen,
+                                             (__m128i*&)readPtrBlue,
+                                             (__m128i*&)writePtr,
+                                             pixelsToCopySSE);
+    }
+    else if (!readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<false, true> ((__m128i*&)readPtrRed,
+                                            (__m128i*&)readPtrGreen,
+                                            (__m128i*&)readPtrBlue,
+                                            (__m128i*&)writePtr,
+                                            pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && !writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<true, false> ((__m128i*&)readPtrRed,
+                                            (__m128i*&)readPtrGreen,
+                                            (__m128i*&)readPtrBlue,
+                                            (__m128i*&)writePtr,
+                                            pixelsToCopySSE);
+    }
+    else if (readPtrAreAligned && writePtrIsAligned)
+    {
+        writeToRGBSSETemplate<true, true> ((__m128i*&)readPtrRed,
+                                           (__m128i*&)readPtrGreen,
+                                           (__m128i*&)readPtrBlue,
+                                           (__m128i*&)writePtr,
+                                           pixelsToCopySSE);
+    }
+
+
+    writeToRGBNormal (readPtrRed, readPtrGreen, readPtrBlue,
+                      writePtr, pixelsToCopyNormal);
+}
+
+
+
+
+#else // ! defined IMF_HAVE_SSE2
+
+#endif // defined IMF_HAVE_SSE2
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
index e69b92b..ff44e66 100644 (file)
@@ -1,10 +1,14 @@
+//
+///\todo: version needs fixing!
+//
+
 ///////////////////////////////////////////////////////////////////////////
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +20,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include "ImathBox.h"
 #include "ImathFun.h"
 #include <ImfArray.h>
-#include <ImfXdr.h>
+#include "ImfXdr.h"
 #include <ImfPreviewImageAttribute.h>
+#include <ImfPartType.h>
 #include "IlmThreadPool.h"
+#include "ImfOutputStreamMutex.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
 #include "Iex.h"
+#include "ImfInputPart.h"
+#include "ImfNamespace.h"
+#include "ImfOutputPartData.h"
+
 #include <string>
 #include <vector>
 #include <fstream>
 #include <assert.h>
-#include <algorithm> // for std::max()
-
+#include <algorithm>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
 using std::string;
 using std::vector;
 using std::ofstream;
 using std::min;
 using std::max;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
+
 
 namespace {
 
@@ -92,20 +102,21 @@ struct OutSliceInfo
     bool               zero;
 
     OutSliceInfo (PixelType type = HALF,
-              const char *base = 0,
-              size_t xStride = 0,
-              size_t yStride = 0,
-              int xSampling = 1,
-              int ySampling = 1,
-              bool zero = false);
+                 const char *base = 0,
+                 size_t xStride = 0,
+                 size_t yStride = 0,
+                 int xSampling = 1,
+                 int ySampling = 1,
+                 bool zero = false);
+                  
 };
 
 
 OutSliceInfo::OutSliceInfo (PixelType t,
-                    const char *b,
-                    size_t xs, size_t ys,
-                    int xsm, int ysm,
-                    bool z)
+                           const char *b,
+                           size_t xs, size_t ys,
+                           int xsm, int ysm,
+                           bool z)
 :
     type (t),
     base (b),
@@ -166,11 +177,11 @@ LineBuffer::~LineBuffer ()
 
 } // namespace
 
-
-struct OutputFile::Data: public Mutex
+struct OutputFile::Data
 {
     Header              header;                // the image header
-    int                         version;               // file format version
+    bool                 multiPart;            // is the file multipart?
+    int                         version;               // version attribute \todo NOT BEING WRITTEN PROPERLY
     Int64               previewPosition;       // file position for preview
     FrameBuffer                 frameBuffer;           // framebuffer to write into
     int                         currentScanLine;       // next scanline to be written
@@ -181,38 +192,39 @@ struct OutputFile::Data: public Mutex
     int                         minY;                  // data window's min y coord
     int                         maxY;                  // data window's max x coord
     vector<Int64>       lineOffsets;           // stores offsets in file for
-                        // each scanline
+                                               // each scanline
     vector<size_t>      bytesPerLine;          // combined size of a line over
                                                 // all channels
     vector<size_t>      offsetInLineBuffer;    // offset for each scanline in
                                                 // its linebuffer
     Compressor::Format  format;                // compressor's data format
     vector<OutSliceInfo> slices;               // info about channels in file
-    OStream *           os;                    // file stream to write to
-    bool                deleteStream;
     Int64               lineOffsetsPosition;   // file position for line
                                                 // offset table
-    Int64               currentPosition;       // current file position
 
     vector<LineBuffer*>  lineBuffers;           // each holds one line buffer
     int                         linesInBuffer;         // number of scanlines each
                                                 // buffer holds
     size_t              lineBufferSize;        // size of the line buffer
 
-     Data (bool deleteStream, int numThreads);
+    int                  partNumber;            // the output part number
+    OutputStreamMutex *  _streamData;         
+    bool                 _deleteStream;
+     Data (int numThreads);
     ~Data ();
 
 
     inline LineBuffer *        getLineBuffer (int number); // hash function from line
-                                // buffer indices into our
-                            // vector of line buffers
+                                                   // buffer indices into our
+                                                   // vector of line buffers
 };
 
 
-OutputFile::Data::Data (bool deleteStream, int numThreads):
-    os (0),
-    deleteStream (deleteStream),
-    lineOffsetsPosition (0)
+OutputFile::Data::Data (int numThreads):
+    lineOffsetsPosition (0),
+    partNumber (-1),
+    _streamData(0),
+    _deleteStream(false)
 {
     //
     // We need at least one lineBuffer, but if threading is used,
@@ -225,9 +237,6 @@ OutputFile::Data::Data (bool deleteStream, int numThreads):
 
 OutputFile::Data::~Data ()
 {
-    if (deleteStream)
-    delete os;
-
     for (size_t i = 0; i < lineBuffers.size(); i++)
         delete lineBuffers[i];
 }
@@ -239,30 +248,29 @@ OutputFile::Data::getLineBuffer (int number)
     return lineBuffers[number % lineBuffers.size()];
 }
 
-
 namespace {
 
-
 Int64
-writeLineOffsets (OStream &os, const vector<Int64> &lineOffsets)
+writeLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const vector<Int64> &lineOffsets)
 {
     Int64 pos = os.tellp();
 
     if (pos == -1)
-    Iex::throwErrnoExc ("Cannot determine current file position (%T).");
-
+       IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
+    
     for (unsigned int i = 0; i < lineOffsets.size(); i++)
-    Xdr::write <StreamIO> (os, lineOffsets[i]);
+       Xdr::write<StreamIO> (os, lineOffsets[i]);
 
     return pos;
 }
 
 
 void
-writePixelData (OutputFile::Data *ofd,
+writePixelData (OutputStreamMutex *filedata,
+                OutputFile::Data *partdata,
                 int lineBufferMinY,
-        const char pixelData[],
-        int pixelDataSize)
+                const char pixelData[],
+                int pixelDataSize)
 {
     //
     // Store a block of pixel data in the output file, and try
@@ -270,39 +278,53 @@ writePixelData (OutputFile::Data *ofd,
     // without calling tellp() (tellp() can be fairly expensive).
     //
 
-    Int64 currentPosition = ofd->currentPosition;
-    ofd->currentPosition = 0;
+    Int64 currentPosition = filedata->currentPosition;
+    filedata->currentPosition = 0;
 
     if (currentPosition == 0)
-    currentPosition = ofd->os->tellp();
+        currentPosition = filedata->os->tellp();
 
-    ofd->lineOffsets[(ofd->currentScanLine - ofd->minY) / ofd->linesInBuffer] =
-    currentPosition;
+    partdata->lineOffsets[(partdata->currentScanLine - partdata->minY) / partdata->linesInBuffer] =
+        currentPosition;
 
     #ifdef DEBUG
 
-    assert (ofd->os->tellp() == currentPosition);
+        assert (filedata->os->tellp() == currentPosition);
 
     #endif
+    
+       
+       
+    if (partdata->multiPart)
+    {
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, partdata->partNumber);
+    }
+    
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, lineBufferMinY);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*filedata->os, pixelDataSize);
+    filedata->os->write (pixelData, pixelDataSize);
 
-    Xdr::write <StreamIO> (*ofd->os, lineBufferMinY);
-    Xdr::write <StreamIO> (*ofd->os, pixelDataSize);
-    ofd->os->write (pixelData, pixelDataSize);
+    filedata->currentPosition = currentPosition +
+                           Xdr::size<int>() +
+                           Xdr::size<int>() +
+                           pixelDataSize;
 
-    ofd->currentPosition = currentPosition +
-               Xdr::size<int>() +
-               Xdr::size<int>() +
-               pixelDataSize;
+    if (partdata->multiPart)
+    {
+        filedata->currentPosition += Xdr::size<int>();
+    }
 }
 
 
 inline void
-writePixelData (OutputFile::Data *ofd, const LineBuffer *lineBuffer)
+writePixelData (OutputStreamMutex* filedata,
+                OutputFile::Data *partdata,
+                const LineBuffer *lineBuffer)
 {
-    writePixelData (ofd,
-            lineBuffer->minY,
+    writePixelData (filedata, partdata,
+                    lineBuffer->minY,
                     lineBuffer->dataPtr,
-            lineBuffer->dataSize);
+                    lineBuffer->dataSize);
 }
 
 
@@ -311,7 +333,7 @@ convertToXdr (OutputFile::Data *ofd,
               Array<char> &lineBuffer,
               int lineBufferMinY,
               int lineBufferMaxY,
-              int /*inSize*/)
+              int inSize)
 {
     //
     // Convert the contents of a lineBuffer from the machine's native
@@ -326,42 +348,25 @@ convertToXdr (OutputFile::Data *ofd,
     // Xdr representation.  This makes it possible to convert the
     // pixel data in place, without an intermediate temporary buffer.
     //
-
-    int startY, endY;          // The first and last scanlines in
-                    // the file that are in the lineBuffer.
-    int step;
-
-    if (ofd->lineOrder == INCREASING_Y)
-    {
-    startY = max (lineBufferMinY, ofd->minY);
-    endY = min (lineBufferMaxY, ofd->maxY) + 1;
-        step = 1;
-    }
-    else
-    {
-    startY = min (lineBufferMaxY, ofd->maxY);
-    endY = max (lineBufferMinY, ofd->minY) - 1;
-        step = -1;
-    }
-
+   
     //
     // Iterate over all scanlines in the lineBuffer to convert.
     //
 
-    for (int y = startY; y != endY; y += step)
+    char *writePtr = &lineBuffer[0];
+    for (int y = lineBufferMinY; y <= lineBufferMaxY; y++)
     {
-    //
+       //
         // Set these to point to the start of line y.
         // We will write to writePtr from readPtr.
-    //
+       //
 
-        char *writePtr = lineBuffer + ofd->offsetInLineBuffer[y - ofd->minY];
         const char *readPtr = writePtr;
-
-    //
+        
+       //
         // Iterate over all slices in the file.
-    //
-
+       //
+       
         for (unsigned int i = 0; i < ofd->slices.size(); ++i)
         {
             //
@@ -377,17 +382,17 @@ convertToXdr (OutputFile::Data *ofd,
 
             //
             // Find the number of sampled pixels, dMaxX-dMinX+1, for
-        // slice i in scan line y (i.e. pixels within the data window
+           // slice i in scan line y (i.e. pixels within the data window
             // for which x % xSampling == 0).
             //
 
             int dMinX = divp (ofd->minX, slice.xSampling);
             int dMaxX = divp (ofd->maxX, slice.xSampling);
-
-        //
+            
+           //
             // Convert the samples in place.
-        //
-
+           //
+            
             convertInPlace (writePtr, readPtr, slice.type, dMaxX - dMinX + 1);
         }
     }
@@ -406,11 +411,11 @@ class LineBufferTask: public Task
 
     LineBufferTask (TaskGroup *group,
                     OutputFile::Data *ofd,
-            int number,
+                   int number,
                     int scanLineMin,
-            int scanLineMax);
+                   int scanLineMax);
 
-    virtual ~LineBufferTask ();
+    virtual ~LineBufferTask (); 
 
     virtual void       execute ();
 
@@ -437,7 +442,7 @@ LineBufferTask::LineBufferTask
     //
 
     _lineBuffer->wait ();
-
+    
     //
     // Initialize the lineBuffer data if necessary
     //
@@ -449,11 +454,11 @@ LineBufferTask::LineBufferTask
         _lineBuffer->minY = _ofd->minY + number * _ofd->linesInBuffer;
 
         _lineBuffer->maxY = min (_lineBuffer->minY + _ofd->linesInBuffer - 1,
-                 _ofd->maxY);
+                                _ofd->maxY);
 
         _lineBuffer->partiallyFull = true;
     }
-
+    
     _lineBuffer->scanLineMin = max (_lineBuffer->minY, scanLineMin);
     _lineBuffer->scanLineMax = min (_lineBuffer->maxY, scanLineMax);
 }
@@ -476,9 +481,9 @@ LineBufferTask::execute ()
     {
         //
         // First copy the pixel data from the
-    // frame buffer into the line buffer
+       // frame buffer into the line buffer
         //
-
+        
         int yStart, yStop, dy;
 
         if (_ofd->lineOrder == INCREASING_Y)
@@ -493,8 +498,8 @@ LineBufferTask::execute ()
             yStop = _lineBuffer->scanLineMin - 1;
             dy = -1;
         }
-
-    int y;
+    
+       int y;
 
         for (y = yStart; y != yStop; y += dy)
         {
@@ -502,7 +507,7 @@ LineBufferTask::execute ()
             // Gather one scan line's worth of pixel data and store
             // them in _ofd->lineBuffer.
             //
-
+        
             char *writePtr = _lineBuffer->buffer +
                              _ofd->offsetInLineBuffer[y - _ofd->minY];
             //
@@ -513,34 +518,34 @@ LineBufferTask::execute ()
             {
                 //
                 // Test if scan line y of this channel contains any data
-        // (the scan line contains data only if y % ySampling == 0).
+               // (the scan line contains data only if y % ySampling == 0).
                 //
-
+        
                 const OutSliceInfo &slice = _ofd->slices[i];
-
+        
                 if (modp (y, slice.ySampling) != 0)
                     continue;
-
+        
                 //
                 // Find the x coordinates of the leftmost and rightmost
                 // sampled pixels (i.e. pixels within the data window
                 // for which x % xSampling == 0).
                 //
-
+        
                 int dMinX = divp (_ofd->minX, slice.xSampling);
                 int dMaxX = divp (_ofd->maxX, slice.xSampling);
-
+        
                 //
-        // Fill the line buffer with with pixel data.
+               // Fill the line buffer with with pixel data.
                 //
-
+        
                 if (slice.zero)
                 {
                     //
                     // The frame buffer contains no data for this channel.
                     // Store zeroes in _lineBuffer->buffer.
                     //
-
+                    
                     fillChannelWithZeroes (writePtr, _ofd->format, slice.type,
                                            dMaxX - dMinX + 1);
                 }
@@ -548,51 +553,51 @@ LineBufferTask::execute ()
                 {
                     //
                     // If necessary, convert the pixel data to Xdr format.
-            // Then store the pixel data in _ofd->lineBuffer.
+                   // Then store the pixel data in _ofd->lineBuffer.
                     //
-
+        
                     const char *linePtr = slice.base +
                                           divp (y, slice.ySampling) *
                                           slice.yStride;
-
+        
                     const char *readPtr = linePtr + dMinX * slice.xStride;
                     const char *endPtr  = linePtr + dMaxX * slice.xStride;
-
+    
                     copyFromFrameBuffer (writePtr, readPtr, endPtr,
                                          slice.xStride, _ofd->format,
                                          slice.type);
                 }
             }
-
+        
             if (_lineBuffer->endOfLineBufferData < writePtr)
                 _lineBuffer->endOfLineBufferData = writePtr;
-
+        
             #ifdef DEBUG
-
+        
                 assert (writePtr - (_lineBuffer->buffer +
                         _ofd->offsetInLineBuffer[y - _ofd->minY]) ==
                         (int) _ofd->bytesPerLine[y - _ofd->minY]);
-
+        
             #endif
-
+        
         }
-
+    
         //
         // If the next scanline isn't past the bounds of the lineBuffer
         // then we are done, otherwise compress the linebuffer
         //
-
+    
         if (y >= _lineBuffer->minY && y <= _lineBuffer->maxY)
             return;
-
+    
         _lineBuffer->dataPtr = _lineBuffer->buffer;
 
         _lineBuffer->dataSize = _lineBuffer->endOfLineBufferData -
                                 _lineBuffer->buffer;
-
-    //
+    
+       //
         // Compress the data
-    //
+       //
 
         Compressor *compressor = _lineBuffer->compressor;
 
@@ -603,7 +608,7 @@ LineBufferTask::execute ()
             int compSize = compressor->compress (_lineBuffer->dataPtr,
                                                  _lineBuffer->dataSize,
                                                  _lineBuffer->minY, compPtr);
-
+    
             if (compSize < _lineBuffer->dataSize)
             {
                 _lineBuffer->dataSize = compSize;
@@ -617,7 +622,7 @@ LineBufferTask::execute ()
                 // native format, so we need to convert the lineBuffer
                 // to Xdr.
                 //
-
+    
                 convertToXdr (_ofd, _lineBuffer->buffer, _lineBuffer->minY,
                               _lineBuffer->maxY, _lineBuffer->dataSize);
             }
@@ -651,68 +656,162 @@ OutputFile::OutputFile
      const Header &header,
      int numThreads)
 :
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads))
 {
+    _data->_streamData=new OutputStreamMutex ();
+    _data->_deleteStream=true;
     try
     {
-    header.sanityCheck();
-    _data->os = new StdOFStream (fileName);
-    initialize (header);
+        header.sanityCheck();
+        _data->_streamData->os = new StdOFStream (fileName);
+        _data->multiPart=false; // only one header, not multipart
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+        
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition =
+            _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+            writeLineOffsets (*_data->_streamData->os,_data->lineOffsets);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        // ~OutputFile will not run, so free memory here
+        if (_data)
+        {
+            if (_data->_streamData)
+            {
+                delete _data->_streamData->os;
+                delete _data->_streamData;
+            }
 
-    REPLACE_EXC (e, "Cannot open image file "
-            "\"" << fileName << "\". " << e);
-    throw;
+            delete _data;
+        }
+
+       REPLACE_EXC (e, "Cannot open image file "
+                       "\"" << fileName << "\". " << e.what());
+       throw;
     }
     catch (...)
     {
-    delete _data;
+        // ~OutputFile will not run, so free memory here
+        if (_data)
+        {
+            if (_data->_streamData)
+            {
+                delete _data->_streamData->os;
+                delete _data->_streamData;
+            }
+            delete _data;
+        }
+
         throw;
     }
 }
 
 
 OutputFile::OutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      int numThreads)
 :
-    _data (new Data (false, numThreads))
+    _data (new Data (numThreads))
 {
+    _data->_streamData=new OutputStreamMutex ();
+    _data->_deleteStream=false;
     try
     {
-    header.sanityCheck();
-    _data->os = &os;
-    initialize (header);
+        header.sanityCheck();
+        _data->_streamData->os = &os;
+        _data->multiPart=false;
+        initialize (header);
+        _data->_streamData->currentPosition = _data->_streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_data->_streamData->os, _data->header);
+        _data->previewPosition =
+            _data->header.writeTo (*_data->_streamData->os);
+        _data->lineOffsetsPosition =
+            writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        // ~OutputFile will not run, so free memory here
+        if (_data)
+        {
+            if (_data->_streamData)
+                delete _data->_streamData;
+            delete _data;
+        }
 
-    REPLACE_EXC (e, "Cannot open image file "
-            "\"" << os.fileName() << "\". " << e);
-    throw;
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << os.fileName() << "\". " << e.what());
+        throw;
     }
     catch (...)
     {
-    delete _data;
+        // ~OutputFile will not run, so free memory here
+        if (_data)
+        {
+            if (_data->_streamData)
+                delete _data->_streamData;
+            delete _data;
+        }
+
         throw;
     }
 }
 
+OutputFile::OutputFile(const OutputPartData* part) : _data(NULL)
+{
+    try
+    {
+        if (part->header.type() != SCANLINEIMAGE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a OutputFile from a type-mismatched part.");
+
+        _data = new Data (part->numThreads);
+        _data->_streamData = part->mutex;
+        _data->_deleteStream=false;
+        _data->multiPart=part->multipart;
+
+        initialize (part->header);
+        _data->partNumber = part->partNumber;
+        _data->lineOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        if (_data) delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                     "\"" << part->partNumber << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        if (_data) delete _data;
+
+        throw;
+    }
+}
 
 void
 OutputFile::initialize (const Header &header)
 {
     _data->header = header;
 
+    // "fix" the type if it happens to be set incorrectly
+    // (attribute is optional, but ensure it is correct if it exists)
+    if(_data->header.hasType())
+    {
+        _data->header.setType(SCANLINEIMAGE);
+    }
+    
     const Box2i &dataWindow = header.dataWindow();
 
     _data->currentScanLine = (header.lineOrder() == INCREASING_Y)?
-                 dataWindow.min.y: dataWindow.max.y;
+                                dataWindow.min.y: dataWindow.max.y;
 
     _data->missingScanLines = dataWindow.max.y - dataWindow.min.y + 1;
     _data->lineOrder = header.lineOrder();
@@ -722,14 +821,14 @@ OutputFile::initialize (const Header &header)
     _data->maxY = dataWindow.max.y;
 
     size_t maxBytesPerLine = bytesPerLineTable (_data->header,
-                        _data->bytesPerLine);
+                                               _data->bytesPerLine);
 
     for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
     {
         _data->lineBuffers[i] =
-        new LineBuffer (newCompressor (_data->header.compression(),
-                       maxBytesPerLine,
-                       _data->header));
+           new LineBuffer (newCompressor (_data->header.compression(),
+                                          maxBytesPerLine,
+                                          _data->header));
     }
 
     LineBuffer *lineBuffer = _data->lineBuffers[0];
@@ -741,21 +840,14 @@ OutputFile::initialize (const Header &header)
         _data->lineBuffers[i]->buffer.resizeErase(_data->lineBufferSize);
 
     int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
-              _data->linesInBuffer) / _data->linesInBuffer;
+                         _data->linesInBuffer) / _data->linesInBuffer;
 
     _data->lineOffsets.resize (lineOffsetSize);
-
+    
+    
     offsetInLineBufferTable (_data->bytesPerLine,
-                 _data->linesInBuffer,
-                 _data->offsetInLineBuffer);
-
-    _data->previewPosition =
-    _data->header.writeTo (*_data->os);
-
-    _data->lineOffsetsPosition =
-    writeLineOffsets (*_data->os, _data->lineOffsets);
-
-    _data->currentPosition = _data->os->tellp();
+                            _data->linesInBuffer,
+                            _data->offsetInLineBuffer);
 }
 
 
@@ -764,12 +856,20 @@ OutputFile::~OutputFile ()
     if (_data)
     {
         {
+            Lock lock(*_data->_streamData);
+            Int64 originalPosition = _data->_streamData->os->tellp();
+
             if (_data->lineOffsetsPosition > 0)
             {
                 try
                 {
-                    _data->os->seekp (_data->lineOffsetsPosition);
-                    writeLineOffsets (*_data->os, _data->lineOffsets);
+                    _data->_streamData->os->seekp (_data->lineOffsetsPosition);
+                    writeLineOffsets (*_data->_streamData->os, _data->lineOffsets);
+
+                    //
+                    // Restore the original position.
+                    //
+                    _data->_streamData->os->seekp (originalPosition);
                 }
                 catch (...)
                 {
@@ -783,15 +883,22 @@ OutputFile::~OutputFile ()
             }
         }
 
-    delete _data;
+        if (_data->_deleteStream && _data->_streamData)
+            delete _data->_streamData->os;
+
+        if (_data->partNumber == -1 && _data->_streamData)
+            delete _data->_streamData;
+
+       delete _data;
     }
+
 }
 
 
 const char *
 OutputFile::fileName () const
 {
-    return _data->os->fileName();
+    return _data->_streamData->os->fileName();
 }
 
 
@@ -802,11 +909,11 @@ OutputFile::header () const
 }
 
 
-void
+void   
 OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    Lock lock (*_data);
-
+    Lock lock (*_data->_streamData);
+    
     //
     // Check if the new frame buffer descriptor
     // is compatible with the image file header.
@@ -815,33 +922,33 @@ OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
     const ChannelList &channels = _data->header.channels();
 
     for (ChannelList::ConstIterator i = channels.begin();
-     i != channels.end();
-     ++i)
-    {
-    FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
-
-    if (j == frameBuffer.end())
-        continue;
-
-    if (i.channel().type != j.slice().type)
-    {
-        THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
-                    "of output file \"" << fileName() << "\" is "
-                    "not compatible with the frame buffer's "
-                    "pixel type.");
-    }
-
-    if (i.channel().xSampling != j.slice().xSampling ||
-        i.channel().ySampling != j.slice().ySampling)
+        i != channels.end();
+        ++i)
     {
-        THROW (Iex::ArgExc, "X and/or y subsampling factors "
-                "of \"" << i.name() << "\" channel "
-                "of output file \"" << fileName() << "\" are "
-                "not compatible with the frame buffer's "
-                "subsampling factors.");
-    }
+       FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+       if (j == frameBuffer.end())
+           continue;
+
+       if (i.channel().type != j.slice().type)
+       {
+           THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+                               "of output file \"" << fileName() << "\" is "
+                               "not compatible with the frame buffer's "
+                               "pixel type.");
+       }
+
+       if (i.channel().xSampling != j.slice().xSampling ||
+           i.channel().ySampling != j.slice().ySampling)
+       {
+           THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                               "of \"" << i.name() << "\" channel "
+                               "of output file \"" << fileName() << "\" are "
+                               "not compatible with the frame buffer's "
+                               "subsampling factors.");
+       }
     }
-
+    
     //
     // Initialize slice table for writePixels().
     //
@@ -849,40 +956,40 @@ OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
     vector<OutSliceInfo> slices;
 
     for (ChannelList::ConstIterator i = channels.begin();
-     i != channels.end();
-     ++i)
-    {
-    FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
-
-    if (j == frameBuffer.end())
-    {
-        //
-        // Channel i is not present in the frame buffer.
-        // In the file, channel i will contain only zeroes.
-        //
-
-        slices.push_back (OutSliceInfo (i.channel().type,
-                        0, // base
-                        0, // xStride,
-                        0, // yStride,
-                        i.channel().xSampling,
-                        i.channel().ySampling,
-                        true)); // zero
-    }
-    else
+        i != channels.end();
+        ++i)
     {
-        //
-        // Channel i is present in the frame buffer.
-        //
-
-        slices.push_back (OutSliceInfo (j.slice().type,
-                        j.slice().base,
-                        j.slice().xStride,
-                        j.slice().yStride,
-                        j.slice().xSampling,
-                        j.slice().ySampling,
-                        false)); // zero
-    }
+       FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+       if (j == frameBuffer.end())
+       {
+           //
+           // Channel i is not present in the frame buffer.
+           // In the file, channel i will contain only zeroes.
+           //
+
+           slices.push_back (OutSliceInfo (i.channel().type,
+                                           0, // base
+                                           0, // xStride,
+                                           0, // yStride,
+                                           i.channel().xSampling,
+                                           i.channel().ySampling,
+                                           true)); // zero
+       }
+       else
+       {
+           //
+           // Channel i is present in the frame buffer.
+           //
+
+           slices.push_back (OutSliceInfo (j.slice().type,
+                                           j.slice().base,
+                                           j.slice().xStride,
+                                           j.slice().yStride,
+                                           j.slice().xSampling,
+                                           j.slice().ySampling,
+                                           false)); // zero
+       }
     }
 
     //
@@ -897,21 +1004,21 @@ OutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 OutputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
     return _data->frameBuffer;
 }
 
 
-void
+void   
 OutputFile::writePixels (int numScanLines)
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_data->_streamData);
 
-    if (_data->slices.size() == 0)
-        throw Iex::ArgExc ("No frame buffer specified "
-                   "as pixel data source.");
+       if (_data->slices.size() == 0)
+           throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                              "as pixel data source.");
 
         //
         // Maintain two iterators:
@@ -933,37 +1040,37 @@ OutputFile::writePixels (int numScanLines)
             //
             // Create a task group for all line buffer tasks. When the
             // taskgroup goes out of scope, the destructor waits until
-        // all tasks are complete.
+           // all tasks are complete.
             //
-
+            
             TaskGroup taskGroup;
-
+            
             //
             // Determine the range of lineBuffers that intersect the scan
-        // line range.  Then add the initial compression tasks to the
-        // thread pool.  We always add in at least one task but the
-        // individual task might not do anything if numScanLines == 0.
+           // line range.  Then add the initial compression tasks to the
+           // thread pool.  We always add in at least one task but the
+           // individual task might not do anything if numScanLines == 0.
             //
-
+    
             if (_data->lineOrder == INCREASING_Y)
             {
                 int last = (_data->currentScanLine + (numScanLines - 1) -
                             _data->minY) / _data->linesInBuffer;
-
+    
                 scanLineMin = _data->currentScanLine;
                 scanLineMax = _data->currentScanLine + numScanLines - 1;
-
+    
                 int numTasks = max (min ((int)_data->lineBuffers.size(),
                                          last - first + 1),
-                    1);
+                                   1);
 
                 for (int i = 0; i < numTasks; i++)
-        {
+               {
                     ThreadPool::addGlobalTask
                         (new LineBufferTask (&taskGroup, _data, first + i,
                                              scanLineMin, scanLineMax));
-        }
-
+               }
+    
                 nextCompressBuffer = first + numTasks;
                 stop = last + 1;
                 step = 1;
@@ -972,173 +1079,173 @@ OutputFile::writePixels (int numScanLines)
             {
                 int last = (_data->currentScanLine - (numScanLines - 1) -
                             _data->minY) / _data->linesInBuffer;
-
+    
                 scanLineMax = _data->currentScanLine;
                 scanLineMin = _data->currentScanLine - numScanLines + 1;
-
+    
                 int numTasks = max (min ((int)_data->lineBuffers.size(),
                                          first - last + 1),
-                    1);
+                                   1);
 
                 for (int i = 0; i < numTasks; i++)
-        {
+               {
                     ThreadPool::addGlobalTask
                         (new LineBufferTask (&taskGroup, _data, first - i,
                                              scanLineMin, scanLineMax));
-        }
-
+               }
+    
                 nextCompressBuffer = first - numTasks;
                 stop = last - 1;
                 step = -1;
             }
-
+            
             while (true)
             {
                 if (_data->missingScanLines <= 0)
                 {
-                    throw Iex::ArgExc ("Tried to write more scan lines "
+                    throw IEX_NAMESPACE::ArgExc ("Tried to write more scan lines "
                                        "than specified by the data window.");
                 }
-
-        //
+    
+               //
                 // Wait until the next line buffer is ready to be written
-        //
+               //
 
                 LineBuffer *writeBuffer =
-            _data->getLineBuffer (nextWriteBuffer);
+                   _data->getLineBuffer (nextWriteBuffer);
 
                 writeBuffer->wait();
-
-                int numLines = writeBuffer->scanLineMax -
+                
+                int numLines = writeBuffer->scanLineMax - 
                                writeBuffer->scanLineMin + 1;
 
                 _data->missingScanLines -= numLines;
-
-        //
+    
+               //
                 // If the line buffer is only partially full, then it is
-        // not complete and we cannot write it to disk yet.
-        //
+               // not complete and we cannot write it to disk yet.
+               //
 
                 if (writeBuffer->partiallyFull)
                 {
                     _data->currentScanLine = _data->currentScanLine +
                                              step * numLines;
                     writeBuffer->post();
-
+    
                     return;
                 }
-
-        //
+    
+               //
                 // Write the line buffer
-        //
+               //
 
-                writePixelData (_data, writeBuffer);
+                writePixelData (_data->_streamData, _data, writeBuffer);
                 nextWriteBuffer += step;
 
                 _data->currentScanLine = _data->currentScanLine +
                                          step * numLines;
-
+    
                 #ifdef DEBUG
-
+    
                     assert (_data->currentScanLine ==
                             ((_data->lineOrder == INCREASING_Y) ?
                              writeBuffer->scanLineMax + 1:
                              writeBuffer->scanLineMin - 1));
-
+    
                 #endif
-
-        //
+                
+               //
                 // Release the lock on the line buffer
-        //
+               //
 
                 writeBuffer->post();
-
-        //
+                
+               //
                 // If this was the last line buffer in the scanline range
-        //
+               //
 
                 if (nextWriteBuffer == stop)
                     break;
-
-        //
+    
+               //
                 // If there are no more line buffers to compress,
                 // then only continue to write out remaining lineBuffers
-        //
+               //
 
                 if (nextCompressBuffer == stop)
                     continue;
-
-        //
+    
+               //
                 // Add nextCompressBuffer as a compression task
-        //
+               //
 
                 ThreadPool::addGlobalTask
                     (new LineBufferTask (&taskGroup, _data, nextCompressBuffer,
                                          scanLineMin, scanLineMax));
-
-        //
+                
+               //
                 // Update the next line buffer we need to compress
-        //
+               //
 
                 nextCompressBuffer += step;
             }
-
-        //
+        
+           //
             // Finish all tasks
-        //
+           //
         }
-
-    //
-    // Exeption handling:
-    //
-    // LineBufferTask::execute() may have encountered exceptions, but
-    // those exceptions occurred in another thread, not in the thread
-    // that is executing this call to OutputFile::writePixels().
-    // LineBufferTask::execute() has caught all exceptions and stored
-    // the exceptions' what() strings in the line buffers.
-    // Now we check if any line buffer contains a stored exception; if
-    // this is the case then we re-throw the exception in this thread.
-    // (It is possible that multiple line buffers contain stored
-    // exceptions.  We re-throw the first exception we find and
-    // ignore all others.)
-    //
-
-    const string *exception = 0;
-
-        for (int i = 0; i < _data->lineBuffers.size(); ++i)
-    {
+        
+       //
+       // Exeption handling:
+       //
+       // LineBufferTask::execute() may have encountered exceptions, but
+       // those exceptions occurred in another thread, not in the thread
+       // that is executing this call to OutputFile::writePixels().
+       // LineBufferTask::execute() has caught all exceptions and stored
+       // the exceptions' what() strings in the line buffers.
+       // Now we check if any line buffer contains a stored exception; if
+       // this is the case then we re-throw the exception in this thread.
+       // (It is possible that multiple line buffers contain stored
+       // exceptions.  We re-throw the first exception we find and
+       // ignore all others.)
+       //
+
+       const string *exception = 0;
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+       {
             LineBuffer *lineBuffer = _data->lineBuffers[i];
 
-        if (lineBuffer->hasException && !exception)
-        exception = &lineBuffer->exception;
+           if (lineBuffer->hasException && !exception)
+               exception = &lineBuffer->exception;
 
-        lineBuffer->hasException = false;
-    }
+           lineBuffer->hasException = false;
+       }
 
-    if (exception)
-        throw Iex::IoExc (*exception);
+       if (exception)
+           throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Failed to write pixel data to image "
-                "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Failed to write pixel data to image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
 
-int
+int    
 OutputFile::currentScanLine () const
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
     return _data->currentScanLine;
 }
 
 
-void
+void   
 OutputFile::copyPixels (InputFile &in)
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
     //
     // Check if this file's and and the InputFile's
@@ -1149,36 +1256,36 @@ OutputFile::copyPixels (InputFile &in)
     const Header &inHdr = in.header();
 
     if (inHdr.find("tiles") != inHdr.end())
-    THROW (Iex::ArgExc, "Cannot copy pixels from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\". "
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\". "
                             "The input file is tiled, but the output file is "
                             "not. Try using TiledOutputFile::copyPixels "
                             "instead.");
 
     if (!(hdr.dataWindow() == inHdr.dataWindow()))
-    THROW (Iex::ArgExc, "Cannot copy pixels from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\". "
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\". "
                             "The files have different data windows.");
 
     if (!(hdr.lineOrder() == inHdr.lineOrder()))
-    THROW (Iex::ArgExc, "Quick pixel copy from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\" failed. "
-                "The files have different line orders.");
+       THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\" failed. "
+                           "The files have different line orders.");
 
     if (!(hdr.compression() == inHdr.compression()))
-    THROW (Iex::ArgExc, "Quick pixel copy from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\" failed. "
-                "The files use different compression methods.");
+       THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\" failed. "
+                           "The files use different compression methods.");
 
     if (!(hdr.channels() == inHdr.channels()))
-    THROW (Iex::ArgExc, "Quick pixel copy from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\" failed.  "
-                "The files have different channel lists.");
+       THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\" failed.  "
+                           "The files have different channel lists.");
 
     //
     // Verify that no pixel data have been written to this file yet.
@@ -1187,11 +1294,11 @@ OutputFile::copyPixels (InputFile &in)
     const Box2i &dataWindow = hdr.dataWindow();
 
     if (_data->missingScanLines != dataWindow.max.y - dataWindow.min.y + 1)
-    THROW (Iex::LogicExc, "Quick pixel copy from image "
-                  "file \"" << in.fileName() << "\" to image "
-                  "file \"" << fileName() << "\" failed. "
-                  "\"" << fileName() << "\" already contains "
-                  "pixel data.");
+       THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
+                             "file \"" << in.fileName() << "\" to image "
+                             "file \"" << fileName() << "\" failed. "
+                             "\"" << fileName() << "\" already contains "
+                             "pixel data.");
 
     //
     // Copy the pixel data.
@@ -1199,47 +1306,55 @@ OutputFile::copyPixels (InputFile &in)
 
     while (_data->missingScanLines > 0)
     {
-    const char *pixelData;
-    int pixelDataSize;
+       const char *pixelData;
+       int pixelDataSize;
 
-    in.rawPixelData (_data->currentScanLine, pixelData, pixelDataSize);
+       in.rawPixelData (_data->currentScanLine, pixelData, pixelDataSize);
 
-    writePixelData (_data, lineBufferMinY (_data->currentScanLine,
-                               _data->minY,
-                               _data->linesInBuffer),
+        writePixelData (_data->_streamData, _data, lineBufferMinY (_data->currentScanLine,
+                                               _data->minY,
+                                               _data->linesInBuffer),
                         pixelData, pixelDataSize);
 
-    _data->currentScanLine += (_data->lineOrder == INCREASING_Y)?
-                   _data->linesInBuffer: -_data->linesInBuffer;
+       _data->currentScanLine += (_data->lineOrder == INCREASING_Y)?
+                                  _data->linesInBuffer: -_data->linesInBuffer;
 
-    _data->missingScanLines -= _data->linesInBuffer;
+       _data->missingScanLines -= _data->linesInBuffer;
     }
 }
 
 
 void
+OutputFile::copyPixels( InputPart & in)
+{
+    copyPixels(*in.file);
+}
+
+
+
+void
 OutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
     if (_data->previewPosition <= 0)
-    THROW (Iex::LogicExc, "Cannot update preview image pixels. "
-                  "File \"" << fileName() << "\" does not "
-                  "contain a preview image.");
+       THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
+                             "File \"" << fileName() << "\" does not "
+                             "contain a preview image.");
 
     //
     // Store the new pixels in the header's preview image attribute.
     //
 
     PreviewImageAttribute &pia =
-    _data->header.typedAttribute <PreviewImageAttribute> ("preview");
+       _data->header.typedAttribute <PreviewImageAttribute> ("preview");
 
     PreviewImage &pi = pia.value();
     PreviewRgba *pixels = pi.pixels();
     int numPixels = pi.width() * pi.height();
 
     for (int i = 0; i < numPixels; ++i)
-    pixels[i] = newPixels[i];
+       pixels[i] = newPixels[i];
 
     //
     // Save the current file position, jump to the position in
@@ -1247,42 +1362,42 @@ OutputFile::updatePreviewImage (const PreviewRgba newPixels[])
     // preview image, and jump back to the saved file position.
     //
 
-    Int64 savedPosition = _data->os->tellp();
+    Int64 savedPosition = _data->_streamData->os->tellp();
 
     try
     {
-    _data->os->seekp (_data->previewPosition);
-    pia.writeValueTo (*_data->os, _data->version);
-    _data->os->seekp (savedPosition);
+        _data->_streamData->os->seekp (_data->previewPosition);
+       pia.writeValueTo (*_data->_streamData->os, _data->version);
+       _data->_streamData->os->seekp (savedPosition);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Cannot update preview image pixels for "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Cannot update preview image pixels for "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
 
-void
+void   
 OutputFile::breakScanLine  (int y, int offset, int length, char c)
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
-    Int64 position =
-    _data->lineOffsets[(y - _data->minY) / _data->linesInBuffer];
+    Int64 position = 
+       _data->lineOffsets[(y - _data->minY) / _data->linesInBuffer];
 
     if (!position)
-    THROW (Iex::ArgExc, "Cannot overwrite scan line " << y << ". "
-                "The scan line has not yet been stored in "
-                "file \"" << fileName() << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "Cannot overwrite scan line " << y << ". "
+                           "The scan line has not yet been stored in "
+                           "file \"" << fileName() << "\".");
 
-    _data->currentPosition = 0;
-    _data->os->seekp (position + offset);
+    _data->_streamData->currentPosition = 0;
+    _data->_streamData->os->seekp (position + offset);
 
     for (int i = 0; i < length; ++i)
-    _data->os->write (&c, 1);
+        _data->_streamData->os->write (&c, 1);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index ed7b98b..54d8baf 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfThreading.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class InputFile;
-struct PreviewRgba;
 
-
-class OutputFile
+class OutputFile : public GenericOutputFile
 {
   public:
 
@@ -68,6 +69,7 @@ class OutputFile
     // used to write the file (see ImfThreading.h).
     //-----------------------------------------------------------
 
+    IMF_EXPORT
     OutputFile (const char fileName[], const Header &header,
                 int numThreads = globalThreadCount());
 
@@ -84,7 +86,8 @@ class OutputFile
     // used to write the file (see ImfThreading.h).
     //------------------------------------------------------------
 
-    OutputFile (OStream &os, const Header &header,
+    IMF_EXPORT
+    OutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, const Header &header,
                 int numThreads = globalThreadCount());
 
 
@@ -96,6 +99,7 @@ class OutputFile
     // an incomplete file.
     //-------------------------------------------------
 
+    IMF_EXPORT
     virtual ~OutputFile ();
 
 
@@ -103,6 +107,7 @@ class OutputFile
     // Access to the file name
     //------------------------
 
+    IMF_EXPORT
     const char *       fileName () const;
 
 
@@ -110,6 +115,7 @@ class OutputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &     header () const;
 
 
@@ -124,6 +130,7 @@ class OutputFile
     // after each call to writePixels.
     //-------------------------------------------------------
 
+    IMF_EXPORT
     void               setFrameBuffer (const FrameBuffer &frameBuffer);
 
 
@@ -131,6 +138,7 @@ class OutputFile
     // Access to the current frame buffer
     //-----------------------------------
 
+    IMF_EXPORT
     const FrameBuffer &        frameBuffer () const;
 
 
@@ -147,6 +155,7 @@ class OutputFile
     // header().dataWindow().max.y - header().dataWindow().min.y + 1.
     //-------------------------------------------------------------------
 
+    IMF_EXPORT
     void               writePixels (int numScanLines = 1);
 
 
@@ -171,6 +180,7 @@ class OutputFile
     //
     //------------------------------------------------------------------
 
+    IMF_EXPORT
     int                        currentScanLine () const;
 
 
@@ -182,7 +192,17 @@ class OutputFile
     // "lineOrder" and "channels" attributes must be the same.
     //--------------------------------------------------------------
 
+    IMF_EXPORT
     void               copyPixels (InputFile &in);
+    
+    //-------------------------------------------------------------
+    // Shortcut to copy all pixels from an InputPart into this file
+    // - equivalent to copyPixel(InputFile &in) but for multipart files
+    //---------------------------------------------------------------
+    
+    IMF_EXPORT
+    void                copyPixels (InputPart &in);
+        
 
 
     //--------------------------------------------------------------
@@ -191,7 +211,7 @@ class OutputFile
     // updatePreviewImage() supplies a new set of pixels for the
     // preview image attribute in the file's header.  If the header
     // does not contain a preview image, updatePreviewImage() throws
-    // an Iex::LogicExc.
+    // an IEX_NAMESPACE::LogicExc.
     //
     // Note: updatePreviewImage() is necessary because images are
     // often stored in a file incrementally, a few scan lines at a
@@ -203,12 +223,13 @@ class OutputFile
     //
     //--------------------------------------------------------------
 
+    IMF_EXPORT
     void               updatePreviewImage (const PreviewRgba newPixels[]);
 
 
     //---------------------------------------------------------
     // Break a scan line -- for testing and debugging only:
-    //
+    // 
     // breakScanLine(y,p,n,c) introduces an error into the
     // output file by writing n copies of character c, starting
     // p bytes from the beginning of the pixel data block that
@@ -220,6 +241,7 @@ class OutputFile
     //
     //---------------------------------------------------------
 
+    IMF_EXPORT
     void               breakScanLine  (int y, int offset, int length, char c);
 
 
@@ -227,15 +249,28 @@ class OutputFile
 
   private:
 
+    //------------------------------------------------------------
+    // Constructor -- attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    //------------------------------------------------------------
+    OutputFile (const OutputPartData* part);
+
     OutputFile (const OutputFile &);                   // not implemented
     OutputFile & operator = (const OutputFile &);      // not implemented
 
     void               initialize (const Header &header);
 
     Data *             _data;
+
+
+    friend class MultiPartOutputFile;
+    
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfOutputPart.cpp b/3rdparty/openexr/IlmImf/ImfOutputPart.cpp
new file mode 100644 (file)
index 0000000..920b4d3
--- /dev/null
@@ -0,0 +1,105 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfOutputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+OutputPart::OutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<OutputFile>(partNumber);
+}
+
+const char *
+OutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+OutputPart::header () const
+{
+    return file->header();
+}
+
+void
+OutputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+OutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+void
+OutputPart::writePixels (int numScanLines)
+{
+    file->writePixels(numScanLines);
+}
+
+int
+OutputPart::currentScanLine () const
+{
+    return file->currentScanLine();
+}
+
+void
+OutputPart::copyPixels (InputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+OutputPart::copyPixels (InputPart &in)
+{
+    file->copyPixels(in);
+}
+
+void
+OutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+void
+OutputPart::breakScanLine  (int y, int offset, int length, char c)
+{
+    file->breakScanLine(y, offset, length, c);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfOutputPart.h b/3rdparty/openexr/IlmImf/ImfOutputPart.h
new file mode 100644 (file)
index 0000000..730396b
--- /dev/null
@@ -0,0 +1,88 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFOUTPUTPART_H_
+#define IMFOUTPUTPART_H_
+
+#include "ImfMultiPartOutputFile.h"
+#include "ImfOutputFile.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+//---------------------------------------------------------------------
+// class OutputPart:
+//
+// Same interface as OutputFile. Please refer to OutputFile.
+//---------------------------------------------------------------------
+
+class OutputPart
+{
+    public:
+        IMF_EXPORT
+        OutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+        IMF_EXPORT
+        const char *        fileName () const;
+        IMF_EXPORT
+        const Header &      header () const;
+        IMF_EXPORT
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        IMF_EXPORT
+        const FrameBuffer & frameBuffer () const;
+        IMF_EXPORT
+        void                writePixels (int numScanLines = 1);
+        IMF_EXPORT
+        int                 currentScanLine () const;
+        IMF_EXPORT
+        void                copyPixels (InputFile &in);
+        IMF_EXPORT
+        void                copyPixels (InputPart &in);
+        
+        IMF_EXPORT
+        void                updatePreviewImage (const PreviewRgba newPixels[]);
+        IMF_EXPORT
+        void                breakScanLine  (int y, int offset, int length, char c);
+
+    private:
+        OutputFile* file;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFOUTPUTPART_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfOutputPartData.cpp b/3rdparty/openexr/IlmImf/ImfOutputPartData.cpp
new file mode 100644 (file)
index 0000000..b517a47
--- /dev/null
@@ -0,0 +1,52 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfOutputPartData.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+OutputPartData::OutputPartData(OutputStreamMutex* mutex, const Header &header,
+                               int partNumber, int numThreads, bool multipart):
+        header(header),
+        numThreads(numThreads),
+        partNumber(partNumber),
+        multipart(multipart),
+        mutex(mutex)
+{
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfOutputPartData.h b/3rdparty/openexr/IlmImf/ImfOutputPartData.h
new file mode 100644 (file)
index 0000000..67dcb59
--- /dev/null
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFOUTPUTPARTDATA_H_
+#define IMFOUTPUTPARTDATA_H_
+
+#include "ImfHeader.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+struct OutputPartData
+{
+    Header                  header;
+    Int64                   chunkOffsetTablePosition;
+    Int64                   previewPosition;
+    int                     numThreads;
+    int                     partNumber;
+    bool                    multipart;
+    OutputStreamMutex*      mutex;
+
+    IMF_EXPORT
+    OutputPartData(OutputStreamMutex* mutex, const Header &header,
+                   int partNumber, int numThreads, bool multipart);
+
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFOUTPUTPARTDATA_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfOutputStreamMutex.h b/3rdparty/openexr/IlmImf/ImfOutputStreamMutex.h
new file mode 100644 (file)
index 0000000..bf5e1c3
--- /dev/null
@@ -0,0 +1,70 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFOUTPUTSTREAMMUTEX_H_
+#define IMFOUTPUTSTREAMMUTEX_H_
+
+#include <vector>
+
+#include "ImfIO.h"
+#include "IlmThreadMutex.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+using ILMTHREAD_NAMESPACE::Mutex;
+
+//
+// Used to wrap OPENEXR_IMF_INTERNAL_NAMESPACE::OStream as a Mutex.
+//
+struct OutputStreamMutex : public Mutex
+{
+        OPENEXR_IMF_INTERNAL_NAMESPACE::OStream* os;
+        Int64 currentPosition;
+
+        OutputStreamMutex()
+        {
+            os = 0;
+            currentPosition = 0;
+        }
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
+
+#endif /* IMFOUTPUTSTREAMMUTEX_H_ */
diff --git a/3rdparty/openexr/IlmImf/ImfPartHelper.h b/3rdparty/openexr/IlmImf/ImfPartHelper.h
new file mode 100644 (file)
index 0000000..d55cc7b
--- /dev/null
@@ -0,0 +1,262 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Weta Digital Ltd
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Weta Digital 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMF_PARTHELPER_H
+#define INCLUDED_IMF_PARTHELPER_H
+
+//-----------------------------------------------------------------------------
+//
+//     Functions to help split channels into separate parts: provide a list of
+//      channels, with desired views. call SplitChannels to assign a part to each
+//      layer, or correct the name of the channel.
+//      Also can enumerate the parts in a file and list which parts channels are in
+//
+//      This is a good way to offer a 'create Multipart file' checkbox to the user in a
+//      write dialog box: Populate a list of MultiViewChannelName objects,
+//      call SplitChannels with whether single or multipart files are required.
+//      Then write the number of parts it specifies, using internal_name for the channel
+//      names in the ChannelList and FrameBuffer objects. There should be no need
+//      for different codepaths for single part and multipart files
+//
+//      Similarly, on reading a file as a MultiPartInputFile, use GetChannelsInMultiPartFile to
+//      enumerate all channels in the file, using internal_name in FrameBuffer objects
+//      to read the channel
+//   
+//
+//-----------------------------------------------------------------------------
+
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfMultiPartInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfStringVectorAttribute.h"
+#include "ImfStandardAttributes.h"
+#include "ImfMultiView.h"
+
+#include <string>
+#include <map>
+#include <set>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+struct MultiViewChannelName{
+  
+public:
+  std::string name;         ///< name of channel
+  std::string view;         ///< view for channel
+  
+  int part_number;          ///< part number: updated by SplitChannels
+  std::string internal_name;///< name used in headers: in singlepart mode, may contain viewname
+  
+  virtual ~MultiViewChannelName() {}
+    
+    //return layer for this channel, or "" if no layer
+    std::string getLayer() const 
+    {
+        std::size_t q=name.rfind('.');
+       if(  q==name.npos  )
+       {
+           return "";
+       }
+       return name.substr(0,q);
+    
+  }
+
+  std::string getSuffix() const
+  {
+        std::size_t q=name.rfind('.');
+       if(  q==name.npos  )
+       {
+           return name;
+       }
+       return name.substr(q+1);
+      
+  }
+  
+};
+
+
+
+//
+///\brief assigns individual channels to different parts based on their layer and view name
+///       input is an array, list, vector etc of MultiViewChannelName objects
+///       on entry, each MultiViewChannelName name/view must be set (view can be empty if not multiview)
+///
+///       if singlepart set, then on exit part_number will be zero, and internal_name will have view name inserted
+///       otherwise, each channel will be assigned to a different part based on its layer name and view name
+///
+/// @param begin pointer to first MultiViewChannelName item
+/// @param end   pointer to end of MultiViewChannelName item array
+/// @return      total number of parts required
+//
+
+template<typename T> int 
+SplitChannels(const T & begin,const T & end,bool multipart=true,const std::string & heroView="")
+{
+    if(!multipart)
+    {
+       for(T i=begin;i!=end;i++)
+       {
+           i->part_number=0;
+       
+           //does this have a view name set?
+           if(i->view=="")
+           {
+               i->internal_name=i->name;
+           }else{
+               
+               std::string lname = i->getLayer();
+          
+               // no layer, only non-hero views get view name in layer name
+       
+           
+               if(lname=="")
+               {
+                   if(i->view==heroView)
+                   {
+                       i->internal_name = i->name;
+                   }else{
+                       i->internal_name = i->view+"."+i->name;
+                   }
+               }else{
+                   i->internal_name = lname+"."+i->view+"."+i->getSuffix();
+               }
+           }
+       }
+       // single part created
+       return 1;
+    }else{
+       // step 1: extract individual layers and parts
+       // for each layer, enumerate which views are active
+       
+       std::map< std::string , std::set< std::string > > viewsInLayers;
+       for(T i=begin;i!=end;i++)
+       {
+           viewsInLayers[i->getLayer()].insert(i->view);
+       }
+       
+       // step 2: assign a part number to each layer/view
+       
+       std::map< std::pair<std::string,std::string> , int > layerToPart;
+       
+       int partCount=0;
+       
+       for(std::map< std::string , std::set< std::string > >::const_iterator layer=viewsInLayers.begin();
+           layer!=viewsInLayers.end();layer++)
+       {
+           // if this layer has a heroView, insert that first
+           bool layer_has_hero = layer->second.find(heroView)!=layer->second.end();
+           if( layer_has_hero )
+           {
+               layerToPart[ std::make_pair(layer->first,heroView) ] = partCount++;
+           }
+           
+           
+           // insert other layers which aren't the hero view
+           for(std::set< std::string >::const_iterator view=layer->second.begin();
+               view!=layer->second.end();view++)
+           {
+               if(*view!=heroView)
+               {
+                   layerToPart[ std::make_pair(layer->first,*view) ] = partCount++;
+               }
+           }
+               
+       }
+       
+       // step 3: update part number of each provided channel
+       
+       for( T i=begin;i!=end;i++)
+       {
+           i->internal_name=i->name;
+           i->part_number = layerToPart[ std::make_pair(i->getLayer(),i->view) ];
+       }
+       
+       
+       // return number of parts created
+       return partCount;
+    }
+}
+
+//
+// populate the chans vector<MultiViewChannelName> with a list of channels in the file
+// and their corresponding part number
+//
+template<class T> void
+GetChannelsInMultiPartFile(const MultiPartInputFile & file,T & chans)
+{
+    bool has_multiview=false;
+    StringVector mview; 
+    if(file.parts()==1)
+    {
+       if(hasMultiView(file.header(0)))
+       {
+           mview=multiView(file.header(0));
+           has_multiview=true;
+       }
+    }
+    
+    for(int p=0;p<file.parts();p++)
+    {
+       const ChannelList & c=file.header(p).channels();
+       
+       std::string view="";
+       if(file.header(p).hasView())
+       {
+           view=file.header(p).view();
+       }
+       for(ChannelList::ConstIterator i=c.begin();i!=c.end();i++)
+       {
+           MultiViewChannelName m;
+            m.name=std::string(i.name());
+           m.internal_name=m.name;
+
+           if(has_multiview)
+           {
+               m.view=viewFromChannelName(m.name,mview);
+               m.name=removeViewName(m.internal_name,m.view);
+           }else{
+               m.view=view;
+           }
+            m.part_number=p;
+           chans.push_back(m);
+               
+       }
+    }
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmImf/ImfPartType.cpp b/3rdparty/openexr/IlmImf/ImfPartType.cpp
new file mode 100644 (file)
index 0000000..2856d44
--- /dev/null
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include <ImfPartType.h>
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using std::string;
+
+bool isImage(const string& name)
+{
+    return (name == SCANLINEIMAGE || name == TILEDIMAGE);
+}
+
+bool isTiled(const string& name)
+{
+    return (name == TILEDIMAGE || name == DEEPTILE);
+}
+
+bool isDeepData(const string& name)
+{
+    return (name == DEEPTILE || name == DEEPSCANLINE);
+}
+
+bool isSupportedType(const string& name)
+{
+    return (name == SCANLINEIMAGE || name == TILEDIMAGE ||
+            name == DEEPSCANLINE || name == DEEPTILE);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfPartType.h b/3rdparty/openexr/IlmImf/ImfPartType.h
new file mode 100644 (file)
index 0000000..423bce0
--- /dev/null
@@ -0,0 +1,62 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFPARTTYPE_H_
+#define IMFPARTTYPE_H_
+
+#include <string>
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+const std::string SCANLINEIMAGE = "scanlineimage";
+const std::string TILEDIMAGE    = "tiledimage";
+const std::string DEEPSCANLINE  = "deepscanline";
+const std::string DEEPTILE      = "deeptile";
+
+IMF_EXPORT bool isImage(const std::string& name);
+
+IMF_EXPORT bool isTiled(const std::string& name);
+
+IMF_EXPORT bool isDeepData(const std::string& name);
+
+IMF_EXPORT bool isSupportedType(const std::string& name);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif /* IMFPARTTYPE_H_ */
index 468e807..4b8005e 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 enum PixelType
 {
-    UINT  = 0,         // unsigned int (32 bit)
-    HALF  = 1,         // half (16 bit floating point)
-    FLOAT = 2,         // float (32 bit floating point)
+    UINT   = 0,                // unsigned int (32 bit)
+    HALF   = 1,                // half (16 bit floating point)
+    FLOAT  = 2,                // float (32 bit floating point)
 
     NUM_PIXELTYPES     // number of different pixel types
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index b0c0bb2..8b3ee38 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfPizCompressor.h>
-#include <ImfHeader.h>
-#include <ImfChannelList.h>
-#include <ImfHuf.h>
-#include <ImfWav.h>
-#include <ImfMisc.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfPizCompressor.h"
+#include "ImfHeader.h"
+#include "ImfChannelList.h"
+#include "ImfHuf.h"
+#include "ImfWav.h"
+#include "ImfMisc.h"
+#include "ImfCheckedArithmetic.h"
 #include <ImathFun.h>
 #include <ImathBox.h>
 #include <Iex.h>
-#include <ImfIO.h>
-#include <ImfXdr.h>
-#include <ImfAutoArray.h>
+#include "ImfIO.h"
+#include "ImfXdr.h"
+#include "ImfAutoArray.h"
 #include <string.h>
 #include <assert.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::divp;
-using Imath::modp;
-using Imath::Box2i;
-using Imath::V2i;
-using Iex::InputExc;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
+using IEX_NAMESPACE::InputExc;
 
 namespace {
 
@@ -74,48 +75,48 @@ const int BITMAP_SIZE  = (USHORT_RANGE >> 3);
 
 void
 bitmapFromData (const unsigned short data[/*nData*/],
-        int nData,
-        unsigned char bitmap[BITMAP_SIZE],
-        unsigned short &minNonZero,
-        unsigned short &maxNonZero)
+               int nData,
+               unsigned char bitmap[BITMAP_SIZE],
+               unsigned short &minNonZero,
+               unsigned short &maxNonZero)
 {
     for (int i = 0; i < BITMAP_SIZE; ++i)
-    bitmap[i] = 0;
+       bitmap[i] = 0;
 
     for (int i = 0; i < nData; ++i)
-    bitmap[data[i] >> 3] |= (1 << (data[i] & 7));
+       bitmap[data[i] >> 3] |= (1 << (data[i] & 7));
 
     bitmap[0] &= ~1;                   // zero is not explicitly stored in
-                    // the bitmap; we assume that the
-                    // data always contain zeroes
+                                       // the bitmap; we assume that the
+                                       // data always contain zeroes
     minNonZero = BITMAP_SIZE - 1;
     maxNonZero = 0;
 
     for (int i = 0; i < BITMAP_SIZE; ++i)
     {
-    if (bitmap[i])
-    {
-        if (minNonZero > i)
-        minNonZero = i;
-        if (maxNonZero < i)
-        maxNonZero = i;
-    }
+       if (bitmap[i])
+       {
+           if (minNonZero > i)
+               minNonZero = i;
+           if (maxNonZero < i)
+               maxNonZero = i;
+       }
     }
 }
 
 
 unsigned short
 forwardLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE],
-              unsigned short lut[USHORT_RANGE])
+                     unsigned short lut[USHORT_RANGE])
 {
     int k = 0;
 
     for (int i = 0; i < USHORT_RANGE; ++i)
     {
-    if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
-        lut[i] = k++;
-    else
-        lut[i] = 0;
+       if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
+           lut[i] = k++;
+       else
+           lut[i] = 0;
     }
 
     return k - 1;      // maximum value stored in lut[],
@@ -124,20 +125,20 @@ forwardLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE],
 
 unsigned short
 reverseLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE],
-              unsigned short lut[USHORT_RANGE])
+                     unsigned short lut[USHORT_RANGE])
 {
     int k = 0;
 
     for (int i = 0; i < USHORT_RANGE; ++i)
     {
-    if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
-        lut[k++] = i;
+       if ((i == 0) || (bitmap[i >> 3] & (1 << (i & 7))))
+           lut[k++] = i;
     }
 
     int n = k - 1;
 
     while (k < USHORT_RANGE)
-    lut[k++] = 0;
+       lut[k++] = 0;
 
     return n;          // maximum k where lut[k] is non-zero,
 }                      // i.e. number of ones in bitmap minus 1
@@ -145,11 +146,11 @@ reverseLutFromBitmap (const unsigned char bitmap[BITMAP_SIZE],
 
 void
 applyLut (const unsigned short lut[USHORT_RANGE],
-      unsigned short data[/*nData*/],
-      int nData)
+         unsigned short data[/*nData*/],
+         int nData)
 {
     for (int i = 0; i < nData; ++i)
-    data[i] = lut[data[i]];
+       data[i] = lut[data[i]];
 }
 
 
@@ -198,15 +199,15 @@ PizCompressor::PizCompressor
     bool onlyHalfChannels = true;
 
     for (ChannelList::ConstIterator c = channels.begin();
-     c != channels.end();
-     ++c)
+        c != channels.end();
+        ++c)
     {
-    _numChans++;
+       _numChans++;
 
-    assert (pixelTypeSize (c.channel().type) % pixelTypeSize (HALF) == 0);
+       assert (pixelTypeSize (c.channel().type) % pixelTypeSize (HALF) == 0);
 
-    if (c.channel().type != HALF)
-        onlyHalfChannels = false;
+       if (c.channel().type != HALF)
+           onlyHalfChannels = false;
     }
 
     _channelData = new ChannelData[_numChans];
@@ -224,7 +225,7 @@ PizCompressor::PizCompressor
     //
 
     if (onlyHalfChannels && (sizeof (half) == pixelTypeSize (HALF)))
-    _format = NATIVE;
+       _format = NATIVE;
 }
 
 
@@ -252,23 +253,23 @@ PizCompressor::format () const
 
 int
 PizCompressor::compress (const char *inPtr,
-             int inSize,
-             int minY,
-             const char *&outPtr)
+                        int inSize,
+                        int minY,
+                        const char *&outPtr)
 {
     return compress (inPtr,
-             inSize,
-             Box2i (V2i (_minX, minY),
-                V2i (_maxX, minY + numScanLines() - 1)),
-             outPtr);
+                    inSize,
+                    Box2i (V2i (_minX, minY),
+                           V2i (_maxX, minY + numScanLines() - 1)),
+                    outPtr);
 }
 
 
 int
 PizCompressor::compressTile (const char *inPtr,
-                 int inSize,
-                 Imath::Box2i range,
-                 const char *&outPtr)
+                            int inSize,
+                            IMATH_NAMESPACE::Box2i range,
+                            const char *&outPtr)
 {
     return compress (inPtr, inSize, range, outPtr);
 }
@@ -276,23 +277,23 @@ PizCompressor::compressTile (const char *inPtr,
 
 int
 PizCompressor::uncompress (const char *inPtr,
-               int inSize,
-               int minY,
-               const char *&outPtr)
+                          int inSize,
+                          int minY,
+                          const char *&outPtr)
 {
     return uncompress (inPtr,
-               inSize,
-               Box2i (V2i (_minX, minY),
-                  V2i (_maxX, minY + numScanLines() - 1)),
-               outPtr);
+                      inSize,
+                      Box2i (V2i (_minX, minY),
+                             V2i (_maxX, minY + numScanLines() - 1)),
+                      outPtr);
 }
 
 
 int
 PizCompressor::uncompressTile (const char *inPtr,
-                   int inSize,
-                   Imath::Box2i range,
-                   const char *&outPtr)
+                              int inSize,
+                              IMATH_NAMESPACE::Box2i range,
+                              const char *&outPtr)
 {
     return uncompress (inPtr, inSize, range, outPtr);
 }
@@ -300,9 +301,9 @@ PizCompressor::uncompressTile (const char *inPtr,
 
 int
 PizCompressor::compress (const char *inPtr,
-             int inSize,
-             Imath::Box2i range,
-             const char *&outPtr)
+                        int inSize,
+                        IMATH_NAMESPACE::Box2i range,
+                        const char *&outPtr)
 {
     //
     // This is the compress function which is used by both the tiled and
@@ -310,13 +311,13 @@ PizCompressor::compress (const char *inPtr,
     //
 
     //
-    // Special case Â­- empty input buffer
+    // Special case ï¿½- empty input buffer
     //
 
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
+       outPtr = _outBuffer;
+       return 0;
     }
 
     //
@@ -333,10 +334,10 @@ PizCompressor::compress (const char *inPtr,
     int maxX = range.max.x;
     int minY = range.min.y;
     int maxY = range.max.y;
-
+    
     if (maxY > _maxY)
         maxY = _maxY;
-
+    
     if (maxX > _maxX)
         maxX = _maxX;
 
@@ -344,75 +345,75 @@ PizCompressor::compress (const char *inPtr,
     int i = 0;
 
     for (ChannelList::ConstIterator c = _channels.begin();
-     c != _channels.end();
-     ++c, ++i)
+        c != _channels.end();
+        ++c, ++i)
     {
-    ChannelData &cd = _channelData[i];
+       ChannelData &cd = _channelData[i];
 
-    cd.start = tmpBufferEnd;
-    cd.end = cd.start;
+       cd.start = tmpBufferEnd;
+       cd.end = cd.start;
 
-    cd.nx = numSamples (c.channel().xSampling, minX, maxX);
-    cd.ny = numSamples (c.channel().ySampling, minY, maxY);
-    cd.ys = c.channel().ySampling;
+       cd.nx = numSamples (c.channel().xSampling, minX, maxX);
+       cd.ny = numSamples (c.channel().ySampling, minY, maxY);
+       cd.ys = c.channel().ySampling;
 
-    cd.size = pixelTypeSize (c.channel().type) / pixelTypeSize (HALF);
+       cd.size = pixelTypeSize (c.channel().type) / pixelTypeSize (HALF);
 
-    tmpBufferEnd += cd.nx * cd.ny * cd.size;
+       tmpBufferEnd += cd.nx * cd.ny * cd.size;
     }
 
     if (_format == XDR)
     {
-    //
-    // Machine-independent (Xdr) data format
-    //
-
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        for (int x = cd.nx * cd.size; x > 0; --x)
-        {
-            Xdr::read <CharPtrIO> (inPtr, *cd.end);
-            ++cd.end;
-        }
-        }
-    }
+       //
+       // Machine-independent (Xdr) data format
+       //
+
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               for (int x = cd.nx * cd.size; x > 0; --x)
+               {
+                   Xdr::read <CharPtrIO> (inPtr, *cd.end);
+                   ++cd.end;
+               }
+           }
+       }
     }
     else
     {
-    //
-    // Native, machine-dependent data format
-    //
-
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        int n = cd.nx * cd.size;
-        memcpy (cd.end, inPtr, n * sizeof (unsigned short));
-        inPtr  += n * sizeof (unsigned short);
-        cd.end += n;
-        }
-    }
+       //
+       // Native, machine-dependent data format
+       //
+
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               int n = cd.nx * cd.size;
+               memcpy (cd.end, inPtr, n * sizeof (unsigned short));
+               inPtr  += n * sizeof (unsigned short);
+               cd.end += n;
+           }
+       }
     }
 
     #if defined (DEBUG)
 
-    for (int i = 1; i < _numChans; ++i)
-        assert (_channelData[i-1].end == _channelData[i].start);
+       for (int i = 1; i < _numChans; ++i)
+           assert (_channelData[i-1].end == _channelData[i].start);
 
-    assert (_channelData[_numChans-1].end == tmpBufferEnd);
+       assert (_channelData[_numChans-1].end == tmpBufferEnd);
 
     #endif
 
@@ -425,9 +426,9 @@ PizCompressor::compress (const char *inPtr,
     unsigned short maxNonZero;
 
     bitmapFromData (_tmpBuffer,
-            tmpBufferEnd - _tmpBuffer,
-            bitmap,
-            minNonZero, maxNonZero);
+                   tmpBufferEnd - _tmpBuffer,
+                   bitmap,
+                   minNonZero, maxNonZero);
 
     AutoArray <unsigned short, USHORT_RANGE> lut;
     unsigned short maxValue = forwardLutFromBitmap (bitmap, lut);
@@ -444,8 +445,8 @@ PizCompressor::compress (const char *inPtr,
 
     if (minNonZero <= maxNonZero)
     {
-    Xdr::write <CharPtrIO> (buf, (char *) &bitmap[0] + minNonZero,
-                maxNonZero - minNonZero + 1);
+       Xdr::write <CharPtrIO> (buf, (char *) &bitmap[0] + minNonZero,
+                               maxNonZero - minNonZero + 1);
     }
 
     //
@@ -454,15 +455,15 @@ PizCompressor::compress (const char *inPtr,
 
     for (int i = 0; i < _numChans; ++i)
     {
-    ChannelData &cd = _channelData[i];
-
-    for (int j = 0; j < cd.size; ++j)
-    {
-        wav2Encode (cd.start + j,
-            cd.nx, cd.size,
-            cd.ny, cd.nx * cd.size,
-            maxValue);
-    }
+       ChannelData &cd = _channelData[i];
+
+       for (int j = 0; j < cd.size; ++j)
+       {
+           wav2Encode (cd.start + j,
+                       cd.nx, cd.size,
+                       cd.ny, cd.nx * cd.size,
+                       maxValue);
+       }
     }
 
     //
@@ -482,23 +483,23 @@ PizCompressor::compress (const char *inPtr,
 
 int
 PizCompressor::uncompress (const char *inPtr,
-               int inSize,
-               Imath::Box2i range,
-               const char *&outPtr)
+                          int inSize,
+                          IMATH_NAMESPACE::Box2i range,
+                          const char *&outPtr)
 {
     //
     // This is the cunompress function which is used by both the tiled and
     // scanline decompression routines.
     //
-
+    
     //
     // Special case - empty input buffer
     //
 
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
+       outPtr = _outBuffer;
+       return 0;
     }
 
     //
@@ -509,10 +510,10 @@ PizCompressor::uncompress (const char *inPtr,
     int maxX = range.max.x;
     int minY = range.min.y;
     int maxY = range.max.y;
-
+    
     if (maxY > _maxY)
         maxY = _maxY;
-
+    
     if (maxX > _maxX)
         maxX = _maxX;
 
@@ -520,21 +521,21 @@ PizCompressor::uncompress (const char *inPtr,
     int i = 0;
 
     for (ChannelList::ConstIterator c = _channels.begin();
-     c != _channels.end();
-     ++c, ++i)
+        c != _channels.end();
+        ++c, ++i)
     {
-    ChannelData &cd = _channelData[i];
+       ChannelData &cd = _channelData[i];
 
-    cd.start = tmpBufferEnd;
-    cd.end = cd.start;
+       cd.start = tmpBufferEnd;
+       cd.end = cd.start;
 
-    cd.nx = numSamples (c.channel().xSampling, minX, maxX);
-    cd.ny = numSamples (c.channel().ySampling, minY, maxY);
-    cd.ys = c.channel().ySampling;
+       cd.nx = numSamples (c.channel().xSampling, minX, maxX);
+       cd.ny = numSamples (c.channel().ySampling, minY, maxY);
+       cd.ys = c.channel().ySampling;
 
-    cd.size = pixelTypeSize (c.channel().type) / pixelTypeSize (HALF);
+       cd.size = pixelTypeSize (c.channel().type) / pixelTypeSize (HALF);
 
-    tmpBufferEnd += cd.nx * cd.ny * cd.size;
+       tmpBufferEnd += cd.nx * cd.ny * cd.size;
     }
 
     //
@@ -552,14 +553,14 @@ PizCompressor::uncompress (const char *inPtr,
 
     if (maxNonZero >= BITMAP_SIZE)
     {
-    throw InputExc ("Error in header for PIZ-compressed data "
-            "(invalid bitmap size).");
+       throw InputExc ("Error in header for PIZ-compressed data "
+                       "(invalid bitmap size).");
     }
 
     if (minNonZero <= maxNonZero)
     {
-    Xdr::read <CharPtrIO> (inPtr, (char *) &bitmap[0] + minNonZero,
-                   maxNonZero - minNonZero + 1);
+       Xdr::read <CharPtrIO> (inPtr, (char *) &bitmap[0] + minNonZero,
+                              maxNonZero - minNonZero + 1);
     }
 
     AutoArray <unsigned short, USHORT_RANGE> lut;
@@ -572,6 +573,12 @@ PizCompressor::uncompress (const char *inPtr,
     int length;
     Xdr::read <CharPtrIO> (inPtr, length);
 
+    if (length > inSize)
+    {
+       throw InputExc ("Error in header for PIZ-compressed data "
+                       "(invalid array length).");
+    }
+
     hufUncompress (inPtr, length, _tmpBuffer, tmpBufferEnd - _tmpBuffer);
 
     //
@@ -580,15 +587,15 @@ PizCompressor::uncompress (const char *inPtr,
 
     for (int i = 0; i < _numChans; ++i)
     {
-    ChannelData &cd = _channelData[i];
-
-    for (int j = 0; j < cd.size; ++j)
-    {
-        wav2Decode (cd.start + j,
-            cd.nx, cd.size,
-            cd.ny, cd.nx * cd.size,
-            maxValue);
-    }
+       ChannelData &cd = _channelData[i];
+
+       for (int j = 0; j < cd.size; ++j)
+       {
+           wav2Decode (cd.start + j,
+                       cd.nx, cd.size,
+                       cd.ny, cd.nx * cd.size,
+                       maxValue);
+       }
     }
 
     //
@@ -596,7 +603,7 @@ PizCompressor::uncompress (const char *inPtr,
     //
 
     applyLut (lut, _tmpBuffer, tmpBufferEnd - _tmpBuffer);
-
+    
     //
     // Rearrange the pixel data into the format expected by the caller.
     //
@@ -605,56 +612,56 @@ PizCompressor::uncompress (const char *inPtr,
 
     if (_format == XDR)
     {
-    //
-    // Machine-independent (Xdr) data format
-    //
-
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        for (int x = cd.nx * cd.size; x > 0; --x)
-        {
-            Xdr::write <CharPtrIO> (outEnd, *cd.end);
-            ++cd.end;
-        }
-        }
-    }
+       //
+       // Machine-independent (Xdr) data format
+       //
+
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               for (int x = cd.nx * cd.size; x > 0; --x)
+               {
+                   Xdr::write <CharPtrIO> (outEnd, *cd.end);
+                   ++cd.end;
+               }
+           }
+       }
     }
     else
     {
-    //
-    // Native, machine-dependent data format
-    //
-
-    for (int y = minY; y <= maxY; ++y)
-    {
-        for (int i = 0; i < _numChans; ++i)
-        {
-        ChannelData &cd = _channelData[i];
-
-        if (modp (y, cd.ys) != 0)
-            continue;
-
-        int n = cd.nx * cd.size;
-        memcpy (outEnd, cd.end, n * sizeof (unsigned short));
-        outEnd += n * sizeof (unsigned short);
-        cd.end += n;
-        }
-    }
+       //
+       // Native, machine-dependent data format
+       //
+
+       for (int y = minY; y <= maxY; ++y)
+       {
+           for (int i = 0; i < _numChans; ++i)
+           {
+               ChannelData &cd = _channelData[i];
+
+               if (modp (y, cd.ys) != 0)
+                   continue;
+
+               int n = cd.nx * cd.size;
+               memcpy (outEnd, cd.end, n * sizeof (unsigned short));
+               outEnd += n * sizeof (unsigned short);
+               cd.end += n;
+           }
+       }
     }
 
     #if defined (DEBUG)
 
-    for (int i = 1; i < _numChans; ++i)
-        assert (_channelData[i-1].end == _channelData[i].start);
+       for (int i = 1; i < _numChans; ++i)
+           assert (_channelData[i-1].end == _channelData[i].start);
 
-    assert (_channelData[_numChans-1].end == tmpBufferEnd);
+       assert (_channelData[_numChans-1].end == tmpBufferEnd);
 
     #endif
 
@@ -663,4 +670,4 @@ PizCompressor::uncompress (const char *inPtr,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index df7de7c..703f552 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-namespace Imf {
 
-class ChannelList;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class PizCompressor: public Compressor
 {
   public:
 
+    IMF_EXPORT
     PizCompressor (const Header &hdr,
                    size_t maxScanLineSize,
                    size_t numScanLines);
 
+    IMF_EXPORT
     virtual ~PizCompressor ();
 
+    IMF_EXPORT
     virtual int                numScanLines () const;
 
+    IMF_EXPORT
     virtual Format     format () const;
 
+    IMF_EXPORT
     virtual int                compress (const char *inPtr,
-                  int inSize,
-                  int minY,
-                  const char *&outPtr);
-
+                                 int inSize,
+                                 int minY,
+                                 const char *&outPtr);                  
+                  
+    IMF_EXPORT
     virtual int                compressTile (const char *inPtr,
-                      int inSize,
-                      Imath::Box2i range,
-                      const char *&outPtr);
+                                     int inSize,
+                                     IMATH_NAMESPACE::Box2i range,
+                                     const char *&outPtr);
 
+    IMF_EXPORT
     virtual int                uncompress (const char *inPtr,
-                    int inSize,
-                    int minY,
-                    const char *&outPtr);
-
+                                   int inSize,
+                                   int minY,
+                                   const char *&outPtr);
+                    
+    IMF_EXPORT
     virtual int                uncompressTile (const char *inPtr,
-                    int inSize,
-                    Imath::Box2i range,
-                    const char *&outPtr);
+                                       int inSize,
+                                       IMATH_NAMESPACE::Box2i range,
+                                       const char *&outPtr);
   private:
 
     struct ChannelData;
-
+    
     int                        compress (const char *inPtr,
-                  int inSize,
-                  Imath::Box2i range,
-                  const char *&outPtr);
-
+                                 int inSize,
+                                 IMATH_NAMESPACE::Box2i range,
+                                 const char *&outPtr);
     int                        uncompress (const char *inPtr,
-                    int inSize,
-                    Imath::Box2i range,
-                    const char *&outPtr);
+                                   int inSize,
+                                   IMATH_NAMESPACE::Box2i range,
+                                   const char *&outPtr);
 
     int                        _maxScanLineSize;
     Format             _format;
@@ -110,6 +120,6 @@ class PizCompressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 5bd1e40..8027d0f 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfPreviewImage.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfPreviewImage.h"
+#include "ImfCheckedArithmetic.h"
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 PreviewImage::PreviewImage (unsigned int width,
-                unsigned int height,
-                const PreviewRgba pixels[])
+                           unsigned int height,
+                           const PreviewRgba pixels[])
 {
     _width = width;
     _height = height;
@@ -57,13 +58,13 @@ PreviewImage::PreviewImage (unsigned int width,
 
     if (pixels)
     {
-    for (unsigned int i = 0; i < _width * _height; ++i)
-        _pixels[i] = pixels[i];
+       for (unsigned int i = 0; i < _width * _height; ++i)
+           _pixels[i] = pixels[i];
     }
     else
     {
-    for (unsigned int i = 0; i < _width * _height; ++i)
-        _pixels[i] = PreviewRgba();
+       for (unsigned int i = 0; i < _width * _height; ++i)
+           _pixels[i] = PreviewRgba();
     }
 }
 
@@ -74,7 +75,7 @@ PreviewImage::PreviewImage (const PreviewImage &other):
     _pixels (new PreviewRgba [other._width * other._height])
 {
     for (unsigned int i = 0; i < _width * _height; ++i)
-    _pixels[i] = other._pixels[i];
+       _pixels[i] = other._pixels[i];
 }
 
 
@@ -94,10 +95,10 @@ PreviewImage::operator = (const PreviewImage &other)
     _pixels = new PreviewRgba [other._width * other._height];
 
     for (unsigned int i = 0; i < _width * _height; ++i)
-    _pixels[i] = other._pixels[i];
+       _pixels[i] = other._pixels[i];
 
     return *this;
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 716085c..20a2253 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -36,6 +36,9 @@
 #ifndef INCLUDED_IMF_PREVIEW_IMAGE_H
 #define INCLUDED_IMF_PREVIEW_IMAGE_H
 
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 //-----------------------------------------------------------------------------
 //
 //     class PreviewImage -- a usually small, low-dynamic range image,
@@ -45,7 +48,8 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 struct PreviewRgba
@@ -53,16 +57,16 @@ struct PreviewRgba
     unsigned char      r;      // Red, green and blue components of
     unsigned char      g;      // the pixel's color; intensity is
     unsigned char      b;      // proportional to pow (x/255, 2.2),
-                    // where x is r, g, or b.
+                               // where x is r, g, or b.
 
     unsigned char      a;      // The pixel's alpha; 0 == transparent,
-                // 255 == opaque.
+                               // 255 == opaque.
 
     PreviewRgba (unsigned char r = 0,
-         unsigned char g = 0,
-         unsigned char b = 0,
-         unsigned char a = 255)
-    : r(r), g(g), b(b), a(a) {}
+                unsigned char g = 0,
+                unsigned char b = 0,
+                unsigned char a = 255)
+       : r(r), g(g), b(b), a(a) {}
 };
 
 
@@ -82,18 +86,22 @@ class PreviewImage
     // (r = 0, b = 0, g = 0, a = 255).
     //
     //--------------------------------------------------------------------
-
+   
+    IMF_EXPORT
      PreviewImage (unsigned int width = 0,
-           unsigned int height = 0,
-           const PreviewRgba pixels[] = 0);
+                  unsigned int height = 0,
+                  const PreviewRgba pixels[] = 0);
 
     //-----------------------------------------------------
     // Copy constructor, destructor and assignment operator
     //-----------------------------------------------------
 
+    IMF_EXPORT
      PreviewImage (const PreviewImage &other);
+    IMF_EXPORT
     ~PreviewImage ();
 
+    IMF_EXPORT
     PreviewImage &     operator = (const PreviewImage &other);
 
 
@@ -101,10 +109,14 @@ class PreviewImage
     // Access to width, height and to the pixel array
     //-----------------------------------------------
 
+    IMF_EXPORT
     unsigned int       width () const  {return _width;}
+    IMF_EXPORT
     unsigned int       height () const {return _height;}
 
+    IMF_EXPORT
     PreviewRgba *      pixels ()       {return _pixels;}
+    IMF_EXPORT
     const PreviewRgba *        pixels () const {return _pixels;}
 
 
@@ -112,11 +124,13 @@ class PreviewImage
     // Access to individual pixels
     //----------------------------
 
+    IMF_EXPORT
     PreviewRgba &      pixel (unsigned int x, unsigned int y)
-                        {return _pixels[y * _width + x];}
+                                       {return _pixels[y * _width + x];}
 
+    IMF_EXPORT
     const PreviewRgba &        pixel (unsigned int x, unsigned int y) const
-                        {return _pixels[y * _width + x];}
+                                       {return _pixels[y * _width + x];}
 
   private:
 
@@ -126,6 +140,6 @@ class PreviewImage
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 441ee22..8729f88 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,8 +42,9 @@
 #include <ImfPreviewImageAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ PreviewImageAttribute::staticTypeName ()
 
 template <>
 void
-PreviewImageAttribute::writeValueTo (OStream &os, int) const
+PreviewImageAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.width());
     Xdr::write <StreamIO> (os, _value.height());
@@ -65,17 +66,17 @@ PreviewImageAttribute::writeValueTo (OStream &os, int) const
 
     for (int i = 0; i < numPixels; ++i)
     {
-    Xdr::write <StreamIO> (os, pixels[i].r);
-    Xdr::write <StreamIO> (os, pixels[i].g);
-    Xdr::write <StreamIO> (os, pixels[i].b);
-    Xdr::write <StreamIO> (os, pixels[i].a);
+       Xdr::write <StreamIO> (os, pixels[i].r);
+       Xdr::write <StreamIO> (os, pixels[i].g);
+       Xdr::write <StreamIO> (os, pixels[i].b);
+       Xdr::write <StreamIO> (os, pixels[i].a);
     }
 }
 
 
 template <>
 void
-PreviewImageAttribute::readValueFrom (IStream &is, int, int)
+PreviewImageAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     int width, height;
 
@@ -89,14 +90,14 @@ PreviewImageAttribute::readValueFrom (IStream &is, int, int)
 
     for (int i = 0; i < numPixels; ++i)
     {
-    Xdr::read <StreamIO> (is, pixels[i].r);
-    Xdr::read <StreamIO> (is, pixels[i].g);
-    Xdr::read <StreamIO> (is, pixels[i].b);
-    Xdr::read <StreamIO> (is, pixels[i].a);
+       Xdr::read <StreamIO> (is, pixels[i].r);
+       Xdr::read <StreamIO> (is, pixels[i].g);
+       Xdr::read <StreamIO> (is, pixels[i].b);
+       Xdr::read <StreamIO> (is, pixels[i].a);
     }
 
     _value = p;
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index bd80dbf..160e409 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfPreviewImage.h>
+#include "ImfAttribute.h"
+#include "ImfPreviewImage.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<PreviewImage> PreviewImageAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::PreviewImage> PreviewImageAttribute;
 
 template <>
+IMF_EXPORT
 const char *PreviewImageAttribute::staticTypeName ();
 
 template <>
-void PreviewImageAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void PreviewImageAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                          int) const;
 
 template <>
-void PreviewImageAttribute::readValueFrom (IStream &, int, int);
-
+IMF_EXPORT
+void PreviewImageAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                           int, int);
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfPreviewImageAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index f9f35d3..6489576 100644 (file)
 //     string of bytes is compressed with zlib.
 //
 //-----------------------------------------------------------------------------
-//#define ZLIB_WINAPI
 
-#include <ImfPxr24Compressor.h>
-#include <ImfHeader.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfPxr24Compressor.h"
+#include "ImfHeader.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfNamespace.h"
+
 #include <ImathFun.h>
 #include <Iex.h>
+
 #include <half.h>
 #include <zlib.h>
 #include <assert.h>
 #include <algorithm>
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 //
@@ -92,8 +95,8 @@ floatToFloat24 (float f)
 {
     union
     {
-    float              f;
-    unsigned int       i;
+       float           f;
+       unsigned int    i;
     } u;
 
     u.f = f;
@@ -110,48 +113,48 @@ floatToFloat24 (float f)
 
     if (e == 0x7f800000)
     {
-    if (m)
-    {
-        //
-        // F is a NAN; we preserve the sign bit and
-        // the 15 leftmost bits of the significand,
-        // with one exception: If the 15 leftmost
-        // bits are all zero, the NAN would turn
-        // into an infinity, so we have to set at
-        // least one bit in the significand.
-        //
-
-        m >>= 8;
-        i = (e >> 8) | m | (m == 0);
+       if (m)
+       {
+           //
+           // F is a NAN; we preserve the sign bit and
+           // the 15 leftmost bits of the significand,
+           // with one exception: If the 15 leftmost
+           // bits are all zero, the NAN would turn
+           // into an infinity, so we have to set at
+           // least one bit in the significand.
+           //
+
+           m >>= 8;
+           i = (e >> 8) | m | (m == 0);
+       }
+       else
+       {
+           //
+           // F is an infinity.
+           //
+
+           i = e >> 8;
+       }
     }
     else
     {
-        //
-        // F is an infinity.
-        //
-
-        i = e >> 8;
-    }
-    }
-    else
-    {
-    //
-    // F is finite, round the significand to 15 bits.
-    //
-
-    i = ((e | m) + (m & 0x00000080)) >> 8;
-
-    if (i >= 0x7f8000)
-    {
-        //
-        // F was close to FLT_MAX, and the significand was
-        // rounded up, resulting in an exponent overflow.
-        // Avoid the overflow by truncating the significand
-        // instead of rounding it.
-        //
-
-        i = (e | m) >> 8;
-    }
+       //
+       // F is finite, round the significand to 15 bits.
+       //
+
+       i = ((e | m) + (m & 0x00000080)) >> 8;
+
+       if (i >= 0x7f8000)
+       {
+           //
+           // F was close to FLT_MAX, and the significand was
+           // rounded up, resulting in an exponent overflow.
+           // Avoid the overflow by truncating the significand
+           // instead of rounding it.
+           //
+
+           i = (e | m) >> 8;
+       }
     }
 
     return (s >> 8) | i;
@@ -161,24 +164,24 @@ floatToFloat24 (float f)
 void
 notEnoughData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
-             "(input data are shorter than expected).");
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
+                        "(input data are shorter than expected).");
 }
 
 
 void
 tooMuchData ()
 {
-    throw Iex::InputExc ("Error decompressing data "
-             "(input data are longer than expected).");
+    throw IEX_NAMESPACE::InputExc ("Error decompressing data "
+                        "(input data are longer than expected).");
 }
 
 } // namespace
 
 
 Pxr24Compressor::Pxr24Compressor (const Header &hdr,
-                  size_t maxScanLineSize,
-                  size_t numScanLines)
+                                 size_t maxScanLineSize,
+                                 size_t numScanLines)
 :
     Compressor (hdr),
     _maxScanLineSize (maxScanLineSize),
@@ -229,23 +232,23 @@ Pxr24Compressor::format () const
 
 int
 Pxr24Compressor::compress (const char *inPtr,
-               int inSize,
-               int minY,
-               const char *&outPtr)
+                          int inSize,
+                          int minY,
+                          const char *&outPtr)
 {
     return compress (inPtr,
-                 inSize,
-             Box2i (V2i (_minX, minY),
-                V2i (_maxX, minY + _numScanLines - 1)),
-             outPtr);
+                    inSize,
+                    Box2i (V2i (_minX, minY),
+                           V2i (_maxX, minY + _numScanLines - 1)),
+                    outPtr);
 }
 
-
+             
 int
 Pxr24Compressor::compressTile (const char *inPtr,
-                   int inSize,
-                   Box2i range,
-                   const char *&outPtr)
+                              int inSize,
+                              Box2i range,
+                              const char *&outPtr)
 {
     return compress (inPtr, inSize, range, outPtr);
 }
@@ -253,23 +256,23 @@ Pxr24Compressor::compressTile (const char *inPtr,
 
 int
 Pxr24Compressor::uncompress (const char *inPtr,
-                 int inSize,
-                 int minY,
-                 const char *&outPtr)
+                            int inSize,
+                            int minY,
+                            const char *&outPtr)
 {
     return uncompress (inPtr,
-                   inSize,
-               Box2i (V2i (_minX, minY),
-                  V2i (_maxX, minY + _numScanLines - 1)),
-               outPtr);
+                      inSize,
+                      Box2i (V2i (_minX, minY),
+                             V2i (_maxX, minY + _numScanLines - 1)),
+                      outPtr);
 }
 
-
+               
 int
 Pxr24Compressor::uncompressTile (const char *inPtr,
-                 int inSize,
-                 Box2i range,
-                 const char *&outPtr)
+                                int inSize,
+                                Box2i range,
+                                const char *&outPtr)
 {
     return uncompress (inPtr, inSize, range, outPtr);
 }
@@ -277,14 +280,14 @@ Pxr24Compressor::uncompressTile (const char *inPtr,
 
 int
 Pxr24Compressor::compress (const char *inPtr,
-               int inSize,
-               Box2i range,
-               const char *&outPtr)
+                          int inSize,
+                          Box2i range,
+                          const char *&outPtr)
 {
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
+       outPtr = _outBuffer;
+       return 0;
     }
 
     int minX = range.min.x;
@@ -296,139 +299,139 @@ Pxr24Compressor::compress (const char *inPtr,
 
     for (int y = minY; y <= maxY; ++y)
     {
-    for (ChannelList::ConstIterator i = _channels.begin();
-         i != _channels.end();
-         ++i)
-    {
-        const Channel &c = i.channel();
+       for (ChannelList::ConstIterator i = _channels.begin();
+            i != _channels.end();
+            ++i)
+       {
+           const Channel &c = i.channel();
 
-        if (modp (y, c.ySampling) != 0)
-        continue;
+           if (modp (y, c.ySampling) != 0)
+               continue;
 
-        int n = numSamples (c.xSampling, minX, maxX);
+           int n = numSamples (c.xSampling, minX, maxX);
 
-        unsigned char *ptr[4];
-        unsigned int previousPixel = 0;
+           unsigned char *ptr[4];
+           unsigned int previousPixel = 0;
 
-        switch (c.type)
-        {
-          case UINT:
+           switch (c.type)
+           {
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
-        ptr[0] = tmpBufferEnd;
-        ptr[1] = ptr[0] + n;
-        ptr[2] = ptr[1] + n;
-        ptr[3] = ptr[2] + n;
-        tmpBufferEnd = ptr[3] + n;
+               ptr[0] = tmpBufferEnd;
+               ptr[1] = ptr[0] + n;
+               ptr[2] = ptr[1] + n;
+               ptr[3] = ptr[2] + n;
+               tmpBufferEnd = ptr[3] + n;
 
-        for (int j = 0; j < n; ++j)
-        {
-            unsigned int pixel;
-            char *pPtr = (char *) &pixel;
+               for (int j = 0; j < n; ++j)
+               {
+                   unsigned int pixel;
+                   char *pPtr = (char *) &pixel;
 
-            for (int k = 0; k < sizeof (pixel); ++k)
-            *pPtr++ = *inPtr++;
+                   for (size_t k = 0; k < sizeof (pixel); ++k)
+                       *pPtr++ = *inPtr++;
 
-            unsigned int diff = pixel - previousPixel;
-            previousPixel = pixel;
+                   unsigned int diff = pixel - previousPixel;
+                   previousPixel = pixel;
 
-            *(ptr[0]++) = diff >> 24;
-            *(ptr[1]++) = diff >> 16;
-            *(ptr[2]++) = diff >> 8;
-            *(ptr[3]++) = diff;
-        }
+                   *(ptr[0]++) = diff >> 24;
+                   *(ptr[1]++) = diff >> 16;
+                   *(ptr[2]++) = diff >> 8;
+                   *(ptr[3]++) = diff;
+               }
 
-        break;
+               break;
 
-          case HALF:
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-        ptr[0] = tmpBufferEnd;
-        ptr[1] = ptr[0] + n;
-        tmpBufferEnd = ptr[1] + n;
+               ptr[0] = tmpBufferEnd;
+               ptr[1] = ptr[0] + n;
+               tmpBufferEnd = ptr[1] + n;
 
-        for (int j = 0; j < n; ++j)
-        {
-            half pixel;
+               for (int j = 0; j < n; ++j)
+               {
+                   half pixel;
 
-            pixel = *(const half *) inPtr;
-            inPtr += sizeof (half);
+                   pixel = *(const half *) inPtr;
+                   inPtr += sizeof (half);
 
-            unsigned int diff = pixel.bits() - previousPixel;
-            previousPixel = pixel.bits();
+                   unsigned int diff = pixel.bits() - previousPixel;
+                   previousPixel = pixel.bits();
 
-            *(ptr[0]++) = diff >> 8;
-            *(ptr[1]++) = diff;
-        }
+                   *(ptr[0]++) = diff >> 8;
+                   *(ptr[1]++) = diff;
+               }
 
-        break;
+               break;
 
-          case FLOAT:
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-        ptr[0] = tmpBufferEnd;
-        ptr[1] = ptr[0] + n;
-        ptr[2] = ptr[1] + n;
-        tmpBufferEnd = ptr[2] + n;
+               ptr[0] = tmpBufferEnd;
+               ptr[1] = ptr[0] + n;
+               ptr[2] = ptr[1] + n;
+               tmpBufferEnd = ptr[2] + n;
 
-        for (int j = 0; j < n; ++j)
-        {
-            float pixel;
-            char *pPtr = (char *) &pixel;
+               for (int j = 0; j < n; ++j)
+               {
+                   float pixel;
+                   char *pPtr = (char *) &pixel;
 
-            for (int k = 0; k < sizeof (pixel); ++k)
-            *pPtr++ = *inPtr++;
+                   for (size_t k = 0; k < sizeof (pixel); ++k)
+                       *pPtr++ = *inPtr++;
 
-            unsigned int pixel24 = floatToFloat24 (pixel);
-            unsigned int diff = pixel24 - previousPixel;
-            previousPixel = pixel24;
+                   unsigned int pixel24 = floatToFloat24 (pixel);
+                   unsigned int diff = pixel24 - previousPixel;
+                   previousPixel = pixel24;
 
-            *(ptr[0]++) = diff >> 16;
-            *(ptr[1]++) = diff >> 8;
-            *(ptr[2]++) = diff;
-        }
+                   *(ptr[0]++) = diff >> 16;
+                   *(ptr[1]++) = diff >> 8;
+                   *(ptr[2]++) = diff;
+               }
 
-        break;
+               break;
 
-          default:
+             default:
 
-        assert (false);
-        }
-    }
+               assert (false);
+           }
+       }
     }
 
     uLongf outSize = int (ceil ((tmpBufferEnd - _tmpBuffer) * 1.01)) + 100;
 
     if (Z_OK != ::compress ((Bytef *) _outBuffer,
-                &outSize,
-                (const Bytef *) _tmpBuffer,
-                tmpBufferEnd - _tmpBuffer))
+                           &outSize,
+                           (const Bytef *) _tmpBuffer,
+                           tmpBufferEnd - _tmpBuffer))
     {
-    throw Iex::BaseExc ("Data compression (zlib) failed.");
+       throw IEX_NAMESPACE::BaseExc ("Data compression (zlib) failed.");
     }
 
     outPtr = _outBuffer;
     return outSize;
 }
 
-
-int
+int            
 Pxr24Compressor::uncompress (const char *inPtr,
-                 int inSize,
-                 Box2i range,
-                 const char *&outPtr)
+                            int inSize,
+                            Box2i range,
+                            const char *&outPtr)
 {
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
+       outPtr = _outBuffer;
+       return 0;
     }
 
     uLongf tmpSize = _maxScanLineSize * _numScanLines;
 
     if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer,
-                  &tmpSize,
-                  (const Bytef *) inPtr,
-                  inSize))
+                             &tmpSize,
+                             (const Bytef *) inPtr,
+                             inSize))
     {
-    throw Iex::InputExc ("Data decompression (zlib) failed.");
+       throw IEX_NAMESPACE::InputExc ("Data decompression (zlib) failed.");
     }
 
     int minX = range.min.x;
@@ -441,110 +444,110 @@ Pxr24Compressor::uncompress (const char *inPtr,
 
     for (int y = minY; y <= maxY; ++y)
     {
-    for (ChannelList::ConstIterator i = _channels.begin();
-         i != _channels.end();
-         ++i)
-    {
-        const Channel &c = i.channel();
+       for (ChannelList::ConstIterator i = _channels.begin();
+            i != _channels.end();
+            ++i)
+       {
+           const Channel &c = i.channel();
 
-        if (modp (y, c.ySampling) != 0)
-        continue;
+           if (modp (y, c.ySampling) != 0)
+               continue;
 
-        int n = numSamples (c.xSampling, minX, maxX);
+           int n = numSamples (c.xSampling, minX, maxX);
 
-        const unsigned char *ptr[4];
-        unsigned int pixel = 0;
+           const unsigned char *ptr[4];
+           unsigned int pixel = 0;
 
-        switch (c.type)
-        {
-          case UINT:
+           switch (c.type)
+           {
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT:
 
-        ptr[0] = tmpBufferEnd;
-        ptr[1] = ptr[0] + n;
-        ptr[2] = ptr[1] + n;
-        ptr[3] = ptr[2] + n;
-        tmpBufferEnd = ptr[3] + n;
+               ptr[0] = tmpBufferEnd;
+               ptr[1] = ptr[0] + n;
+               ptr[2] = ptr[1] + n;
+               ptr[3] = ptr[2] + n;
+               tmpBufferEnd = ptr[3] + n;
 
-        if (tmpBufferEnd - _tmpBuffer > tmpSize)
-            notEnoughData();
+               if ( (uLongf)(tmpBufferEnd - _tmpBuffer) > tmpSize)
+                   notEnoughData();
 
-        for (int j = 0; j < n; ++j)
-        {
-            unsigned int diff = (*(ptr[0]++) << 24) |
-                    (*(ptr[1]++) << 16) |
-                    (*(ptr[2]++) <<  8) |
-                     *(ptr[3]++);
+               for (int j = 0; j < n; ++j)
+               {
+                   unsigned int diff = (*(ptr[0]++) << 24) |
+                                       (*(ptr[1]++) << 16) |
+                                       (*(ptr[2]++) <<  8) |
+                                        *(ptr[3]++);
 
-            pixel += diff;
+                   pixel += diff;
 
-            char *pPtr = (char *) &pixel;
+                   char *pPtr = (char *) &pixel;
 
-            for (int k = 0; k < sizeof (pixel); ++k)
-            *writePtr++ = *pPtr++;
-        }
+                   for (size_t k = 0; k < sizeof (pixel); ++k)
+                       *writePtr++ = *pPtr++;
+               }
 
-        break;
+               break;
 
-          case HALF:
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF:
 
-        ptr[0] = tmpBufferEnd;
-        ptr[1] = ptr[0] + n;
-        tmpBufferEnd = ptr[1] + n;
+               ptr[0] = tmpBufferEnd;
+               ptr[1] = ptr[0] + n;
+               tmpBufferEnd = ptr[1] + n;
 
-        if (tmpBufferEnd - _tmpBuffer > tmpSize)
-            notEnoughData();
+        if ( (uLongf)(tmpBufferEnd - _tmpBuffer) > tmpSize)
+                   notEnoughData();
 
-        for (int j = 0; j < n; ++j)
-        {
-            unsigned int diff = (*(ptr[0]++) << 8) |
-                     *(ptr[1]++);
+               for (int j = 0; j < n; ++j)
+               {
+                   unsigned int diff = (*(ptr[0]++) << 8) |
+                                        *(ptr[1]++);
 
-            pixel += diff;
+                   pixel += diff;
 
-            half * hPtr = (half *) writePtr;
-            hPtr->setBits ((unsigned short) pixel);
-            writePtr += sizeof (half);
-        }
+                   half * hPtr = (half *) writePtr;
+                   hPtr->setBits ((unsigned short) pixel);
+                   writePtr += sizeof (half);
+               }
 
-        break;
+               break;
 
-          case FLOAT:
+             case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT:
 
-        ptr[0] = tmpBufferEnd;
-        ptr[1] = ptr[0] + n;
-        ptr[2] = ptr[1] + n;
-        tmpBufferEnd = ptr[2] + n;
+               ptr[0] = tmpBufferEnd;
+               ptr[1] = ptr[0] + n;
+               ptr[2] = ptr[1] + n;
+               tmpBufferEnd = ptr[2] + n;
 
-        if (tmpBufferEnd - _tmpBuffer > tmpSize)
-            notEnoughData();
+        if ( (uLongf) (tmpBufferEnd - _tmpBuffer) > tmpSize)
+                   notEnoughData();
 
-        for (int j = 0; j < n; ++j)
-        {
-            unsigned int diff = (*(ptr[0]++) << 24) |
-                    (*(ptr[1]++) << 16) |
-                    (*(ptr[2]++) <<  8);
-            pixel += diff;
+               for (int j = 0; j < n; ++j)
+               {
+                   unsigned int diff = (*(ptr[0]++) << 24) |
+                                       (*(ptr[1]++) << 16) |
+                                       (*(ptr[2]++) <<  8);
+                   pixel += diff;
 
-            char *pPtr = (char *) &pixel;
+                   char *pPtr = (char *) &pixel;
 
-            for (int k = 0; k < sizeof (pixel); ++k)
-            *writePtr++ = *pPtr++;
-        }
+                   for (size_t k = 0; k < sizeof (pixel); ++k)
+                       *writePtr++ = *pPtr++;
+               }
 
-        break;
+               break;
 
-          default:
+             default:
 
-        assert (false);
-        }
-    }
+               assert (false);
+           }
+       }
     }
 
-    if (tmpBufferEnd - _tmpBuffer < tmpSize)
-    tooMuchData();
+    if ((uLongf) (tmpBufferEnd - _tmpBuffer) < tmpSize)
+       tooMuchData();
 
     outPtr = _outBuffer;
     return writePtr - _outBuffer;
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index b94cbdc..d8c7091 100644 (file)
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+#include "ImfForward.h"
 
-namespace Imf {
-
-class ChannelList;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class Pxr24Compressor: public Compressor
 {
   public:
 
-    Pxr24Compressor (const Header &hdr,
+    IMF_EXPORT
+    Pxr24Compressor (const Header &hdr, 
                      size_t maxScanLineSize,
                      size_t numScanLines);
 
+    IMF_EXPORT
     virtual ~Pxr24Compressor ();
 
+    IMF_EXPORT
     virtual int                numScanLines () const;
 
+    IMF_EXPORT
     virtual Format     format () const;
 
+    IMF_EXPORT
     virtual int                compress (const char *inPtr,
-                  int inSize,
-                  int minY,
-                  const char *&outPtr);
-
+                                 int inSize,
+                                 int minY,
+                                 const char *&outPtr);                  
+                  
+    IMF_EXPORT
     virtual int                compressTile (const char *inPtr,
-                      int inSize,
-                      Imath::Box2i range,
-                      const char *&outPtr);
+                                     int inSize,
+                                     IMATH_NAMESPACE::Box2i range,
+                                     const char *&outPtr);
 
+    IMF_EXPORT
     virtual int                uncompress (const char *inPtr,
-                    int inSize,
-                    int minY,
-                    const char *&outPtr);
-
+                                   int inSize,
+                                   int minY,
+                                   const char *&outPtr);
+                    
+    IMF_EXPORT
     virtual int                uncompressTile (const char *inPtr,
-                    int inSize,
-                    Imath::Box2i range,
-                    const char *&outPtr);
+                                       int inSize,
+                                       IMATH_NAMESPACE::Box2i range,
+                                       const char *&outPtr);
   private:
 
     int                        compress (const char *inPtr,
-                  int inSize,
-                  Imath::Box2i range,
-                  const char *&outPtr);
-
+                                 int inSize,
+                                 IMATH_NAMESPACE::Box2i range,
+                                 const char *&outPtr);
     int                        uncompress (const char *inPtr,
-                    int inSize,
-                    Imath::Box2i range,
-                    const char *&outPtr);
+                                   int inSize,
+                                   IMATH_NAMESPACE::Box2i range,
+                                   const char *&outPtr);
 
     int                        _maxScanLineSize;
     int                        _numScanLines;
@@ -103,6 +112,6 @@ class Pxr24Compressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 7eff9e2..fda7fc9 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <cmath>
 
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
 double
@@ -72,8 +74,8 @@ denom (double x, double e)
     }
     else
     {
-    double r = frac (1 / x, e);
-
+       double r = frac (1 / x, e);
+       
         if (e > r)
         {
             return floor (1 / x + e);
@@ -95,25 +97,25 @@ Rational::Rational (double x)
 
     if (x >= 0)
     {
-    sign = 1;  // positive
+       sign = 1;       // positive
     }
     else if (x < 0)
     {
-    sign = -1; // negative
-    x = -x;
+       sign = -1;      // negative
+       x = -x;
     }
     else
     {
-    n = 0;             // NaN
-    d = 0;
-    return;
+       n = 0;          // NaN
+       d = 0;
+       return;
     }
 
     if (x >= (1U << 31) - 0.5)
     {
-    n = sign;  // infinity
-    d = 0;
-    return;
+       n = sign;       // infinity
+       d = 0;
+       return;
     }
 
     double e = (x < 1? 1: x) / (1U << 30);
@@ -122,4 +124,4 @@ Rational::Rational (double x)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index a2493b1..9dfe806 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #ifndef INCLUDED_IMF_RATIONAL_H
 #define INCLUDED_IMF_RATIONAL_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 //-----------------------------------------------------------------------------
 //
 //     Rational numbers
 //
 //     A rational number is represented as pair of integers, n and d.
 //     The value of of the rational number is
-//
+// 
 //             n/d                     for d > 0
 //             positive infinity       for n > 0, d == 0
 //             negative infinity       for n < 0, d == 0
@@ -50,7 +53,8 @@
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
 
 class Rational
 {
@@ -71,13 +75,14 @@ class Rational
     // Constructor, explicitly sets n and d
     //-------------------------------------
 
-    Rational (int _n, int _d): n (_n), d (_d) {}
+    Rational (int n, int d): n (n), d (d) {}
 
 
     //----------------------------
     // Constructor, approximates x
     //----------------------------
 
+    IMF_EXPORT
     explicit Rational (double x);
 
 
@@ -88,6 +93,7 @@ class Rational
     operator double () const {return double (n) / double (d);}
 };
 
-} // namespace Imf
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 0a7afca..a416468 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -41,8 +41,9 @@
 #include <ImfRationalAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -54,7 +55,7 @@ RationalAttribute::staticTypeName ()
 
 template <>
 void
-RationalAttribute::writeValueTo (OStream &os, int) const
+RationalAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.n);
     Xdr::write <StreamIO> (os, _value.d);
@@ -63,11 +64,11 @@ RationalAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-RationalAttribute::readValueFrom (IStream &is, int, int)
+RationalAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.n);
     Xdr::read <StreamIO> (is, _value.d);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index cda2861..988fe01 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfRational.h>
+#include "ImfAttribute.h"
+#include "ImfRational.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-
-typedef TypedAttribute<Rational> RationalAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::Rational> RationalAttribute;
 
 template <>
+IMF_EXPORT
 const char *RationalAttribute::staticTypeName ();
 
 template <>
-void RationalAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void RationalAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                      int) const;
 
 template <>
-void RationalAttribute::readValueFrom (IStream &, int, int);
-
+IMF_EXPORT
+void RationalAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                       int, int);
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfRationalAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 3f39a11..dccba9f 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,8 +43,9 @@
 //-----------------------------------------------------------------------------
 
 #include "half.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //
@@ -57,18 +58,18 @@ struct Rgba
     half       g;
     half       b;
     half       a;
-
+    
     Rgba () {}
     Rgba (half r, half g, half b, half a = 1.f): r (r), g (g), b (b), a (a) {}
 
     Rgba & operator = (const Rgba &other)
     {
-        r = other.r;
-        g = other.g;
-        b = other.b;
-        a = other.a;
+       r = other.r;
+       g = other.g;
+       b = other.b;
+       a = other.a;
 
-        return *this;
+       return *this;
     }
 };
 
@@ -85,10 +86,10 @@ enum RgbaChannels
     WRITE_A    = 0x08,         // Alpha
 
     WRITE_Y    = 0x10,         // Luminance, for black-and-white images,
-                    // or in combination with chroma
+                               // or in combination with chroma
 
     WRITE_C    = 0x20,         // Chroma (two subsampled channels, RY and BY,
-                    // supported only for scanline-based files)
+                               // supported only for scanline-based files)
 
     WRITE_RGB  = 0x07,         // Red, green, blue
     WRITE_RGBA = 0x0f,         // Red, green, blue, alpha
@@ -99,6 +100,10 @@ enum RgbaChannels
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index 6b3634e..c2b604a 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <string.h>
 #include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
 using namespace RgbaYca;
-using namespace IlmThread;
+using namespace ILMTHREAD_NAMESPACE;
 
 namespace {
 
@@ -68,31 +69,31 @@ insertChannels (Header &header, RgbaChannels rgbaChannels)
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
     {
-    if (rgbaChannels & WRITE_Y)
-    {
-        ch.insert ("Y", Channel (HALF, 1, 1));
-    }
-
-    if (rgbaChannels & WRITE_C)
-    {
-        ch.insert ("RY", Channel (HALF, 2, 2, true));
-        ch.insert ("BY", Channel (HALF, 2, 2, true));
-    }
+       if (rgbaChannels & WRITE_Y)
+       {
+           ch.insert ("Y", Channel (HALF, 1, 1));
+       }
+
+       if (rgbaChannels & WRITE_C)
+       {
+           ch.insert ("RY", Channel (HALF, 2, 2, true));
+           ch.insert ("BY", Channel (HALF, 2, 2, true));
+       }
     }
     else
     {
-    if (rgbaChannels & WRITE_R)
-        ch.insert ("R", Channel (HALF, 1, 1));
+       if (rgbaChannels & WRITE_R)
+           ch.insert ("R", Channel (HALF, 1, 1));
 
-    if (rgbaChannels & WRITE_G)
-        ch.insert ("G", Channel (HALF, 1, 1));
+       if (rgbaChannels & WRITE_G)
+           ch.insert ("G", Channel (HALF, 1, 1));
 
-    if (rgbaChannels & WRITE_B)
-        ch.insert ("B", Channel (HALF, 1, 1));
+       if (rgbaChannels & WRITE_B)
+           ch.insert ("B", Channel (HALF, 1, 1));
     }
 
     if (rgbaChannels & WRITE_A)
-    ch.insert ("A", Channel (HALF, 1, 1));
+       ch.insert ("A", Channel (HALF, 1, 1));
 
     header.channels() = ch;
 }
@@ -104,23 +105,23 @@ rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "")
     int i = 0;
 
     if (ch.findChannel (channelNamePrefix + "R"))
-    i |= WRITE_R;
+       i |= WRITE_R;
 
     if (ch.findChannel (channelNamePrefix + "G"))
-    i |= WRITE_G;
-
+       i |= WRITE_G;
+    
     if (ch.findChannel (channelNamePrefix + "B"))
-    i |= WRITE_B;
+       i |= WRITE_B;
 
     if (ch.findChannel (channelNamePrefix + "A"))
-    i |= WRITE_A;
+       i |= WRITE_A;
 
     if (ch.findChannel (channelNamePrefix + "Y"))
-    i |= WRITE_Y;
+       i |= WRITE_Y;
 
     if (ch.findChannel (channelNamePrefix + "RY") ||
-    ch.findChannel (channelNamePrefix + "BY"))
-    i |= WRITE_C;
+       ch.findChannel (channelNamePrefix + "BY"))
+       i |= WRITE_C;
 
     return RgbaChannels (i);
 }
@@ -130,10 +131,10 @@ string
 prefixFromLayerName (const string &layerName, const Header &header)
 {
     if (layerName.empty())
-    return "";
+       return "";
 
     if (hasMultiView (header) && multiView(header)[0] == layerName)
-    return "";
+       return "";
 
     return layerName + ".";
 }
@@ -145,7 +146,7 @@ ywFromHeader (const Header &header)
     Chromaticities cr;
 
     if (hasChromaticities (header))
-    cr = chromaticities (header);
+       cr = chromaticities (header);
 
     return computeYw (cr);
 }
@@ -173,13 +174,13 @@ cachePadding (ptrdiff_t size)
     int i = LOG2_CACHE_LINE_SIZE + 2;
 
     while ((size >> i) > 1)
-    ++i;
+       ++i;
 
     if (size > (1 << (i + 1)) - 64)
-    return 64 + ((1 << (i + 1)) - size);
+       return 64 + ((1 << (i + 1)) - size);
 
     if (size < (1 << i) + 64)
-    return 64 + ((1 << i) - size);
+       return 64 + ((1 << i) - size);
 
     return 0;
 }
@@ -195,11 +196,11 @@ class RgbaOutputFile::ToYca: public Mutex
     ~ToYca ();
 
     void               setYCRounding (unsigned int roundY,
-                           unsigned int roundC);
+                                      unsigned int roundC);
 
     void               setFrameBuffer (const Rgba *base,
-                    size_t xStride,
-                    size_t yStride);
+                                       size_t xStride,
+                                       size_t yStride);
 
     void               writePixels (int numScanLines);
     int                        currentScanLine () const;
@@ -235,7 +236,7 @@ class RgbaOutputFile::ToYca: public Mutex
 
 
 RgbaOutputFile::ToYca::ToYca (OutputFile &outputFile,
-                  RgbaChannels rgbaChannels)
+                             RgbaChannels rgbaChannels)
 :
     _outputFile (outputFile)
 {
@@ -251,11 +252,11 @@ RgbaOutputFile::ToYca::ToYca (OutputFile &outputFile,
 
     _linesConverted = 0;
     _lineOrder = _outputFile.header().lineOrder();
-
+    
     if (_lineOrder == INCREASING_Y)
-    _currentScanLine = dw.min.y;
+       _currentScanLine = dw.min.y;
     else
-    _currentScanLine = dw.max.y;
+       _currentScanLine = dw.max.y;
 
     _yw = ywFromHeader (_outputFile.header());
 
@@ -264,7 +265,7 @@ RgbaOutputFile::ToYca::ToYca (OutputFile &outputFile,
     _bufBase = new Rgba[(_width + pad) * N];
 
     for (int i = 0; i < N; ++i)
-    _buf[i] = _bufBase + (i * (_width + pad));
+       _buf[i] = _bufBase + (i * (_width + pad));
 
     _tmpBuf = new Rgba[_width + N - 1];
 
@@ -286,7 +287,7 @@ RgbaOutputFile::ToYca::~ToYca ()
 
 void
 RgbaOutputFile::ToYca::setYCRounding (unsigned int roundY,
-                      unsigned int roundC)
+                                     unsigned int roundC)
 {
     _roundY = roundY;
     _roundC = roundC;
@@ -295,55 +296,55 @@ RgbaOutputFile::ToYca::setYCRounding (unsigned int roundY,
 
 void
 RgbaOutputFile::ToYca::setFrameBuffer (const Rgba *base,
-                       size_t xStride,
-                       size_t yStride)
+                                      size_t xStride,
+                                      size_t yStride)
 {
     if (_fbBase == 0)
     {
-    FrameBuffer fb;
-
-    if (_writeY)
-    {
-        fb.insert ("Y",
-               Slice (HALF,                            // type
-                  (char *) &_tmpBuf[-_xMin].g, // base
-                  sizeof (Rgba),                       // xStride
-                  0,                           // yStride
-                  1,                           // xSampling
-                  1));                         // ySampling
-    }
-
-    if (_writeC)
-    {
-        fb.insert ("RY",
-               Slice (HALF,                            // type
-                  (char *) &_tmpBuf[-_xMin].r, // base
-                  sizeof (Rgba) * 2,           // xStride
-                  0,                           // yStride
-                  2,                           // xSampling
-                  2));                         // ySampling
-
-        fb.insert ("BY",
-               Slice (HALF,                            // type
-                  (char *) &_tmpBuf[-_xMin].b, // base
-                  sizeof (Rgba) * 2,           // xStride
-                  0,                           // yStride
-                  2,                           // xSampling
-                  2));                         // ySampling
-    }
-
-    if (_writeA)
-    {
-        fb.insert ("A",
-               Slice (HALF,                            // type
-                  (char *) &_tmpBuf[-_xMin].a, // base
-                  sizeof (Rgba),                       // xStride
-                  0,                           // yStride
-                  1,                           // xSampling
-                  1));                         // ySampling
-    }
-
-    _outputFile.setFrameBuffer (fb);
+       FrameBuffer fb;
+
+       if (_writeY)
+       {
+           fb.insert ("Y",
+                      Slice (HALF,                             // type
+                             (char *) &_tmpBuf[-_xMin].g,      // base
+                             sizeof (Rgba),                    // xStride
+                             0,                                // yStride
+                             1,                                // xSampling
+                             1));                              // ySampling
+       }
+
+       if (_writeC)
+       {
+           fb.insert ("RY",
+                      Slice (HALF,                             // type
+                             (char *) &_tmpBuf[-_xMin].r,      // base
+                             sizeof (Rgba) * 2,                // xStride
+                             0,                                // yStride
+                             2,                                // xSampling
+                             2));                              // ySampling
+
+           fb.insert ("BY",
+                      Slice (HALF,                             // type
+                             (char *) &_tmpBuf[-_xMin].b,      // base
+                             sizeof (Rgba) * 2,                // xStride
+                             0,                                // yStride
+                             2,                                // xSampling
+                             2));                              // ySampling
+       }
+
+       if (_writeA)
+       {
+           fb.insert ("A",
+                      Slice (HALF,                             // type
+                             (char *) &_tmpBuf[-_xMin].a,      // base
+                             sizeof (Rgba),                    // xStride
+                             0,                                // yStride
+                             1,                                // xSampling
+                             1));                              // ySampling
+       }
+
+       _outputFile.setFrameBuffer (fb);
     }
 
     _fbBase = base;
@@ -357,138 +358,138 @@ RgbaOutputFile::ToYca::writePixels (int numScanLines)
 {
     if (_fbBase == 0)
     {
-    THROW (Iex::ArgExc, "No frame buffer was specified as the "
-                "pixel data source for image file "
-                "\"" << _outputFile.fileName() << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
+                           "pixel data source for image file "
+                           "\"" << _outputFile.fileName() << "\".");
     }
 
     if (_writeY && !_writeC)
     {
-    //
-    // We are writing only luminance; filtering
-    // and subsampling are not necessary.
-    //
-
-    for (int i = 0; i < numScanLines; ++i)
-    {
-        //
-        // Copy the next scan line from the caller's
-        // frame buffer into _tmpBuf.
-        //
-
-        for (int j = 0; j < _width; ++j)
-        {
-        _tmpBuf[j] = _fbBase[_fbYStride * _currentScanLine +
-                     _fbXStride * (j + _xMin)];
-        }
-
-        //
-        // Convert the scan line from RGB to luminance/chroma,
-        // and store the result in the output file.
-        //
-
-        RGBAtoYCA (_yw, _width, _writeA, _tmpBuf, _tmpBuf);
-        _outputFile.writePixels (1);
-
-        ++_linesConverted;
-
-        if (_lineOrder == INCREASING_Y)
-        ++_currentScanLine;
-        else
-        --_currentScanLine;
-    }
+       //
+       // We are writing only luminance; filtering
+       // and subsampling are not necessary.
+       //
+
+       for (int i = 0; i < numScanLines; ++i)
+       {
+           //
+           // Copy the next scan line from the caller's
+           // frame buffer into _tmpBuf.
+           //
+
+           for (int j = 0; j < _width; ++j)
+           {
+               _tmpBuf[j] = _fbBase[_fbYStride * _currentScanLine +
+                                    _fbXStride * (j + _xMin)];
+           }
+
+           //
+           // Convert the scan line from RGB to luminance/chroma,
+           // and store the result in the output file.
+           //
+
+           RGBAtoYCA (_yw, _width, _writeA, _tmpBuf, _tmpBuf);
+           _outputFile.writePixels (1);
+
+           ++_linesConverted;
+
+           if (_lineOrder == INCREASING_Y)
+               ++_currentScanLine;
+           else
+               --_currentScanLine;
+       }
     }
     else
     {
-    //
-    // We are writing chroma; the pixels must be filtered and subsampled.
-    //
-
-    for (int i = 0; i < numScanLines; ++i)
-    {
-        //
-        // Copy the next scan line from the caller's
-        // frame buffer into _tmpBuf.
-        //
-
-        for (int j = 0; j < _width; ++j)
-        {
-        _tmpBuf[j + N2] = _fbBase[_fbYStride * _currentScanLine +
-                      _fbXStride * (j + _xMin)];
-        }
-
-        //
-        // Convert the scan line from RGB to luminance/chroma.
-        //
-
-        RGBAtoYCA (_yw, _width, _writeA, _tmpBuf + N2, _tmpBuf + N2);
-
-        //
-        // Append N2 copies of the first and last pixel to the
-        // beginning and end of the scan line.
-        //
-
-        padTmpBuf ();
-
-        //
-        // Filter and subsample the scan line's chroma channels
-        // horizontally; store the result in _buf.
-        //
-
-        rotateBuffers();
-        decimateChromaHoriz (_width, _tmpBuf, _buf[N - 1]);
-
-        //
-        // If this is the first scan line in the image,
-        // store N2 more copies of the scan line in _buf.
-        //
-
-        if (_linesConverted == 0)
-        {
-        for (int j = 0; j < N2; ++j)
-            duplicateLastBuffer();
-        }
-
-        ++_linesConverted;
-
-        //
-        // If we have have converted at least N2 scan lines from
-        // RGBA to luminance/chroma, then we can start to filter
-        // and subsample vertically, and store pixels in the
-        // output file.
-        //
-
-        if (_linesConverted > N2)
-        decimateChromaVertAndWriteScanLine();
-
-        //
-        // If we have already converted the last scan line in
-        // the image to luminance/chroma, filter, subsample and
-        // store the remaining scan lines in _buf.
-        //
-
-        if (_linesConverted >= _height)
-        {
-        for (int j = 0; j < N2 - _height; ++j)
-            duplicateLastBuffer();
-
-        duplicateSecondToLastBuffer();
-        ++_linesConverted;
-        decimateChromaVertAndWriteScanLine();
-
-        for (int j = 1; j < min (_height, N2); ++j)
-        {
-            duplicateLastBuffer();
-            ++_linesConverted;
-            decimateChromaVertAndWriteScanLine();
-        }
-        }
-
-        if (_lineOrder == INCREASING_Y)
-        ++_currentScanLine;
-        else
-        --_currentScanLine;
-    }
+       //
+       // We are writing chroma; the pixels must be filtered and subsampled.
+       //
+
+       for (int i = 0; i < numScanLines; ++i)
+       {
+           //
+           // Copy the next scan line from the caller's
+           // frame buffer into _tmpBuf.
+           //
+
+           for (int j = 0; j < _width; ++j)
+           {
+               _tmpBuf[j + N2] = _fbBase[_fbYStride * _currentScanLine +
+                                         _fbXStride * (j + _xMin)];
+           }
+
+           //
+           // Convert the scan line from RGB to luminance/chroma.
+           //
+
+           RGBAtoYCA (_yw, _width, _writeA, _tmpBuf + N2, _tmpBuf + N2);
+
+           //
+           // Append N2 copies of the first and last pixel to the
+           // beginning and end of the scan line.
+           //
+
+           padTmpBuf ();
+
+           //
+           // Filter and subsample the scan line's chroma channels
+           // horizontally; store the result in _buf.
+           //
+
+           rotateBuffers();
+           decimateChromaHoriz (_width, _tmpBuf, _buf[N - 1]);
+
+           //
+           // If this is the first scan line in the image,
+           // store N2 more copies of the scan line in _buf.
+           //
+
+           if (_linesConverted == 0)
+           {
+               for (int j = 0; j < N2; ++j)
+                   duplicateLastBuffer();
+           }
+
+           ++_linesConverted;
+
+           //
+           // If we have have converted at least N2 scan lines from
+           // RGBA to luminance/chroma, then we can start to filter
+           // and subsample vertically, and store pixels in the
+           // output file.
+           //
+
+           if (_linesConverted > N2)
+               decimateChromaVertAndWriteScanLine();
+
+           //
+           // If we have already converted the last scan line in
+           // the image to luminance/chroma, filter, subsample and
+           // store the remaining scan lines in _buf.
+           //
+
+           if (_linesConverted >= _height)
+           {
+               for (int j = 0; j < N2 - _height; ++j)
+                   duplicateLastBuffer();
+
+               duplicateSecondToLastBuffer();
+               ++_linesConverted;
+               decimateChromaVertAndWriteScanLine();
+
+               for (int j = 1; j < min (_height, N2); ++j)
+               {
+                   duplicateLastBuffer();
+                   ++_linesConverted;
+                   decimateChromaVertAndWriteScanLine();
+               }
+           }
+
+           if (_lineOrder == INCREASING_Y)
+               ++_currentScanLine;
+           else
+               --_currentScanLine;
+       }
     }
 }
 
@@ -505,8 +506,8 @@ RgbaOutputFile::ToYca::padTmpBuf ()
 {
     for (int i = 0; i < N2; ++i)
     {
-    _tmpBuf[i] = _tmpBuf[N2];
-    _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
+       _tmpBuf[i] = _tmpBuf[N2];
+       _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
     }
 }
 
@@ -517,7 +518,7 @@ RgbaOutputFile::ToYca::rotateBuffers ()
     Rgba *tmp = _buf[0];
 
     for (int i = 0; i < N - 1; ++i)
-    _buf[i] = _buf[i + 1];
+       _buf[i] = _buf[i + 1];
 
     _buf[N - 1] = tmp;
 }
@@ -543,20 +544,20 @@ void
 RgbaOutputFile::ToYca::decimateChromaVertAndWriteScanLine ()
 {
     if (_linesConverted & 1)
-    memcpy (_tmpBuf, _buf[N2], _width * sizeof (Rgba));
+       memcpy (_tmpBuf, _buf[N2], _width * sizeof (Rgba));
     else
-    decimateChromaVert (_width, _buf, _tmpBuf);
+       decimateChromaVert (_width, _buf, _tmpBuf);
 
     if (_writeY && _writeC)
-    roundYCA (_width, _roundY, _roundC, _tmpBuf, _tmpBuf);
+       roundYCA (_width, _roundY, _roundC, _tmpBuf, _tmpBuf);
 
     _outputFile.writePixels (1);
 }
 
 
 RgbaOutputFile::RgbaOutputFile (const char name[],
-                const Header &header,
-                RgbaChannels rgbaChannels,
+                               const Header &header,
+                               RgbaChannels rgbaChannels,
                                 int numThreads):
     _outputFile (0),
     _toYca (0)
@@ -566,13 +567,13 @@ RgbaOutputFile::RgbaOutputFile (const char name[],
     _outputFile = new OutputFile (name, hd, numThreads);
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _toYca = new ToYca (*_outputFile, rgbaChannels);
+       _toYca = new ToYca (*_outputFile, rgbaChannels);
 }
 
 
-RgbaOutputFile::RgbaOutputFile (OStream &os,
-                const Header &header,
-                RgbaChannels rgbaChannels,
+RgbaOutputFile::RgbaOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                               const Header &header,
+                               RgbaChannels rgbaChannels,
                                 int numThreads):
     _outputFile (0),
     _toYca (0)
@@ -582,65 +583,65 @@ RgbaOutputFile::RgbaOutputFile (OStream &os,
     _outputFile = new OutputFile (os, hd, numThreads);
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _toYca = new ToYca (*_outputFile, rgbaChannels);
+       _toYca = new ToYca (*_outputFile, rgbaChannels);
 }
 
 
 RgbaOutputFile::RgbaOutputFile (const char name[],
-                const Imath::Box2i &displayWindow,
-                const Imath::Box2i &dataWindow,
-                RgbaChannels rgbaChannels,
-                float pixelAspectRatio,
-                const Imath::V2f screenWindowCenter,
-                float screenWindowWidth,
-                LineOrder lineOrder,
-                Compression compression,
+                               const IMATH_NAMESPACE::Box2i &displayWindow,
+                               const IMATH_NAMESPACE::Box2i &dataWindow,
+                               RgbaChannels rgbaChannels,
+                               float pixelAspectRatio,
+                               const IMATH_NAMESPACE::V2f screenWindowCenter,
+                               float screenWindowWidth,
+                               LineOrder lineOrder,
+                               Compression compression,
                                 int numThreads):
     _outputFile (0),
     _toYca (0)
 {
     Header hd (displayWindow,
-           dataWindow.isEmpty()? displayWindow: dataWindow,
-           pixelAspectRatio,
-           screenWindowCenter,
-           screenWindowWidth,
-           lineOrder,
-           compression);
+              dataWindow.isEmpty()? displayWindow: dataWindow,
+              pixelAspectRatio,
+              screenWindowCenter,
+              screenWindowWidth,
+              lineOrder,
+              compression);
 
     insertChannels (hd, rgbaChannels);
     _outputFile = new OutputFile (name, hd, numThreads);
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _toYca = new ToYca (*_outputFile, rgbaChannels);
+       _toYca = new ToYca (*_outputFile, rgbaChannels);
 }
 
 
 RgbaOutputFile::RgbaOutputFile (const char name[],
-                int width,
-                int height,
-                RgbaChannels rgbaChannels,
-                float pixelAspectRatio,
-                const Imath::V2f screenWindowCenter,
-                float screenWindowWidth,
-                LineOrder lineOrder,
-                Compression compression,
+                               int width,
+                               int height,
+                               RgbaChannels rgbaChannels,
+                               float pixelAspectRatio,
+                               const IMATH_NAMESPACE::V2f screenWindowCenter,
+                               float screenWindowWidth,
+                               LineOrder lineOrder,
+                               Compression compression,
                                 int numThreads):
     _outputFile (0),
     _toYca (0)
 {
     Header hd (width,
-           height,
-           pixelAspectRatio,
-           screenWindowCenter,
-           screenWindowWidth,
-           lineOrder,
-           compression);
+              height,
+              pixelAspectRatio,
+              screenWindowCenter,
+              screenWindowWidth,
+              lineOrder,
+              compression);
 
     insertChannels (hd, rgbaChannels);
     _outputFile = new OutputFile (name, hd, numThreads);
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _toYca = new ToYca (*_outputFile, rgbaChannels);
+       _toYca = new ToYca (*_outputFile, rgbaChannels);
 }
 
 
@@ -653,57 +654,57 @@ RgbaOutputFile::~RgbaOutputFile ()
 
 void
 RgbaOutputFile::setFrameBuffer (const Rgba *base,
-                size_t xStride,
-                size_t yStride)
+                               size_t xStride,
+                               size_t yStride)
 {
     if (_toYca)
     {
-    Lock lock (*_toYca);
-    _toYca->setFrameBuffer (base, xStride, yStride);
+       Lock lock (*_toYca);
+       _toYca->setFrameBuffer (base, xStride, yStride);
     }
     else
     {
-    size_t xs = xStride * sizeof (Rgba);
-    size_t ys = yStride * sizeof (Rgba);
+       size_t xs = xStride * sizeof (Rgba);
+       size_t ys = yStride * sizeof (Rgba);
 
-    FrameBuffer fb;
+       FrameBuffer fb;
 
-    fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys));
-    fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys));
-    fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys));
-    fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys));
+       fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys));
+       fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys));
+       fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys));
+       fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys));
 
-    _outputFile->setFrameBuffer (fb);
+       _outputFile->setFrameBuffer (fb);
     }
 }
 
 
-void
+void   
 RgbaOutputFile::writePixels (int numScanLines)
 {
     if (_toYca)
     {
-    Lock lock (*_toYca);
-    _toYca->writePixels (numScanLines);
+       Lock lock (*_toYca);
+       _toYca->writePixels (numScanLines);
     }
     else
     {
-    _outputFile->writePixels (numScanLines);
+       _outputFile->writePixels (numScanLines);
     }
 }
 
 
-int
+int    
 RgbaOutputFile::currentScanLine () const
 {
     if (_toYca)
     {
-    Lock lock (*_toYca);
-    return _toYca->currentScanLine();
+       Lock lock (*_toYca);
+       return _toYca->currentScanLine();
     }
     else
     {
-    return _outputFile->currentScanLine();
+       return _outputFile->currentScanLine();
     }
 }
 
@@ -722,35 +723,35 @@ RgbaOutputFile::frameBuffer () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaOutputFile::displayWindow () const
 {
     return _outputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaOutputFile::dataWindow () const
 {
     return _outputFile->header().dataWindow();
 }
 
 
-float
+float  
 RgbaOutputFile::pixelAspectRatio () const
 {
     return _outputFile->header().pixelAspectRatio();
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 RgbaOutputFile::screenWindowCenter () const
 {
     return _outputFile->header().screenWindowCenter();
 }
 
 
-float
+float  
 RgbaOutputFile::screenWindowWidth () const
 {
     return _outputFile->header().screenWindowWidth();
@@ -778,25 +779,25 @@ RgbaOutputFile::channels () const
 }
 
 
-void
+void           
 RgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 {
     _outputFile->updatePreviewImage (newPixels);
 }
 
 
-void
+void           
 RgbaOutputFile::setYCRounding (unsigned int roundY, unsigned int roundC)
 {
     if (_toYca)
     {
-    Lock lock (*_toYca);
-    _toYca->setYCRounding (roundY, roundC);
+       Lock lock (*_toYca);
+       _toYca->setYCRounding (roundY, roundC);
     }
 }
 
 
-void
+void   
 RgbaOutputFile::breakScanLine  (int y, int offset, int length, char c)
 {
     _outputFile->breakScanLine (y, offset, length, c);
@@ -811,9 +812,9 @@ class RgbaInputFile::FromYca: public Mutex
     ~FromYca ();
 
     void               setFrameBuffer (Rgba *base,
-                    size_t xStride,
-                    size_t yStride,
-                    const string &channelNamePrefix);
+                                       size_t xStride,
+                                       size_t yStride,
+                                       const string &channelNamePrefix);
 
     void               readPixels (int scanLine1, int scanLine2);
 
@@ -846,7 +847,7 @@ class RgbaInputFile::FromYca: public Mutex
 
 
 RgbaInputFile::FromYca::FromYca (InputFile &inputFile,
-                 RgbaChannels rgbaChannels)
+                                RgbaChannels rgbaChannels)
 :
     _inputFile (inputFile)
 {
@@ -868,10 +869,10 @@ RgbaInputFile::FromYca::FromYca (InputFile &inputFile,
     _bufBase = new Rgba[(_width + pad) * (N + 2 + 3)];
 
     for (int i = 0; i < N + 2; ++i)
-    _buf1[i] = _bufBase + (i * (_width + pad));
-
+       _buf1[i] = _bufBase + (i * (_width + pad));
+    
     for (int i = 0; i < 3; ++i)
-    _buf2[i] = _bufBase + ((i + N + 2) * (_width + pad));
+       _buf2[i] = _bufBase + ((i + N + 2) * (_width + pad));
 
     _tmpBuf = new Rgba[_width + N - 1];
 
@@ -890,54 +891,54 @@ RgbaInputFile::FromYca::~FromYca ()
 
 void
 RgbaInputFile::FromYca::setFrameBuffer (Rgba *base,
-                    size_t xStride,
-                    size_t yStride,
-                    const string &channelNamePrefix)
+                                       size_t xStride,
+                                       size_t yStride,
+                                       const string &channelNamePrefix)
 {
     if (_fbBase == 0)
     {
-    FrameBuffer fb;
-
-    fb.insert (channelNamePrefix + "Y",
-           Slice (HALF,                                        // type
-              (char *) &_tmpBuf[N2 - _xMin].g, // base
-              sizeof (Rgba),                   // xStride
-              0,                                       // yStride
-              1,                                       // xSampling
-              1,                                       // ySampling
-              0.5));                           // fillValue
-
-    if (_readC)
-    {
-        fb.insert (channelNamePrefix + "RY",
-               Slice (HALF,                            // type
-                  (char *) &_tmpBuf[N2 - _xMin].r,     // base
-                  sizeof (Rgba) * 2,           // xStride
-                  0,                           // yStride
-                  2,                           // xSampling
-                  2,                           // ySampling
-                  0.0));                               // fillValue
-
-        fb.insert (channelNamePrefix + "BY",
-               Slice (HALF,                            // type
-                  (char *) &_tmpBuf[N2 - _xMin].b,     // base
-                  sizeof (Rgba) * 2,           // xStride
-                  0,                           // yStride
-                  2,                           // xSampling
-                  2,                           // ySampling
-                  0.0));                               // fillValue
-    }
-
-    fb.insert (channelNamePrefix + "A",
-           Slice (HALF,                                        // type
-              (char *) &_tmpBuf[N2 - _xMin].a, // base
-              sizeof (Rgba),                   // xStride
-              0,                                       // yStride
-              1,                                       // xSampling
-              1,                                       // ySampling
-              1.0));                           // fillValue
-
-    _inputFile.setFrameBuffer (fb);
+       FrameBuffer fb;
+
+       fb.insert (channelNamePrefix + "Y",
+                  Slice (HALF,                                 // type
+                         (char *) &_tmpBuf[N2 - _xMin].g,      // base
+                         sizeof (Rgba),                        // xStride
+                         0,                                    // yStride
+                         1,                                    // xSampling
+                         1,                                    // ySampling
+                         0.5));                                // fillValue
+
+       if (_readC)
+       {
+           fb.insert (channelNamePrefix + "RY",
+                      Slice (HALF,                             // type
+                             (char *) &_tmpBuf[N2 - _xMin].r,  // base
+                             sizeof (Rgba) * 2,                // xStride
+                             0,                                // yStride
+                             2,                                // xSampling
+                             2,                                // ySampling
+                             0.0));                            // fillValue
+
+           fb.insert (channelNamePrefix + "BY",
+                      Slice (HALF,                             // type
+                             (char *) &_tmpBuf[N2 - _xMin].b,  // base
+                             sizeof (Rgba) * 2,                // xStride
+                             0,                                // yStride
+                             2,                                // xSampling
+                             2,                                // ySampling
+                             0.0));                            // fillValue
+       }
+
+       fb.insert (channelNamePrefix + "A",
+                  Slice (HALF,                                 // type
+                         (char *) &_tmpBuf[N2 - _xMin].a,      // base
+                         sizeof (Rgba),                        // xStride
+                         0,                                    // yStride
+                         1,                                    // xSampling
+                         1,                                    // ySampling
+                         1.0));                                // fillValue
+
+       _inputFile.setFrameBuffer (fb);
     }
 
     _fbBase = base;
@@ -946,7 +947,7 @@ RgbaInputFile::FromYca::setFrameBuffer (Rgba *base,
 }
 
 
-void
+void   
 RgbaInputFile::FromYca::readPixels (int scanLine1, int scanLine2)
 {
     int minY = min (scanLine1, scanLine2);
@@ -954,25 +955,25 @@ RgbaInputFile::FromYca::readPixels (int scanLine1, int scanLine2)
 
     if (_lineOrder == INCREASING_Y)
     {
-    for (int y = minY; y <= maxY; ++y)
-        readPixels (y);
+       for (int y = minY; y <= maxY; ++y)
+           readPixels (y);
     }
     else
     {
-    for (int y = maxY; y >= minY; --y)
-        readPixels (y);
+       for (int y = maxY; y >= minY; --y)
+           readPixels (y);
     }
 }
 
 
-void
+void   
 RgbaInputFile::FromYca::readPixels (int scanLine)
 {
     if (_fbBase == 0)
     {
-    THROW (Iex::ArgExc, "No frame buffer was specified as the "
-                "pixel data destination for image file "
-                "\"" << _inputFile.fileName() << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
+                           "pixel data destination for image file "
+                           "\"" << _inputFile.fileName() << "\".");
     }
 
     //
@@ -1007,70 +1008,70 @@ RgbaInputFile::FromYca::readPixels (int scanLine)
     int dy = scanLine - _currentScanLine;
 
     if (abs (dy) < N + 2)
-    rotateBuf1 (dy);
+       rotateBuf1 (dy);
 
     if (abs (dy) < 3)
-    rotateBuf2 (dy);
+       rotateBuf2 (dy);
 
     if (dy < 0)
     {
-    {
-        int n = min (-dy, N + 2);
-        int yMin = scanLine - N2 - 1;
-
-        for (int i = n - 1; i >= 0; --i)
-        readYCAScanLine (yMin + i, _buf1[i]);
-    }
-
-    {
-        int n = min (-dy, 3);
-
-        for (int i = 0; i < n; ++i)
-        {
-        if ((scanLine + i) & 1)
-        {
-            YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
-        }
-        else
-        {
-            reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
-            YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
-        }
-        }
-    }
+       {
+           int n = min (-dy, N + 2);
+           int yMin = scanLine - N2 - 1;
+
+           for (int i = n - 1; i >= 0; --i)
+               readYCAScanLine (yMin + i, _buf1[i]);
+       }
+
+       {
+           int n = min (-dy, 3);
+
+           for (int i = 0; i < n; ++i)
+           {
+               if ((scanLine + i) & 1)
+               {
+                   YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
+               }
+               else
+               {
+                   reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
+                   YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
+               }
+           }
+       }
     }
     else
     {
-    {
-        int n = min (dy, N + 2);
-        int yMax = scanLine + N2 + 1;
-
-        for (int i = n - 1; i >= 0; --i)
-        readYCAScanLine (yMax - i, _buf1[N + 1 - i]);
-    }
-
-    {
-        int n = min (dy, 3);
-
-        for (int i = 2; i > 2 - n; --i)
-        {
-        if ((scanLine + i) & 1)
-        {
-            YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
-        }
-        else
-        {
-            reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
-            YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
-        }
-        }
-    }
+       {
+           int n = min (dy, N + 2);
+           int yMax = scanLine + N2 + 1;
+
+           for (int i = n - 1; i >= 0; --i)
+               readYCAScanLine (yMax - i, _buf1[N + 1 - i]);
+       }
+
+       {
+           int n = min (dy, 3);
+
+           for (int i = 2; i > 2 - n; --i)
+           {
+               if ((scanLine + i) & 1)
+               {
+                   YCAtoRGBA (_yw, _width, _buf1[N2 + i], _buf2[i]);
+               }
+               else
+               {
+                   reconstructChromaVert (_width, _buf1 + i, _buf2[i]);
+                   YCAtoRGBA (_yw, _width, _buf2[i], _buf2[i]);
+               }
+           }
+       }
     }
 
     fixSaturation (_yw, _width, _buf2, _tmpBuf);
 
     for (int i = 0; i < _width; ++i)
-    _fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i];
+       _fbBase[_fbYStride * scanLine + _fbXStride * (i + _xMin)] = _tmpBuf[i];
 
     _currentScanLine = scanLine;
 }
@@ -1084,10 +1085,10 @@ RgbaInputFile::FromYca::rotateBuf1 (int d)
     Rgba *tmp[N + 2];
 
     for (int i = 0; i < N + 2; ++i)
-    tmp[i] = _buf1[i];
+       tmp[i] = _buf1[i];
 
     for (int i = 0; i < N + 2; ++i)
-    _buf1[i] = tmp[(i + d) % (N + 2)];
+       _buf1[i] = tmp[(i + d) % (N + 2)];
 }
 
 
@@ -1099,10 +1100,10 @@ RgbaInputFile::FromYca::rotateBuf2 (int d)
     Rgba *tmp[3];
 
     for (int i = 0; i < 3; ++i)
-    tmp[i] = _buf2[i];
+       tmp[i] = _buf2[i];
 
     for (int i = 0; i < 3; ++i)
-    _buf2[i] = tmp[(i + d) % 3];
+       _buf2[i] = tmp[(i + d) % 3];
 }
 
 
@@ -1114,9 +1115,9 @@ RgbaInputFile::FromYca::readYCAScanLine (int y, Rgba *buf)
     //
 
     if (y < _yMin)
-    y = _yMin;
+       y = _yMin;
     else if (y > _yMax)
-    y = _yMax - 1;
+       y = _yMax - 1;
 
     //
     // Read scan line y into _tmpBuf.
@@ -1131,21 +1132,21 @@ RgbaInputFile::FromYca::readYCAScanLine (int y, Rgba *buf)
 
     if (!_readC)
     {
-    for (int i = 0; i < _width; ++i)
-    {
-        _tmpBuf[i + N2].r = 0;
-        _tmpBuf[i + N2].b = 0;
-    }
+       for (int i = 0; i < _width; ++i)
+       {
+           _tmpBuf[i + N2].r = 0;
+           _tmpBuf[i + N2].b = 0;
+       }
     }
 
     if (y & 1)
     {
-    memcpy (buf, _tmpBuf + N2, _width * sizeof (Rgba));
+       memcpy (buf, _tmpBuf + N2, _width * sizeof (Rgba));
     }
     else
     {
-    padTmpBuf();
-    reconstructChromaHoriz (_width, _tmpBuf, buf);
+       padTmpBuf();
+       reconstructChromaHoriz (_width, _tmpBuf, buf);
     }
 }
 
@@ -1155,8 +1156,8 @@ RgbaInputFile::FromYca::padTmpBuf ()
 {
     for (int i = 0; i < N2; ++i)
     {
-    _tmpBuf[i] = _tmpBuf[N2];
-    _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
+       _tmpBuf[i] = _tmpBuf[N2];
+       _tmpBuf[_width + N2 + i] = _tmpBuf[_width + N2 - 2];
     }
 }
 
@@ -1169,11 +1170,11 @@ RgbaInputFile::RgbaInputFile (const char name[], int numThreads):
     RgbaChannels rgbaChannels = channels();
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _fromYca = new FromYca (*_inputFile, rgbaChannels);
+       _fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
 
-RgbaInputFile::RgbaInputFile (IStream &is, int numThreads):
+RgbaInputFile::RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
     _inputFile (new InputFile (is, numThreads)),
     _fromYca (0),
     _channelNamePrefix ("")
@@ -1181,13 +1182,13 @@ RgbaInputFile::RgbaInputFile (IStream &is, int numThreads):
     RgbaChannels rgbaChannels = channels();
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _fromYca = new FromYca (*_inputFile, rgbaChannels);
+       _fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
 
 RgbaInputFile::RgbaInputFile (const char name[],
-                  const string &layerName,
-                  int numThreads)
+                             const string &layerName,
+                             int numThreads)
 :
     _inputFile (new InputFile (name, numThreads)),
     _fromYca (0),
@@ -1196,13 +1197,13 @@ RgbaInputFile::RgbaInputFile (const char name[],
     RgbaChannels rgbaChannels = channels();
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _fromYca = new FromYca (*_inputFile, rgbaChannels);
+       _fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
 
-RgbaInputFile::RgbaInputFile (IStream &is,
-                  const string &layerName,
-                  int numThreads)
+RgbaInputFile::RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                             const string &layerName,
+                             int numThreads)
 :
     _inputFile (new InputFile (is, numThreads)),
     _fromYca (0),
@@ -1211,7 +1212,7 @@ RgbaInputFile::RgbaInputFile (IStream &is,
     RgbaChannels rgbaChannels = channels();
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _fromYca = new FromYca (*_inputFile, rgbaChannels);
+       _fromYca = new FromYca (*_inputFile, rgbaChannels);
 }
 
 
@@ -1222,50 +1223,50 @@ RgbaInputFile::~RgbaInputFile ()
 }
 
 
-void
+void   
 RgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
 {
     if (_fromYca)
     {
-    Lock lock (*_fromYca);
-    _fromYca->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
+       Lock lock (*_fromYca);
+       _fromYca->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
     }
     else
     {
-    size_t xs = xStride * sizeof (Rgba);
-    size_t ys = yStride * sizeof (Rgba);
-
-    FrameBuffer fb;
-
-    fb.insert (_channelNamePrefix + "R",
-           Slice (HALF,
-              (char *) &base[0].r,
-              xs, ys,
-              1, 1,            // xSampling, ySampling
-              0.0));   // fillValue
-
-    fb.insert (_channelNamePrefix + "G",
-           Slice (HALF,
-              (char *) &base[0].g,
-              xs, ys,
-              1, 1,            // xSampling, ySampling
-              0.0));   // fillValue
-
-    fb.insert (_channelNamePrefix + "B",
-           Slice (HALF,
-              (char *) &base[0].b,
-              xs, ys,
-              1, 1,            // xSampling, ySampling
-              0.0));   // fillValue
-
-    fb.insert (_channelNamePrefix + "A",
-           Slice (HALF,
-              (char *) &base[0].a,
-              xs, ys,
-              1, 1,            // xSampling, ySampling
-              1.0));   // fillValue
-
-    _inputFile->setFrameBuffer (fb);
+       size_t xs = xStride * sizeof (Rgba);
+       size_t ys = yStride * sizeof (Rgba);
+
+       FrameBuffer fb;
+
+       fb.insert (_channelNamePrefix + "R",
+                  Slice (HALF,
+                         (char *) &base[0].r,
+                         xs, ys,
+                         1, 1,         // xSampling, ySampling
+                         0.0));        // fillValue
+
+       fb.insert (_channelNamePrefix + "G",
+                  Slice (HALF,
+                         (char *) &base[0].g,
+                         xs, ys,
+                         1, 1,         // xSampling, ySampling
+                         0.0));        // fillValue
+
+       fb.insert (_channelNamePrefix + "B",
+                  Slice (HALF,
+                         (char *) &base[0].b,
+                         xs, ys,
+                         1, 1,         // xSampling, ySampling
+                         0.0));        // fillValue
+
+       fb.insert (_channelNamePrefix + "A",
+                  Slice (HALF,
+                         (char *) &base[0].a,
+                         xs, ys,
+                         1, 1,         // xSampling, ySampling
+                         1.0));        // fillValue
+
+       _inputFile->setFrameBuffer (fb);
     }
 }
 
@@ -1281,29 +1282,29 @@ RgbaInputFile::setLayerName (const string &layerName)
     RgbaChannels rgbaChannels = channels();
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
-    _fromYca = new FromYca (*_inputFile, rgbaChannels);
+       _fromYca = new FromYca (*_inputFile, rgbaChannels);
 
     FrameBuffer fb;
     _inputFile->setFrameBuffer (fb);
 }
 
 
-void
+void   
 RgbaInputFile::readPixels (int scanLine1, int scanLine2)
 {
     if (_fromYca)
     {
-    Lock lock (*_fromYca);
-    _fromYca->readPixels (scanLine1, scanLine2);
+       Lock lock (*_fromYca);
+       _fromYca->readPixels (scanLine1, scanLine2);
     }
     else
     {
-    _inputFile->readPixels (scanLine1, scanLine2);
+       _inputFile->readPixels (scanLine1, scanLine2);
     }
 }
 
 
-void
+void   
 RgbaInputFile::readPixels (int scanLine)
 {
     readPixels (scanLine, scanLine);
@@ -1331,42 +1332,42 @@ RgbaInputFile::fileName () const
 }
 
 
-const FrameBuffer &
+const FrameBuffer &    
 RgbaInputFile::frameBuffer () const
 {
     return _inputFile->frameBuffer();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaInputFile::displayWindow () const
 {
     return _inputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 RgbaInputFile::dataWindow () const
 {
     return _inputFile->header().dataWindow();
 }
 
 
-float
+float  
 RgbaInputFile::pixelAspectRatio () const
 {
     return _inputFile->header().pixelAspectRatio();
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f     
 RgbaInputFile::screenWindowCenter () const
 {
     return _inputFile->header().screenWindowCenter();
 }
 
 
-float
+float  
 RgbaInputFile::screenWindowWidth () const
 {
     return _inputFile->header().screenWindowWidth();
@@ -1387,7 +1388,7 @@ RgbaInputFile::compression () const
 }
 
 
-RgbaChannels
+RgbaChannels   
 RgbaInputFile::channels () const
 {
     return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix);
@@ -1401,4 +1402,4 @@ RgbaInputFile::version () const
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 95e79d3..ace1859 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfRgba.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfRgba.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "half.h"
-#include <ImfThreading.h>
+#include "ImfThreading.h"
 #include <string>
+#include "ImfNamespace.h"
+#include "ImfForward.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class OutputFile;
-class InputFile;
-struct PreviewRgba;
 
 //
 // RGBA output file.
@@ -75,9 +73,10 @@ class RgbaOutputFile
     // Constructor -- header is constructed by the caller
     //---------------------------------------------------
 
+    IMF_EXPORT
     RgbaOutputFile (const char name[],
-            const Header &header,
-            RgbaChannels rgbaChannels = WRITE_RGBA,
+                   const Header &header,
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
                     int numThreads = globalThreadCount());
 
 
@@ -87,9 +86,10 @@ class RgbaOutputFile
     // automatically close the file.
     //----------------------------------------------------
 
-    RgbaOutputFile (OStream &os,
-            const Header &header,
-            RgbaChannels rgbaChannels = WRITE_RGBA,
+    IMF_EXPORT
+    RgbaOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                   const Header &header,
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
                     int numThreads = globalThreadCount());
 
 
@@ -98,15 +98,16 @@ class RgbaOutputFile
     // call arguments (empty dataWindow means "same as displayWindow")
     //----------------------------------------------------------------
 
+    IMF_EXPORT
     RgbaOutputFile (const char name[],
-            const Imath::Box2i &displayWindow,
-            const Imath::Box2i &dataWindow = Imath::Box2i(),
-            RgbaChannels rgbaChannels = WRITE_RGBA,
-            float pixelAspectRatio = 1,
-            const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
-            float screenWindowWidth = 1,
-            LineOrder lineOrder = INCREASING_Y,
-            Compression compression = PIZ_COMPRESSION,
+                   const IMATH_NAMESPACE::Box2i &displayWindow,
+                   const IMATH_NAMESPACE::Box2i &dataWindow = IMATH_NAMESPACE::Box2i(),
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
+                   float pixelAspectRatio = 1,
+                   const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
+                   float screenWindowWidth = 1,
+                   LineOrder lineOrder = INCREASING_Y,
+                   Compression compression = PIZ_COMPRESSION,
                     int numThreads = globalThreadCount());
 
 
@@ -116,15 +117,16 @@ class RgbaOutputFile
     // Box2i (V2i (0, 0), V2i (width - 1, height -1))
     //-----------------------------------------------
 
+    IMF_EXPORT
     RgbaOutputFile (const char name[],
-            int width,
-            int height,
-            RgbaChannels rgbaChannels = WRITE_RGBA,
-            float pixelAspectRatio = 1,
-            const Imath::V2f screenWindowCenter = Imath::V2f (0, 0),
-            float screenWindowWidth = 1,
-            LineOrder lineOrder = INCREASING_Y,
-            Compression compression = PIZ_COMPRESSION,
+                   int width,
+                   int height,
+                   RgbaChannels rgbaChannels = WRITE_RGBA,
+                   float pixelAspectRatio = 1,
+                   const IMATH_NAMESPACE::V2f screenWindowCenter = IMATH_NAMESPACE::V2f (0, 0),
+                   float screenWindowWidth = 1,
+                   LineOrder lineOrder = INCREASING_Y,
+                   Compression compression = PIZ_COMPRESSION,
                     int numThreads = globalThreadCount());
 
 
@@ -132,6 +134,7 @@ class RgbaOutputFile
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~RgbaOutputFile ();
 
 
@@ -143,16 +146,19 @@ class RgbaOutputFile
     //
     //------------------------------------------------
 
+    IMF_EXPORT
     void                       setFrameBuffer (const Rgba *base,
-                        size_t xStride,
-                        size_t yStride);
+                                               size_t xStride,
+                                               size_t yStride);
 
 
     //---------------------------------------------
     // Write pixel data (see class Imf::OutputFile)
     //---------------------------------------------
 
+    IMF_EXPORT
     void                       writePixels (int numScanLines = 1);
+    IMF_EXPORT
     int                                currentScanLine () const;
 
 
@@ -160,15 +166,25 @@ class RgbaOutputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &             header () const;
+    IMF_EXPORT
     const FrameBuffer &                frameBuffer () const;
-    const Imath::Box2i &       displayWindow () const;
-    const Imath::Box2i &       dataWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     displayWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     dataWindow () const;
+    IMF_EXPORT
     float                      pixelAspectRatio () const;
-    const Imath::V2f           screenWindowCenter () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::V2f         screenWindowCenter () const;
+    IMF_EXPORT
     float                      screenWindowWidth () const;
+    IMF_EXPORT
     LineOrder                  lineOrder () const;
+    IMF_EXPORT
     Compression                        compression () const;
+    IMF_EXPORT
     RgbaChannels               channels () const;
 
 
@@ -176,6 +192,7 @@ class RgbaOutputFile
     // Update the preview image (see Imf::OutputFile::updatePreviewImage())
     // --------------------------------------------------------------------
 
+    IMF_EXPORT
     void                       updatePreviewImage (const PreviewRgba[]);
 
 
@@ -193,8 +210,9 @@ class RgbaOutputFile
     // without chroma, then no rounding is performed.
     //-----------------------------------------------------------------------
 
+    IMF_EXPORT
     void                       setYCRounding (unsigned int roundY,
-                           unsigned int roundC);
+                                              unsigned int roundC);
 
 
     //----------------------------------------------------
@@ -207,10 +225,11 @@ class RgbaOutputFile
     //
     //----------------------------------------------------
 
+    IMF_EXPORT
     void                       breakScanLine  (int y,
-                        int offset,
-                        int length,
-                        char c);
+                                               int offset,
+                                               int length,
+                                               char c);
   private:
 
     RgbaOutputFile (const RgbaOutputFile &);             // not implemented
@@ -236,6 +255,7 @@ class RgbaInputFile
     // destructor will automatically close the file.
     //-------------------------------------------------------
 
+    IMF_EXPORT
     RgbaInputFile (const char name[], int numThreads = globalThreadCount());
 
 
@@ -246,7 +266,8 @@ class RgbaInputFile
     // close the file.
     //-----------------------------------------------------------
 
-    RgbaInputFile (IStream &is, int numThreads = globalThreadCount());
+    IMF_EXPORT
+    RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount());
 
 
     //--------------------------------------------------------------
@@ -255,19 +276,22 @@ class RgbaInputFile
     // are expected to be layerName.R, layerName.G, etc.
     //--------------------------------------------------------------
 
+    IMF_EXPORT
     RgbaInputFile (const char name[],
-           const std::string &layerName,
-           int numThreads = globalThreadCount());
+                  const std::string &layerName,
+                  int numThreads = globalThreadCount());
 
-    RgbaInputFile (IStream &is,
-           const std::string &layerName,
-           int numThreads = globalThreadCount());
+    IMF_EXPORT
+    RgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                  const std::string &layerName,
+                  int numThreads = globalThreadCount());
 
 
     //-----------
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~RgbaInputFile ();
 
 
@@ -279,9 +303,10 @@ class RgbaInputFile
     //
     //-----------------------------------------------------
 
+    IMF_EXPORT
     void                       setFrameBuffer (Rgba *base,
-                        size_t xStride,
-                        size_t yStride);
+                                               size_t xStride,
+                                               size_t yStride);
 
 
     //----------------------------------------------------------------
@@ -291,6 +316,7 @@ class RgbaInputFile
     // called at least once before the next call to readPixels().
     //----------------------------------------------------------------
 
+    IMF_EXPORT
     void                       setLayerName (const std::string &layerName);
 
 
@@ -298,7 +324,9 @@ class RgbaInputFile
     // Read pixel data (see class Imf::InputFile)
     //-------------------------------------------
 
+    IMF_EXPORT
     void                       readPixels (int scanLine1, int scanLine2);
+    IMF_EXPORT
     void                       readPixels (int scanLine);
 
 
@@ -306,17 +334,29 @@ class RgbaInputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &             header () const;
+    IMF_EXPORT
     const FrameBuffer &                frameBuffer () const;
-    const Imath::Box2i &       displayWindow () const;
-    const Imath::Box2i &       dataWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     displayWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     dataWindow () const;
+    IMF_EXPORT
     float                      pixelAspectRatio () const;
-    const Imath::V2f           screenWindowCenter () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::V2f         screenWindowCenter () const;
+    IMF_EXPORT
     float                      screenWindowWidth () const;
+    IMF_EXPORT
     LineOrder                  lineOrder () const;
+    IMF_EXPORT
     Compression                        compression () const;
+    IMF_EXPORT
     RgbaChannels               channels () const;
+    IMF_EXPORT
     const char *                fileName () const;
+    IMF_EXPORT
     bool                       isComplete () const;
 
 
@@ -324,6 +364,7 @@ class RgbaInputFile
     // Access to the file format version
     //----------------------------------
 
+    IMF_EXPORT
     int                                version () const;
 
   private:
@@ -339,6 +380,10 @@ class RgbaInputFile
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index e1f3340..c6212f3 100644 (file)
 #include <assert.h>
 #include <algorithm>
 
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace RgbaYca {
 
 
@@ -63,78 +65,78 @@ computeYw (const Chromaticities &cr)
 
 void
 RGBAtoYCA (const V3f &yw,
-       int n,
-       bool aIsValid,
-       const Rgba rgbaIn[/*n*/],
-       Rgba ycaOut[/*n*/])
+          int n,
+          bool aIsValid,
+          const Rgba rgbaIn[/*n*/],
+          Rgba ycaOut[/*n*/])
 {
     for (int i = 0; i < n; ++i)
     {
-    Rgba in = rgbaIn[i];
-    Rgba &out = ycaOut[i];
-
-    //
-    // Conversion to YCA and subsequent chroma subsampling
-    // work only if R, G and B are finite and non-negative.
-    //
-
-    if (!in.r.isFinite() || in.r < 0)
-        in.r = 0;
-
-    if (!in.g.isFinite() || in.g < 0)
-        in.g = 0;
-
-    if (!in.b.isFinite() || in.b < 0)
-        in.b = 0;
-
-    if (in.r == in.g && in.g == in.b)
-    {
-        //
-        // Special case -- R, G and B are equal. To avoid rounding
-        // errors, we explicitly set the output luminance channel
-        // to G, and the chroma channels to 0.
-        //
-        // The special cases here and in YCAtoRGBA() ensure that
-        // converting black-and white images from RGBA to YCA and
-        // back is lossless.
-        //
-
-        out.r = 0;
-        out.g = in.g;
-        out.b = 0;
-    }
-    else
-    {
-        out.g = in.r * yw.x + in.g * yw.y + in.b * yw.z;
-
-        float Y = out.g;
-
-        if (abs (in.r - Y) < HALF_MAX * Y)
-        out.r = (in.r - Y) / Y;
-        else
-        out.r = 0;
-
-        if (abs (in.b - Y) < HALF_MAX * Y)
-        out.b = (in.b - Y) / Y;
-        else
-        out.b = 0;
-    }
-
-    if (aIsValid)
-        out.a = in.a;
-    else
-        out.a = 1;
+       Rgba in = rgbaIn[i];
+       Rgba &out = ycaOut[i];
+
+       //
+       // Conversion to YCA and subsequent chroma subsampling
+       // work only if R, G and B are finite and non-negative.
+       //
+
+       if (!in.r.isFinite() || in.r < 0)
+           in.r = 0;
+
+       if (!in.g.isFinite() || in.g < 0)
+           in.g = 0;
+
+       if (!in.b.isFinite() || in.b < 0)
+           in.b = 0;
+
+       if (in.r == in.g && in.g == in.b)
+       {
+           //
+           // Special case -- R, G and B are equal. To avoid rounding
+           // errors, we explicitly set the output luminance channel
+           // to G, and the chroma channels to 0.
+           //
+           // The special cases here and in YCAtoRGBA() ensure that
+           // converting black-and white images from RGBA to YCA and
+           // back is lossless.
+           //
+
+           out.r = 0;
+           out.g = in.g;
+           out.b = 0;
+       }
+       else
+       {
+           out.g = in.r * yw.x + in.g * yw.y + in.b * yw.z;
+
+           float Y = out.g;
+
+           if (abs (in.r - Y) < HALF_MAX * Y)
+               out.r = (in.r - Y) / Y;
+           else
+               out.r = 0;
+
+           if (abs (in.b - Y) < HALF_MAX * Y)
+               out.b = (in.b - Y) / Y;
+           else
+               out.b = 0;
+       }
+
+       if (aIsValid)
+           out.a = in.a;
+       else
+           out.a = 1;
     }
 }
 
 
 void
 decimateChromaHoriz (int n,
-             const Rgba ycaIn[/*n+N-1*/],
-             Rgba ycaOut[/*n*/])
+                    const Rgba ycaIn[/*n+N-1*/],
+                    Rgba ycaOut[/*n*/])
 {
     #ifdef DEBUG
-    assert (ycaIn != ycaOut);
+       assert (ycaIn != ycaOut);
     #endif
 
     int begin = N2;
@@ -142,123 +144,123 @@ decimateChromaHoriz (int n,
 
     for (int i = begin, j = 0; i < end; ++i, ++j)
     {
-    if ((j & 1) == 0)
-    {
-        ycaOut[j].r = ycaIn[i - 13].r *  0.001064f +
-              ycaIn[i - 11].r * -0.003771f +
-              ycaIn[i -  9].r *  0.009801f +
-              ycaIn[i -  7].r * -0.021586f +
-              ycaIn[i -  5].r *  0.043978f +
-              ycaIn[i -  3].r * -0.093067f +
-              ycaIn[i -  1].r *  0.313659f +
-              ycaIn[i     ].r *  0.499846f +
-              ycaIn[i +  1].r *  0.313659f +
-              ycaIn[i +  3].r * -0.093067f +
-              ycaIn[i +  5].r *  0.043978f +
-              ycaIn[i +  7].r * -0.021586f +
-              ycaIn[i +  9].r *  0.009801f +
-              ycaIn[i + 11].r * -0.003771f +
-              ycaIn[i + 13].r *  0.001064f;
-
-        ycaOut[j].b = ycaIn[i - 13].b *  0.001064f +
-              ycaIn[i - 11].b * -0.003771f +
-              ycaIn[i -  9].b *  0.009801f +
-              ycaIn[i -  7].b * -0.021586f +
-              ycaIn[i -  5].b *  0.043978f +
-              ycaIn[i -  3].b * -0.093067f +
-              ycaIn[i -  1].b *  0.313659f +
-              ycaIn[i     ].b *  0.499846f +
-              ycaIn[i +  1].b *  0.313659f +
-              ycaIn[i +  3].b * -0.093067f +
-              ycaIn[i +  5].b *  0.043978f +
-              ycaIn[i +  7].b * -0.021586f +
-              ycaIn[i +  9].b *  0.009801f +
-              ycaIn[i + 11].b * -0.003771f +
-              ycaIn[i + 13].b *  0.001064f;
-    }
-
-    ycaOut[j].g = ycaIn[i].g;
-    ycaOut[j].a = ycaIn[i].a;
+       if ((j & 1) == 0)
+       {
+           ycaOut[j].r = ycaIn[i - 13].r *  0.001064f +
+                         ycaIn[i - 11].r * -0.003771f +
+                         ycaIn[i -  9].r *  0.009801f +
+                         ycaIn[i -  7].r * -0.021586f +
+                         ycaIn[i -  5].r *  0.043978f +
+                         ycaIn[i -  3].r * -0.093067f +
+                         ycaIn[i -  1].r *  0.313659f +
+                         ycaIn[i     ].r *  0.499846f +
+                         ycaIn[i +  1].r *  0.313659f +
+                         ycaIn[i +  3].r * -0.093067f +
+                         ycaIn[i +  5].r *  0.043978f +
+                         ycaIn[i +  7].r * -0.021586f +
+                         ycaIn[i +  9].r *  0.009801f +
+                         ycaIn[i + 11].r * -0.003771f +
+                         ycaIn[i + 13].r *  0.001064f;
+
+           ycaOut[j].b = ycaIn[i - 13].b *  0.001064f +
+                         ycaIn[i - 11].b * -0.003771f +
+                         ycaIn[i -  9].b *  0.009801f +
+                         ycaIn[i -  7].b * -0.021586f +
+                         ycaIn[i -  5].b *  0.043978f +
+                         ycaIn[i -  3].b * -0.093067f +
+                         ycaIn[i -  1].b *  0.313659f +
+                         ycaIn[i     ].b *  0.499846f +
+                         ycaIn[i +  1].b *  0.313659f +
+                         ycaIn[i +  3].b * -0.093067f +
+                         ycaIn[i +  5].b *  0.043978f +
+                         ycaIn[i +  7].b * -0.021586f +
+                         ycaIn[i +  9].b *  0.009801f +
+                         ycaIn[i + 11].b * -0.003771f +
+                         ycaIn[i + 13].b *  0.001064f;
+       }
+
+       ycaOut[j].g = ycaIn[i].g;
+       ycaOut[j].a = ycaIn[i].a;
     }
 }
 
 
 void
 decimateChromaVert (int n,
-            const Rgba * const ycaIn[N],
-            Rgba ycaOut[/*n*/])
+                   const Rgba * const ycaIn[N],
+                   Rgba ycaOut[/*n*/])
 {
     for (int i = 0; i < n; ++i)
     {
-    if ((i & 1) == 0)
-    {
-        ycaOut[i].r = ycaIn[ 0][i].r *  0.001064f +
-              ycaIn[ 2][i].r * -0.003771f +
-              ycaIn[ 4][i].r *  0.009801f +
-              ycaIn[ 6][i].r * -0.021586f +
-              ycaIn[ 8][i].r *  0.043978f +
-              ycaIn[10][i].r * -0.093067f +
-              ycaIn[12][i].r *  0.313659f +
-              ycaIn[13][i].r *  0.499846f +
-              ycaIn[14][i].r *  0.313659f +
-              ycaIn[16][i].r * -0.093067f +
-              ycaIn[18][i].r *  0.043978f +
-              ycaIn[20][i].r * -0.021586f +
-              ycaIn[22][i].r *  0.009801f +
-              ycaIn[24][i].r * -0.003771f +
-              ycaIn[26][i].r *  0.001064f;
-
-        ycaOut[i].b = ycaIn[ 0][i].b *  0.001064f +
-              ycaIn[ 2][i].b * -0.003771f +
-              ycaIn[ 4][i].b *  0.009801f +
-              ycaIn[ 6][i].b * -0.021586f +
-              ycaIn[ 8][i].b *  0.043978f +
-              ycaIn[10][i].b * -0.093067f +
-              ycaIn[12][i].b *  0.313659f +
-              ycaIn[13][i].b *  0.499846f +
-              ycaIn[14][i].b *  0.313659f +
-              ycaIn[16][i].b * -0.093067f +
-              ycaIn[18][i].b *  0.043978f +
-              ycaIn[20][i].b * -0.021586f +
-              ycaIn[22][i].b *  0.009801f +
-              ycaIn[24][i].b * -0.003771f +
-              ycaIn[26][i].b *  0.001064f;
-    }
-
-    ycaOut[i].g = ycaIn[13][i].g;
-    ycaOut[i].a = ycaIn[13][i].a;
+       if ((i & 1) == 0)
+       {
+           ycaOut[i].r = ycaIn[ 0][i].r *  0.001064f +
+                         ycaIn[ 2][i].r * -0.003771f +
+                         ycaIn[ 4][i].r *  0.009801f +
+                         ycaIn[ 6][i].r * -0.021586f +
+                         ycaIn[ 8][i].r *  0.043978f +
+                         ycaIn[10][i].r * -0.093067f +
+                         ycaIn[12][i].r *  0.313659f +
+                         ycaIn[13][i].r *  0.499846f +
+                         ycaIn[14][i].r *  0.313659f +
+                         ycaIn[16][i].r * -0.093067f +
+                         ycaIn[18][i].r *  0.043978f +
+                         ycaIn[20][i].r * -0.021586f +
+                         ycaIn[22][i].r *  0.009801f +
+                         ycaIn[24][i].r * -0.003771f +
+                         ycaIn[26][i].r *  0.001064f;
+
+           ycaOut[i].b = ycaIn[ 0][i].b *  0.001064f +
+                         ycaIn[ 2][i].b * -0.003771f +
+                         ycaIn[ 4][i].b *  0.009801f +
+                         ycaIn[ 6][i].b * -0.021586f +
+                         ycaIn[ 8][i].b *  0.043978f +
+                         ycaIn[10][i].b * -0.093067f +
+                         ycaIn[12][i].b *  0.313659f +
+                         ycaIn[13][i].b *  0.499846f +
+                         ycaIn[14][i].b *  0.313659f +
+                         ycaIn[16][i].b * -0.093067f +
+                         ycaIn[18][i].b *  0.043978f +
+                         ycaIn[20][i].b * -0.021586f +
+                         ycaIn[22][i].b *  0.009801f +
+                         ycaIn[24][i].b * -0.003771f +
+                         ycaIn[26][i].b *  0.001064f;
+       }
+
+       ycaOut[i].g = ycaIn[13][i].g;
+       ycaOut[i].a = ycaIn[13][i].a;
     }
 }
 
 
 void
 roundYCA (int n,
-      unsigned int roundY,
-      unsigned int roundC,
-      const Rgba ycaIn[/*n*/],
-      Rgba ycaOut[/*n*/])
+         unsigned int roundY,
+         unsigned int roundC,
+         const Rgba ycaIn[/*n*/],
+         Rgba ycaOut[/*n*/])
 {
     for (int i = 0; i < n; ++i)
     {
-    ycaOut[i].g = ycaIn[i].g.round (roundY);
-    ycaOut[i].a = ycaIn[i].a;
-
-    if ((i & 1) == 0)
-    {
-        ycaOut[i].r = ycaIn[i].r.round (roundC);
-        ycaOut[i].b = ycaIn[i].b.round (roundC);
-    }
+       ycaOut[i].g = ycaIn[i].g.round (roundY);
+       ycaOut[i].a = ycaIn[i].a;
+
+       if ((i & 1) == 0)
+       {
+           ycaOut[i].r = ycaIn[i].r.round (roundC);
+           ycaOut[i].b = ycaIn[i].b.round (roundC);
+       }
     }
 }
 
 
 void
 reconstructChromaHoriz (int n,
-            const Rgba ycaIn[/*n+N-1*/],
-            Rgba ycaOut[/*n*/])
+                       const Rgba ycaIn[/*n+N-1*/],
+                       Rgba ycaOut[/*n*/])
 {
     #ifdef DEBUG
-    assert (ycaIn != ycaOut);
+       assert (ycaIn != ycaOut);
     #endif
 
     int begin = N2;
@@ -266,133 +268,133 @@ reconstructChromaHoriz (int n,
 
     for (int i = begin, j = 0; i < end; ++i, ++j)
     {
-    if (j & 1)
-    {
-        ycaOut[j].r = ycaIn[i - 13].r *  0.002128f +
-              ycaIn[i - 11].r * -0.007540f +
-              ycaIn[i -  9].r *  0.019597f +
-              ycaIn[i -  7].r * -0.043159f +
-              ycaIn[i -  5].r *  0.087929f +
-              ycaIn[i -  3].r * -0.186077f +
-              ycaIn[i -  1].r *  0.627123f +
-              ycaIn[i +  1].r *  0.627123f +
-              ycaIn[i +  3].r * -0.186077f +
-              ycaIn[i +  5].r *  0.087929f +
-              ycaIn[i +  7].r * -0.043159f +
-              ycaIn[i +  9].r *  0.019597f +
-              ycaIn[i + 11].r * -0.007540f +
-              ycaIn[i + 13].r *  0.002128f;
-
-        ycaOut[j].b = ycaIn[i - 13].b *  0.002128f +
-              ycaIn[i - 11].b * -0.007540f +
-              ycaIn[i -  9].b *  0.019597f +
-              ycaIn[i -  7].b * -0.043159f +
-              ycaIn[i -  5].b *  0.087929f +
-              ycaIn[i -  3].b * -0.186077f +
-              ycaIn[i -  1].b *  0.627123f +
-              ycaIn[i +  1].b *  0.627123f +
-              ycaIn[i +  3].b * -0.186077f +
-              ycaIn[i +  5].b *  0.087929f +
-              ycaIn[i +  7].b * -0.043159f +
-              ycaIn[i +  9].b *  0.019597f +
-              ycaIn[i + 11].b * -0.007540f +
-              ycaIn[i + 13].b *  0.002128f;
-    }
-    else
-    {
-        ycaOut[j].r = ycaIn[i].r;
-        ycaOut[j].b = ycaIn[i].b;
-    }
-
-    ycaOut[j].g = ycaIn[i].g;
-    ycaOut[j].a = ycaIn[i].a;
+       if (j & 1)
+       {
+           ycaOut[j].r = ycaIn[i - 13].r *  0.002128f +
+                         ycaIn[i - 11].r * -0.007540f +
+                         ycaIn[i -  9].r *  0.019597f +
+                         ycaIn[i -  7].r * -0.043159f +
+                         ycaIn[i -  5].r *  0.087929f +
+                         ycaIn[i -  3].r * -0.186077f +
+                         ycaIn[i -  1].r *  0.627123f +
+                         ycaIn[i +  1].r *  0.627123f +
+                         ycaIn[i +  3].r * -0.186077f +
+                         ycaIn[i +  5].r *  0.087929f +
+                         ycaIn[i +  7].r * -0.043159f +
+                         ycaIn[i +  9].r *  0.019597f +
+                         ycaIn[i + 11].r * -0.007540f +
+                         ycaIn[i + 13].r *  0.002128f;
+
+           ycaOut[j].b = ycaIn[i - 13].b *  0.002128f +
+                         ycaIn[i - 11].b * -0.007540f +
+                         ycaIn[i -  9].b *  0.019597f +
+                         ycaIn[i -  7].b * -0.043159f +
+                         ycaIn[i -  5].b *  0.087929f +
+                         ycaIn[i -  3].b * -0.186077f +
+                         ycaIn[i -  1].b *  0.627123f +
+                         ycaIn[i +  1].b *  0.627123f +
+                         ycaIn[i +  3].b * -0.186077f +
+                         ycaIn[i +  5].b *  0.087929f +
+                         ycaIn[i +  7].b * -0.043159f +
+                         ycaIn[i +  9].b *  0.019597f +
+                         ycaIn[i + 11].b * -0.007540f +
+                         ycaIn[i + 13].b *  0.002128f;
+       }
+       else
+       {
+           ycaOut[j].r = ycaIn[i].r;
+           ycaOut[j].b = ycaIn[i].b;
+       }
+
+       ycaOut[j].g = ycaIn[i].g;
+       ycaOut[j].a = ycaIn[i].a;
     }
 }
 
 
 void
 reconstructChromaVert (int n,
-               const Rgba * const ycaIn[N],
-               Rgba ycaOut[/*n*/])
+                      const Rgba * const ycaIn[N],
+                      Rgba ycaOut[/*n*/])
 {
     for (int i = 0; i < n; ++i)
     {
-    ycaOut[i].r = ycaIn[ 0][i].r *  0.002128f +
-              ycaIn[ 2][i].r * -0.007540f +
-              ycaIn[ 4][i].r *  0.019597f +
-              ycaIn[ 6][i].r * -0.043159f +
-              ycaIn[ 8][i].r *  0.087929f +
-              ycaIn[10][i].r * -0.186077f +
-              ycaIn[12][i].r *  0.627123f +
-              ycaIn[14][i].r *  0.627123f +
-              ycaIn[16][i].r * -0.186077f +
-              ycaIn[18][i].r *  0.087929f +
-              ycaIn[20][i].r * -0.043159f +
-              ycaIn[22][i].r *  0.019597f +
-              ycaIn[24][i].r * -0.007540f +
-              ycaIn[26][i].r *  0.002128f;
-
-    ycaOut[i].b = ycaIn[ 0][i].b *  0.002128f +
-              ycaIn[ 2][i].b * -0.007540f +
-              ycaIn[ 4][i].b *  0.019597f +
-              ycaIn[ 6][i].b * -0.043159f +
-              ycaIn[ 8][i].b *  0.087929f +
-              ycaIn[10][i].b * -0.186077f +
-              ycaIn[12][i].b *  0.627123f +
-              ycaIn[14][i].b *  0.627123f +
-              ycaIn[16][i].b * -0.186077f +
-              ycaIn[18][i].b *  0.087929f +
-              ycaIn[20][i].b * -0.043159f +
-              ycaIn[22][i].b *  0.019597f +
-              ycaIn[24][i].b * -0.007540f +
-              ycaIn[26][i].b *  0.002128f;
-
-    ycaOut[i].g = ycaIn[13][i].g;
-    ycaOut[i].a = ycaIn[13][i].a;
+       ycaOut[i].r = ycaIn[ 0][i].r *  0.002128f +
+                     ycaIn[ 2][i].r * -0.007540f +
+                     ycaIn[ 4][i].r *  0.019597f +
+                     ycaIn[ 6][i].r * -0.043159f +
+                     ycaIn[ 8][i].r *  0.087929f +
+                     ycaIn[10][i].r * -0.186077f +
+                     ycaIn[12][i].r *  0.627123f +
+                     ycaIn[14][i].r *  0.627123f +
+                     ycaIn[16][i].r * -0.186077f +
+                     ycaIn[18][i].r *  0.087929f +
+                     ycaIn[20][i].r * -0.043159f +
+                     ycaIn[22][i].r *  0.019597f +
+                     ycaIn[24][i].r * -0.007540f +
+                     ycaIn[26][i].r *  0.002128f;
+
+       ycaOut[i].b = ycaIn[ 0][i].b *  0.002128f +
+                     ycaIn[ 2][i].b * -0.007540f +
+                     ycaIn[ 4][i].b *  0.019597f +
+                     ycaIn[ 6][i].b * -0.043159f +
+                     ycaIn[ 8][i].b *  0.087929f +
+                     ycaIn[10][i].b * -0.186077f +
+                     ycaIn[12][i].b *  0.627123f +
+                     ycaIn[14][i].b *  0.627123f +
+                     ycaIn[16][i].b * -0.186077f +
+                     ycaIn[18][i].b *  0.087929f +
+                     ycaIn[20][i].b * -0.043159f +
+                     ycaIn[22][i].b *  0.019597f +
+                     ycaIn[24][i].b * -0.007540f +
+                     ycaIn[26][i].b *  0.002128f;
+
+       ycaOut[i].g = ycaIn[13][i].g;
+       ycaOut[i].a = ycaIn[13][i].a;
     }
 }
 
-
+                        
 void
-YCAtoRGBA (const Imath::V3f &yw,
-       int n,
-       const Rgba ycaIn[/*n*/],
-       Rgba rgbaOut[/*n*/])
+YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
+          int n,
+          const Rgba ycaIn[/*n*/],
+          Rgba rgbaOut[/*n*/])
 {
     for (int i = 0; i < n; ++i)
     {
-    const Rgba &in = ycaIn[i];
-    Rgba &out = rgbaOut[i];
-
-    if (in.r == 0 && in.b == 0)
-    {
-        //
-        // Special case -- both chroma channels are 0.  To avoid
-        // rounding errors, we explicitly set the output R, G and B
-        // channels equal to the input luminance.
-        //
-        // The special cases here and in RGBAtoYCA() ensure that
-        // converting black-and white images from RGBA to YCA and
-        // back is lossless.
-        //
-
-        out.r = in.g;
-        out.g = in.g;
-        out.b = in.g;
-        out.a = in.a;
-    }
-    else
-    {
-        float Y =  in.g;
-        float r = (in.r + 1) * Y;
-        float b = (in.b + 1) * Y;
-        float g = (Y - r * yw.x - b * yw.z) / yw.y;
-
-        out.r = r;
-        out.g = g;
-        out.b = b;
-        out.a = in.a;
-    }
+       const Rgba &in = ycaIn[i];
+       Rgba &out = rgbaOut[i];
+
+       if (in.r == 0 && in.b == 0)
+       {
+           //
+           // Special case -- both chroma channels are 0.  To avoid
+           // rounding errors, we explicitly set the output R, G and B
+           // channels equal to the input luminance.
+           //
+           // The special cases here and in RGBAtoYCA() ensure that
+           // converting black-and white images from RGBA to YCA and
+           // back is lossless.
+           //
+
+           out.r = in.g;
+           out.g = in.g;
+           out.b = in.g;
+           out.a = in.a;
+       }
+       else
+       {
+           float Y =  in.g;
+           float r = (in.r + 1) * Y;
+           float b = (in.b + 1) * Y;
+           float g = (Y - r * yw.x - b * yw.z) / yw.y;
+
+           out.r = r;
+           out.g = g;
+           out.b = b;
+           out.a = in.a;
+       }
     }
 }
 
@@ -406,9 +408,9 @@ saturation (const Rgba &in)
     float rgbMin = min (in.r, min (in.g, in.b));
 
     if (rgbMax > 0)
-    return 1 - rgbMin / rgbMax;
+       return 1 - rgbMin / rgbMax;
     else
-    return 0;
+       return 0;
 }
 
 
@@ -427,20 +429,20 @@ desaturate (const Rgba &in, float f, const V3f &yw, Rgba &out)
 
     if (Yout > 0)
     {
-    out.r *= Yin / Yout;
-    out.g *= Yin / Yout;
-    out.b *= Yin / Yout;
+       out.r *= Yin / Yout;
+       out.g *= Yin / Yout;
+       out.b *= Yin / Yout;
     }
 }
 
 } // namespace
 
-
+                        
 void
-fixSaturation (const Imath::V3f &yw,
-           int n,
-           const Rgba * const rgbaIn[3],
-           Rgba rgbaOut[/*n*/])
+fixSaturation (const IMATH_NAMESPACE::V3f &yw,
+              int n,
+              const Rgba * const rgbaIn[3],
+              Rgba rgbaOut[/*n*/])
 {
     float neighborA2 = saturation (rgbaIn[0][0]);
     float neighborA1 = neighborA2;
@@ -450,46 +452,46 @@ fixSaturation (const Imath::V3f &yw,
 
     for (int i = 0; i < n; ++i)
     {
-    float neighborA0 = neighborA1;
-    neighborA1 = neighborA2;
+       float neighborA0 = neighborA1;
+       neighborA1 = neighborA2;
 
-    float neighborB0 = neighborB1;
-    neighborB1 = neighborB2;
+       float neighborB0 = neighborB1;
+       neighborB1 = neighborB2;
 
-    if (i < n - 1)
-    {
-        neighborA2 = saturation (rgbaIn[0][i + 1]);
-        neighborB2 = saturation (rgbaIn[2][i + 1]);
-    }
+       if (i < n - 1)
+       {
+           neighborA2 = saturation (rgbaIn[0][i + 1]);
+           neighborB2 = saturation (rgbaIn[2][i + 1]);
+       }
 
-    //
-    // A0       A1       A2
-    //      rgbaOut[i]
-    // B0       B1       B2
-    //
+       //
+       // A0       A1       A2
+       //      rgbaOut[i]
+       // B0       B1       B2
+       //
 
-    float sMean = min (1.0f, 0.25f * (neighborA0 + neighborA2 +
-                      neighborB0 + neighborB2));
+       float sMean = min (1.0f, 0.25f * (neighborA0 + neighborA2 +
+                                         neighborB0 + neighborB2));
 
-    const Rgba &in  = rgbaIn[1][i];
-    Rgba &out = rgbaOut[i];
+       const Rgba &in  = rgbaIn[1][i];
+       Rgba &out = rgbaOut[i];
 
-    float s = saturation (in);
+       float s = saturation (in);
 
-    if (s > sMean)
-    {
-        float sMax = min (1.0f, 1 - (1 - sMean) * 0.25f);
+       if (s > sMean)
+       {
+           float sMax = min (1.0f, 1 - (1 - sMean) * 0.25f);
 
-        if (s > sMax)
-        {
-        desaturate (in, sMax / s, yw, out);
-        continue;
-        }
-    }
+           if (s > sMax)
+           {
+               desaturate (in, sMax / s, yw, out);
+               continue;
+           }
+       }
 
-    out = in;
+       out = in;
     }
 }
 
 } // namespace RgbaYca
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 8b894f5..c4c6775 100644 (file)
 //     Next, decimateChomaHoriz() eliminates the chroma values from
 //     the odd-numbered pixels in every scan line:
 //
-//             YCA  YA   YCA  YA   ... YCA  YA
-//             YCA  YA   YCA  YA   ... YCA  YA
-//             YCA  YA   YCA  YA   ... YCA  YA
-//             YCA  YA   YCA  YA   ... YCA  YA
+//             YCA  YA   YCA  YA   ... YCA  YA  
+//             YCA  YA   YCA  YA   ... YCA  YA  
+//             YCA  YA   YCA  YA   ... YCA  YA  
+//             YCA  YA   YCA  YA   ... YCA  YA  
 //             ...
-//             YCA  YA   YCA  YA   ... YCA  YA
-//             YCA  YA   YCA  YA   ... YCA  YA
+//             YCA  YA   YCA  YA   ... YCA  YA  
+//             YCA  YA   YCA  YA   ... YCA  YA  
 //
 //     decimateChromaVert() eliminates all chroma values from the
 //     odd-numbered scan lines:
 //
-//             YCA  YA   YCA  YA   ... YCA  YA
-//             YA   YA   YA   YA   ... YA   YA
-//             YCA  YA   YCA  YA   ... YCA  YA
-//             YA   YA   YA   YA   ... YA   YA
+//             YCA  YA   YCA  YA   ... YCA  YA  
+//             YA   YA   YA   YA   ... YA   YA  
+//             YCA  YA   YCA  YA   ... YCA  YA  
+//             YA   YA   YA   YA   ... YA   YA  
 //             ...
-//             YCA  YA   YCA  YA   ... YCA  YA
-//             YA   YA   YA   YA   ... YA   YA
+//             YCA  YA   YCA  YA   ... YCA  YA  
+//             YA   YA   YA   YA   ... YA   YA  
 //
 //     Finally, roundYCA() reduces the precision of the luminance
 //     and chroma values so that the pixel data shrink more when
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRgba.h>
-#include <ImfChromaticities.h>
+#include "ImfRgba.h"
+#include "ImfChromaticities.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 namespace RgbaYca {
 
 
@@ -133,8 +135,9 @@ static const int N2 = N / 2;
 // Convert a set of primary chromaticities into a set of weighting
 // factors for computing a pixels's luminance, Y, from R, G and B
 //
-
-Imath::V3f computeYw (const Chromaticities &cr);
+IMF_EXPORT
+IMATH_NAMESPACE::V3f computeYw (const Chromaticities &cr);
 
 
 //
@@ -148,11 +151,12 @@ Imath::V3f computeYw (const Chromaticities &cr);
 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
 //
 
-void RGBAtoYCA (const Imath::V3f &yw,
-        int n,
-            bool aIsValid,
-        const Rgba rgbaIn[/*n*/],
-        Rgba ycaOut[/*n*/]);
+IMF_EXPORT
+void RGBAtoYCA (const IMATH_NAMESPACE::V3f &yw,
+               int n,
+               bool aIsValid,
+               const Rgba rgbaIn[/*n*/],
+               Rgba ycaOut[/*n*/]);
 
 //
 // Perform horizontal low-pass filtering and subsampling of
@@ -164,9 +168,10 @@ void RGBAtoYCA (const Imath::V3f &yw,
 // "real" input pixel.
 //
 
+IMF_EXPORT
 void decimateChromaHoriz (int n,
-              const Rgba ycaIn[/*n+N-1*/],
-              Rgba ycaOut[/*n*/]);
+                         const Rgba ycaIn[/*n+N-1*/],
+                         Rgba ycaOut[/*n*/]);
 
 //
 // Perform vertical chroma channel low-pass filtering and subsampling.
@@ -174,9 +179,10 @@ void decimateChromaHoriz (int n,
 // of output pixels.
 //
 
+IMF_EXPORT
 void decimateChromaVert (int n,
-             const Rgba * const ycaIn[N],
-             Rgba ycaOut[/*n*/]);
+                        const Rgba * const ycaIn[N],
+                        Rgba ycaOut[/*n*/]);
 
 //
 // Round the luminance and chroma channels of an array of YCA
@@ -185,41 +191,45 @@ void decimateChromaVert (int n,
 // are rounded to roundY and roundC bits respectively.
 //
 
+IMF_EXPORT
 void roundYCA (int n,
-           unsigned int roundY,
-           unsigned int roundC,
-           const Rgba ycaIn[/*n*/],
-           Rgba ycaOut[/*n*/]);
+              unsigned int roundY,
+              unsigned int roundC,
+              const Rgba ycaIn[/*n*/],
+              Rgba ycaOut[/*n*/]);
 
 //
 // For a scan line that has valid chroma data only for every other pixel,
 // reconstruct the missing chroma values.
 //
 
+IMF_EXPORT
 void reconstructChromaHoriz (int n,
-                 const Rgba ycaIn[/*n+N-1*/],
-                 Rgba ycaOut[/*n*/]);
+                            const Rgba ycaIn[/*n+N-1*/],
+                            Rgba ycaOut[/*n*/]);
 
 //
 // For a scan line that has only luminance and no valid chroma data,
 // reconstruct chroma from the surronding N scan lines.
 //
 
+IMF_EXPORT
 void reconstructChromaVert (int n,
-                const Rgba * const ycaIn[N],
-                Rgba ycaOut[/*n*/]);
-
+                           const Rgba * const ycaIn[N],
+                           Rgba ycaOut[/*n*/]);
+                        
 //
 // Convert an array of n YCA (luminance/chroma/alpha) pixels to RGBA.
 // This function is the inverse of RGBAtoYCA().
 // yw is a set of RGB-to-Y weighting factors, as computed by computeYw().
 //
 
-void YCAtoRGBA (const Imath::V3f &yw,
-        int n,
-        const Rgba ycaIn[/*n*/],
-        Rgba rgbaOut[/*n*/]);
-
+IMF_EXPORT
+void YCAtoRGBA (const IMATH_NAMESPACE::V3f &yw,
+               int n,
+               const Rgba ycaIn[/*n*/],
+               Rgba rgbaOut[/*n*/]);
+                        
 //
 // Eliminate super-saturated pixels:
 //
@@ -237,12 +247,13 @@ void YCAtoRGBA (const Imath::V3f &yw,
 // saturation of rgbaIn[1], and stores the result in rgbaOut.
 //
 
-void fixSaturation (const Imath::V3f &yw,
-            int n,
-            const Rgba * const rgbaIn[3],
-            Rgba rgbaOut[/*n*/]);
+IMF_EXPORT
+void fixSaturation (const IMATH_NAMESPACE::V3f &yw,
+                   int n,
+                   const Rgba * const rgbaIn[3],
+                   Rgba rgbaOut[/*n*/]);
 
 } // namespace RgbaYca
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfRle.cpp b/3rdparty/openexr/IlmImf/ImfRle.cpp
new file mode 100644 (file)
index 0000000..7be6ac4
--- /dev/null
@@ -0,0 +1,157 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include <string.h>
+#include "ImfRle.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+namespace {
+
+const int MIN_RUN_LENGTH = 3;
+const int MAX_RUN_LENGTH = 127;
+
+}
+
+//
+// Compress an array of bytes, using run-length encoding,
+// and return the length of the compressed data.
+//
+
+int
+rleCompress (int inLength, const char in[], signed char out[])
+{
+    const char *inEnd = in + inLength;
+    const char *runStart = in;
+    const char *runEnd = in + 1;
+    signed char *outWrite = out;
+
+    while (runStart < inEnd)
+    {
+       while (runEnd < inEnd &&
+              *runStart == *runEnd &&
+              runEnd - runStart - 1 < MAX_RUN_LENGTH)
+       {
+           ++runEnd;
+       }
+
+       if (runEnd - runStart >= MIN_RUN_LENGTH)
+       {
+           //
+           // Compressable run
+           //
+
+           *outWrite++ = (runEnd - runStart) - 1;
+           *outWrite++ = *(signed char *) runStart;
+           runStart = runEnd;
+       }
+       else
+       {
+           //
+           // Uncompressable run
+           //
+
+           while (runEnd < inEnd &&
+                  ((runEnd + 1 >= inEnd ||
+                    *runEnd != *(runEnd + 1)) ||
+                   (runEnd + 2 >= inEnd ||
+                    *(runEnd + 1) != *(runEnd + 2))) &&
+                  runEnd - runStart < MAX_RUN_LENGTH)
+           {
+               ++runEnd;
+           }
+
+           *outWrite++ = runStart - runEnd;
+
+           while (runStart < runEnd)
+           {
+               *outWrite++ = *(signed char *) (runStart++);
+           }
+       }
+
+       ++runEnd;
+    }
+
+    return outWrite - out;
+}
+
+
+//
+// Uncompress an array of bytes compressed with rleCompress().
+// Returns the length of the oncompressed data, or 0 if the
+// length of the uncompressed data would be more than maxLength.
+//
+
+int
+rleUncompress (int inLength, int maxLength, const signed char in[], char out[])
+{
+    char *outStart = out;
+
+    while (inLength > 0)
+    {
+       if (*in < 0)
+       {
+           int count = -((int)*in++);
+           inLength -= count + 1;
+
+           if (0 > (maxLength -= count))
+               return 0;
+
+        memcpy(out, in, count);
+        out += count;
+        in  += count;
+       }
+       else
+       {
+           int count = *in++;
+           inLength -= 2;
+
+           if (0 > (maxLength -= count + 1))
+               return 0;
+
+        memset(out, *(char*)in, count+1);
+        out += count+1;
+
+           in++;
+       }
+    }
+
+    return out - outStart;
+}
+
+
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfRle.h b/3rdparty/openexr/IlmImf/ImfRle.h
new file mode 100644 (file)
index 0000000..0def336
--- /dev/null
@@ -0,0 +1,63 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_RLE_H_
+#define INCLUDED_IMF_RLE_H_
+
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Compress an array of bytes, using run-length encoding,
+// and return the length of the compressed data.
+//
+
+IMF_EXPORT
+int rleCompress (int inLength, const char in[], signed char out[]);
+
+//
+// Uncompress an array of bytes compressed with rleCompress().
+// Returns the length of the uncompressed data, or 0 if the
+// length of the uncompressed data would be more than maxLength.
+//
+
+IMF_EXPORT
+int rleUncompress (int inLength, int maxLength,
+                                 const signed char in[], char out[]);
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif
index e214a4e..33914e8 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfRleCompressor.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfRleCompressor.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfRle.h"
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
-namespace {
-
-const int MIN_RUN_LENGTH = 3;
-const int MAX_RUN_LENGTH = 127;
-
-
-//
-// Compress an array of bytes, using run-length encoding,
-// and return the length of the compressed data.
-//
-
-int
-rleCompress (int inLength, const char in[], signed char out[])
-{
-    const char *inEnd = in + inLength;
-    const char *runStart = in;
-    const char *runEnd = in + 1;
-    signed char *outWrite = out;
-
-    while (runStart < inEnd)
-    {
-    while (runEnd < inEnd &&
-           *runStart == *runEnd &&
-           runEnd - runStart - 1 < MAX_RUN_LENGTH)
-    {
-        ++runEnd;
-    }
-
-    if (runEnd - runStart >= MIN_RUN_LENGTH)
-    {
-        //
-        // Compressable run
-        //
-
-        *outWrite++ = (runEnd - runStart) - 1;
-        *outWrite++ = *(signed char *) runStart;
-        runStart = runEnd;
-    }
-    else
-    {
-        //
-        // Uncompressable run
-        //
-
-        while (runEnd < inEnd &&
-           ((runEnd + 1 >= inEnd ||
-             *runEnd != *(runEnd + 1)) ||
-            (runEnd + 2 >= inEnd ||
-             *(runEnd + 1) != *(runEnd + 2))) &&
-           runEnd - runStart < MAX_RUN_LENGTH)
-        {
-        ++runEnd;
-        }
-
-        *outWrite++ = runStart - runEnd;
-
-        while (runStart < runEnd)
-        {
-        *outWrite++ = *(signed char *) (runStart++);
-        }
-    }
-
-    ++runEnd;
-    }
-
-    return outWrite - out;
-}
-
-
-//
-// Uncompress an array of bytes compressed with rleCompress().
-// Returns the length of the oncompressed data, or 0 if the
-// length of the uncompressed data would be more than maxLength.
-//
-
-int
-rleUncompress (int inLength, int maxLength, const signed char in[], char out[])
-{
-    char *outStart = out;
-
-    while (inLength > 0)
-    {
-    if (*in < 0)
-    {
-        int count = -((int)*in++);
-        inLength -= count + 1;
-
-        if (0 > (maxLength -= count))
-        return 0;
-
-        while (count-- > 0)
-        *out++ = *(char *) (in++);
-    }
-    else
-    {
-        int count = *in++;
-        inLength -= 2;
-
-        if (0 > (maxLength -= count + 1))
-        return 0;
-
-        while (count-- >= 0)
-        *out++ = *(char *) in;
-
-        in++;
-    }
-    }
-
-    return out - outStart;
-}
-
-} // namespace
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 RleCompressor::RleCompressor (const Header &hdr, size_t maxScanLineSize):
     Compressor (hdr),
@@ -190,18 +79,18 @@ RleCompressor::numScanLines () const
 
 int
 RleCompressor::compress (const char *inPtr,
-             int inSize,
-             int /*minY*/,
-             const char *&outPtr)
+                        int inSize,
+                        int minY,
+                        const char *&outPtr)
 {
     //
-    // Special case Â­- empty input buffer
+    // Special case ï¿½- empty input buffer
     //
 
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
+       outPtr = _outBuffer;
+       return 0;
     }
 
     //
@@ -209,22 +98,22 @@ RleCompressor::compress (const char *inPtr,
     //
 
     {
-    char *t1 = _tmpBuffer;
-    char *t2 = _tmpBuffer + (inSize + 1) / 2;
-    const char *stop = inPtr + inSize;
+       char *t1 = _tmpBuffer;
+       char *t2 = _tmpBuffer + (inSize + 1) / 2;
+       const char *stop = inPtr + inSize;
 
-    while (true)
-    {
-        if (inPtr < stop)
-        *(t1++) = *(inPtr++);
-        else
-        break;
-
-        if (inPtr < stop)
-        *(t2++) = *(inPtr++);
-        else
-        break;
-    }
+       while (true)
+       {
+           if (inPtr < stop)
+               *(t1++) = *(inPtr++);
+           else
+               break;
+
+           if (inPtr < stop)
+               *(t2++) = *(inPtr++);
+           else
+               break;
+       }
     }
 
     //
@@ -232,17 +121,17 @@ RleCompressor::compress (const char *inPtr,
     //
 
     {
-    unsigned char *t = (unsigned char *) _tmpBuffer + 1;
-    unsigned char *stop = (unsigned char *) _tmpBuffer + inSize;
-    int p = t[-1];
+       unsigned char *t = (unsigned char *) _tmpBuffer + 1;
+       unsigned char *stop = (unsigned char *) _tmpBuffer + inSize;
+       int p = t[-1];
 
-    while (t < stop)
-    {
-        int d = int (t[0]) - p + (128 + 256);
-        p = t[0];
-        t[0] = d;
-        ++t;
-    }
+       while (t < stop)
+       {
+           int d = int (t[0]) - p + (128 + 256);
+           p = t[0];
+           t[0] = d;
+           ++t;
+       }
     }
 
     //
@@ -256,18 +145,18 @@ RleCompressor::compress (const char *inPtr,
 
 int
 RleCompressor::uncompress (const char *inPtr,
-               int inSize,
-               int /*minY*/,
-               const char *&outPtr)
+                          int inSize,
+                          int minY,
+                          const char *&outPtr)
 {
     //
-    // Special case Â­- empty input buffer
+    // Special case ï¿½- empty input buffer
     //
 
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
+       outPtr = _outBuffer;
+       return 0;
     }
 
     //
@@ -277,10 +166,10 @@ RleCompressor::uncompress (const char *inPtr,
     int outSize;
 
     if (0 == (outSize = rleUncompress (inSize, _maxScanLineSize,
-                       (const signed char *) inPtr,
-                       _tmpBuffer)))
+                                      (const signed char *) inPtr,
+                                      _tmpBuffer)))
     {
-    throw Iex::InputExc ("Data decoding (rle) failed.");
+       throw IEX_NAMESPACE::InputExc ("Data decoding (rle) failed.");
     }
 
     //
@@ -288,15 +177,15 @@ RleCompressor::uncompress (const char *inPtr,
     //
 
     {
-    unsigned char *t = (unsigned char *) _tmpBuffer + 1;
-    unsigned char *stop = (unsigned char *) _tmpBuffer + outSize;
+       unsigned char *t = (unsigned char *) _tmpBuffer + 1;
+       unsigned char *stop = (unsigned char *) _tmpBuffer + outSize;
 
-    while (t < stop)
-    {
-        int d = int (t[-1]) + int (t[0]) - 128;
-        t[0] = d;
-        ++t;
-    }
+       while (t < stop)
+       {
+           int d = int (t[-1]) + int (t[0]) - 128;
+           t[0] = d;
+           ++t;
+       }
     }
 
     //
@@ -304,23 +193,23 @@ RleCompressor::uncompress (const char *inPtr,
     //
 
     {
-    const char *t1 = _tmpBuffer;
-    const char *t2 = _tmpBuffer + (outSize + 1) / 2;
-    char *s = _outBuffer;
-    char *stop = s + outSize;
+       const char *t1 = _tmpBuffer;
+       const char *t2 = _tmpBuffer + (outSize + 1) / 2;
+       char *s = _outBuffer;
+       char *stop = s + outSize;
 
-    while (true)
-    {
-        if (s < stop)
-        *(s++) = *(t1++);
-        else
-        break;
-
-        if (s < stop)
-        *(s++) = *(t2++);
-        else
-        break;
-    }
+       while (true)
+       {
+           if (s < stop)
+               *(s++) = *(t1++);
+           else
+               break;
+
+           if (s < stop)
+               *(s++) = *(t2++);
+           else
+               break;
+       }
     }
 
     outPtr = _outBuffer;
@@ -328,4 +217,4 @@ RleCompressor::uncompress (const char *inPtr,
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 0bec2e2..7bb253a 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class RleCompressor: public Compressor
 {
   public:
 
+    IMF_EXPORT
     RleCompressor (const Header &hdr, size_t maxScanLineSize);
+    IMF_EXPORT
     virtual ~RleCompressor ();
 
+    IMF_EXPORT
     virtual int numScanLines () const;
 
+    IMF_EXPORT
     virtual int        compress (const char *inPtr,
-              int inSize,
-              int minY,
-              const char *&outPtr);
+                         int inSize,
+                         int minY,
+                         const char *&outPtr);
 
+    IMF_EXPORT
     virtual int        uncompress (const char *inPtr,
-                int inSize,
-                int minY,
-                const char *&outPtr);
+                           int inSize,
+                           int minY,
+                           const char *&outPtr);
   private:
 
     int                _maxScanLineSize;
@@ -74,6 +80,6 @@ class RleCompressor: public Compressor
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 5d8b522..c3eadb7 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfScanLineInputFile.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfStdIO.h>
-#include <ImfCompressor.h>
+#include "ImfScanLineInputFile.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfStdIO.h"
+#include "ImfCompressor.h"
 #include "ImathBox.h"
 #include "ImathFun.h"
 #include <ImfXdr.h>
 #include <ImfConvert.h>
 #include <ImfThreading.h>
+#include <ImfPartType.h>
 #include "IlmThreadPool.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
 #include "Iex.h"
+#include "ImfVersion.h"
+#include "ImfOptimizedPixelReading.h"
+#include "ImfNamespace.h"
+#include "ImfStandardAttributes.h"
+
+#include <algorithm>
 #include <string>
 #include <vector>
 #include <assert.h>
-#include <algorithm> // for std::max()
+#include <cstring>
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 
-using Imath::Box2i;
-using Imath::divp;
-using Imath::modp;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::divp;
+using IMATH_NAMESPACE::modp;
 using std::string;
 using std::vector;
 using std::ifstream;
 using std::min;
 using std::max;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using std::sort;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
 
 namespace {
 
@@ -92,25 +100,25 @@ struct InSliceInfo
     double     fillValue;
 
     InSliceInfo (PixelType typeInFrameBuffer = HALF,
-         PixelType typeInFile = HALF,
-             char *base = 0,
-             size_t xStride = 0,
-             size_t yStride = 0,
-             int xSampling = 1,
-             int ySampling = 1,
-             bool fill = false,
-             bool skip = false,
-             double fillValue = 0.0);
+                PixelType typeInFile = HALF,
+                char *base = 0,
+                size_t xStride = 0,
+                size_t yStride = 0,
+                int xSampling = 1,
+                int ySampling = 1,
+                bool fill = false,
+                bool skip = false,
+                double fillValue = 0.0);
 };
 
 
 InSliceInfo::InSliceInfo (PixelType tifb,
-              PixelType tifl,
-              char *b,
-              size_t xs, size_t ys,
-              int xsm, int ysm,
-              bool f, bool s,
-              double fv)
+                         PixelType tifl,
+                         char *b,
+                         size_t xs, size_t ys,
+                         int xsm, int ysm,
+                         bool f, bool s,
+                         double fv)
 :
     typeInFrameBuffer (tifb),
     typeInFile (tifl),
@@ -172,6 +180,29 @@ LineBuffer::~LineBuffer ()
     delete compressor;
 }
 
+/// helper struct used to detect the order that the channels are stored
+
+struct sliceOptimizationData
+{
+    const char * base;   ///< pointer to pixel data 
+    bool fill;           ///< is this channel being filled with constant, instead of read?
+    half fillValue;      ///< if filling, the value to use
+    size_t offset;       ///< position this channel will be in the read buffer, accounting for previous channels, as well as their type
+    PixelType type;      ///< type of channel
+    size_t xStride;      ///< x-stride of channel in buffer (must be set to cause channels to interleave)
+    size_t yStride;      ///< y-stride of channel in buffer (must be same in all channels, else order will change, which is bad)
+    int xSampling;       ///< channel x sampling
+    int ySampling;       ///< channel y sampling
+            
+            
+    /// we need to keep the list sorted in the order they'll be written to memory
+    bool operator<(const sliceOptimizationData& other ) const
+    {
+        return base < other.base;
+    }
+};
+    
+
 } // namespace
 
 
@@ -186,33 +217,40 @@ struct ScanLineInputFile::Data: public Mutex
     int                        minY;               // data window's min y coord
     int                        maxY;               // data window's max x coord
     vector<Int64>      lineOffsets;        // stores offsets in file for
-                        // each line
+                                           // each line
     bool               fileIsComplete;     // True if no scanlines are missing
-                            // in the file
+                                           // in the file
     int                        nextLineBufferMinY; // minimum y of the next linebuffer
     vector<size_t>     bytesPerLine;       // combined size of a line over all
                                             // channels
     vector<size_t>     offsetInLineBuffer; // offset for each scanline in its
                                             // linebuffer
     vector<InSliceInfo>        slices;             // info about channels in file
-    IStream *          is;                 // file stream to read from
-
+    
     vector<LineBuffer*> lineBuffers;        // each holds one line buffer
     int                        linesInBuffer;      // number of scanlines each buffer
                                             // holds
     size_t             lineBufferSize;     // size of the line buffer
+    int                 partNumber;         // part number
 
-     Data (IStream *is, int numThreads);
+    bool                memoryMapped;       // if the stream is memory mapped
+    OptimizationMode    optimizationMode;   // optimizibility of the input file
+    vector<sliceOptimizationData>  optimizationData; ///< channel ordering for optimized reading
+    
+    Data (int numThreads);
     ~Data ();
-
+    
     inline LineBuffer * getLineBuffer (int number); // hash function from line
-                                // buffer indices into our
-                            // vector of line buffers
+                                                   // buffer indices into our
+                                                   // vector of line buffers
+    
+    
 };
 
 
-ScanLineInputFile::Data::Data (IStream *is, int numThreads):
-    is (is)
+ScanLineInputFile::Data::Data (int numThreads):
+        partNumber(-1),
+        memoryMapped(false)
 {
     //
     // We need at least one lineBuffer, but if threading is used,
@@ -241,40 +279,40 @@ namespace {
 
 
 void
-reconstructLineOffsets (IStream &is,
-            LineOrder lineOrder,
-            vector<Int64> &lineOffsets)
+reconstructLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                       LineOrder lineOrder,
+                       vector<Int64> &lineOffsets)
 {
     Int64 position = is.tellg();
 
     try
     {
-    for (unsigned int i = 0; i < lineOffsets.size(); i++)
-    {
-        Int64 lineOffset = is.tellg();
+       for (unsigned int i = 0; i < lineOffsets.size(); i++)
+       {
+           Int64 lineOffset = is.tellg();
 
-        int y;
-        Xdr::read <StreamIO> (is, y);
+           int y;
+           OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, y);
 
-        int dataSize;
-        Xdr::read <StreamIO> (is, dataSize);
+           int dataSize;
+           OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, dataSize);
 
-        Xdr::skip <StreamIO> (is, dataSize);
+           Xdr::skip <StreamIO> (is, dataSize);
 
-        if (lineOrder == INCREASING_Y)
-        lineOffsets[i] = lineOffset;
-        else
-        lineOffsets[lineOffsets.size() - i - 1] = lineOffset;
-    }
+           if (lineOrder == INCREASING_Y)
+               lineOffsets[i] = lineOffset;
+           else
+               lineOffsets[lineOffsets.size() - i - 1] = lineOffset;
+       }
     }
     catch (...)
     {
-    //
-    // Suppress all exceptions.  This functions is
-    // called only to reconstruct the line offset
-    // table for incomplete files, and exceptions
-    // are likely.
-    //
+       //
+       // Suppress all exceptions.  This functions is
+       // called only to reconstruct the line offset
+       // table for incomplete files, and exceptions
+       // are likely.
+       //
     }
 
     is.clear();
@@ -283,48 +321,49 @@ reconstructLineOffsets (IStream &is,
 
 
 void
-readLineOffsets (IStream &is,
-         LineOrder lineOrder,
-         vector<Int64> &lineOffsets,
-         bool &complete)
+readLineOffsets (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                LineOrder lineOrder,
+                vector<Int64> &lineOffsets,
+                bool &complete)
 {
     for (unsigned int i = 0; i < lineOffsets.size(); i++)
     {
-    Xdr::read <StreamIO> (is, lineOffsets[i]);
+       OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, lineOffsets[i]);
     }
 
     complete = true;
 
     for (unsigned int i = 0; i < lineOffsets.size(); i++)
     {
-    if (lineOffsets[i] <= 0)
-    {
-        //
-        // Invalid data in the line offset table mean that
-        // the file is probably incomplete (the table is
-        // the last thing written to the file).  Either
-        // some process is still busy writing the file,
-        // or writing the file was aborted.
-        //
-        // We should still be able to read the existing
-        // parts of the file.  In order to do this, we
-        // have to make a sequential scan over the scan
-        // line data to reconstruct the line offset table.
-        //
-
-        complete = false;
-        reconstructLineOffsets (is, lineOrder, lineOffsets);
-        break;
-    }
+       if (lineOffsets[i] <= 0)
+       {
+           //
+           // Invalid data in the line offset table mean that
+           // the file is probably incomplete (the table is
+           // the last thing written to the file).  Either
+           // some process is still busy writing the file,
+           // or writing the file was aborted.
+           //
+           // We should still be able to read the existing
+           // parts of the file.  In order to do this, we
+           // have to make a sequential scan over the scan
+           // line data to reconstruct the line offset table.
+           //
+
+           complete = false;
+           reconstructLineOffsets (is, lineOrder, lineOffsets);
+           break;
+       }
     }
 }
 
 
 void
-readPixelData (ScanLineInputFile::Data *ifd,
-           int minY,
-           char *&buffer,
-           int &dataSize)
+readPixelData (InputStreamMutex *streamData,
+               ScanLineInputFile::Data *ifd,
+              int minY,
+              char *&buffer,
+              int &dataSize)
 {
     //
     // Read a single line buffer from the input file.
@@ -335,19 +374,34 @@ readPixelData (ScanLineInputFile::Data *ifd,
     // array (hence buffer needs to be a reference to a char *).
     //
 
-    Int64 lineOffset =
-    ifd->lineOffsets[(minY - ifd->minY) / ifd->linesInBuffer];
+    int lineBufferNumber = (minY - ifd->minY) / ifd->linesInBuffer;
+    if (lineBufferNumber < 0 || lineBufferNumber >= int(ifd->lineOffsets.size()))
+        THROW (IEX_NAMESPACE::InputExc, "Invalid scan line " << minY << " requested or missing.");
+
+    Int64 lineOffset = ifd->lineOffsets[lineBufferNumber];
 
     if (lineOffset == 0)
-    THROW (Iex::InputExc, "Scan line " << minY << " is missing.");
+       THROW (IEX_NAMESPACE::InputExc, "Scan line " << minY << " is missing.");
 
     //
     // Seek to the start of the scan line in the file,
     // if necessary.
     //
 
-    if (ifd->nextLineBufferMinY != minY)
-    ifd->is->seekg (lineOffset);
+    if ( !isMultiPart(ifd->version) )
+    {
+        if (ifd->nextLineBufferMinY != minY)
+            streamData->is->seekg (lineOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may have been moved by
+        // other parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != ifd->lineOffsets[lineBufferNumber])
+            streamData->is->seekg (lineOffset);
+    }
 
     //
     // Read the data block's header.
@@ -355,23 +409,37 @@ readPixelData (ScanLineInputFile::Data *ifd,
 
     int yInFile;
 
-    Xdr::read <StreamIO> (*ifd->is, yInFile);
-    Xdr::read <StreamIO> (*ifd->is, dataSize);
+    //
+    // Read the part number when we are dealing with a multi-part file.
+    //
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
 
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, yInFile);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, dataSize);
+    
     if (yInFile != minY)
-        throw Iex::InputExc ("Unexpected data block y coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected data block y coordinate.");
 
     if (dataSize > (int) ifd->lineBufferSize)
-    throw Iex::InputExc ("Unexpected data block length.");
+       throw IEX_NAMESPACE::InputExc ("Unexpected data block length.");
 
     //
     // Read the pixel data.
     //
 
-    if (ifd->is->isMemoryMapped ())
-        buffer = ifd->is->readMemoryMapped (dataSize);
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (dataSize);
     else
-        ifd->is->read (buffer, dataSize);
+        streamData->is->read (buffer, dataSize);
 
     //
     // Keep track of which scan line is the next one in
@@ -380,11 +448,12 @@ readPixelData (ScanLineInputFile::Data *ifd,
     //
 
     if (ifd->lineOrder == INCREASING_Y)
-    ifd->nextLineBufferMinY = minY + ifd->linesInBuffer;
+        ifd->nextLineBufferMinY = minY + ifd->linesInBuffer;
     else
-    ifd->nextLineBufferMinY = minY - ifd->linesInBuffer;
+        ifd->nextLineBufferMinY = minY - ifd->linesInBuffer;
 }
 
+                        
 
 //
 // A LineBufferTask encapsulates the task uncompressing a set of
@@ -397,9 +466,10 @@ class LineBufferTask : public Task
 
     LineBufferTask (TaskGroup *group,
                     ScanLineInputFile::Data *ifd,
-            LineBuffer *lineBuffer,
+                   LineBuffer *lineBuffer,
                     int scanLineMin,
-            int scanLineMax);
+                   int scanLineMax,
+                    OptimizationMode optimizationMode);
 
     virtual ~LineBufferTask ();
 
@@ -411,6 +481,7 @@ class LineBufferTask : public Task
     LineBuffer *               _lineBuffer;
     int                                _scanLineMin;
     int                                _scanLineMax;
+    OptimizationMode            _optimizationMode;
 };
 
 
@@ -419,13 +490,14 @@ LineBufferTask::LineBufferTask
      ScanLineInputFile::Data *ifd,
      LineBuffer *lineBuffer,
      int scanLineMin,
-     int scanLineMax)
+     int scanLineMax,OptimizationMode optimizationMode)
 :
     Task (group),
     _ifd (ifd),
     _lineBuffer (lineBuffer),
     _scanLineMin (scanLineMin),
-    _scanLineMax (scanLineMax)
+    _scanLineMax (scanLineMax),
+    _optimizationMode(optimizationMode)
 {
     // empty
 }
@@ -449,27 +521,29 @@ LineBufferTask::execute ()
         //
         // Uncompress the data, if necessary
         //
-
+    
         if (_lineBuffer->uncompressedData == 0)
         {
             int uncompressedSize = 0;
             int maxY = min (_lineBuffer->maxY, _ifd->maxY);
-
+    
             for (int i = _lineBuffer->minY - _ifd->minY;
                  i <= maxY - _ifd->minY;
-         ++i)
-        {
+                ++i)
+           {
                 uncompressedSize += (int) _ifd->bytesPerLine[i];
-        }
-
+           }
+    
             if (_lineBuffer->compressor &&
                 _lineBuffer->dataSize < uncompressedSize)
             {
                 _lineBuffer->format = _lineBuffer->compressor->format();
 
                 _lineBuffer->dataSize = _lineBuffer->compressor->uncompress
-                    (_lineBuffer->buffer, _lineBuffer->dataSize,
-             _lineBuffer->minY, _lineBuffer->uncompressedData);
+                    (_lineBuffer->buffer,
+                     _lineBuffer->dataSize,
+                    _lineBuffer->minY,
+                     _lineBuffer->uncompressedData);
             }
             else
             {
@@ -477,12 +551,12 @@ LineBufferTask::execute ()
                 // If the line is uncompressed, it's in XDR format,
                 // regardless of the compressor's output format.
                 //
-
+    
                 _lineBuffer->format = Compressor::XDR;
                 _lineBuffer->uncompressedData = _lineBuffer->buffer;
             }
         }
-
+        
         int yStart, yStop, dy;
 
         if (_ifd->lineOrder == INCREASING_Y)
@@ -497,7 +571,7 @@ LineBufferTask::execute ()
             yStop = _scanLineMin - 1;
             dy = -1;
         }
-
+    
         for (int y = yStart; y != yStop; y += dy)
         {
             //
@@ -505,46 +579,46 @@ LineBufferTask::execute ()
             // from the machine-independent representation, and
             // store the result in the frame buffer.
             //
-
+    
             const char *readPtr = _lineBuffer->uncompressedData +
                                   _ifd->offsetInLineBuffer[y - _ifd->minY];
-
+    
             //
             // Iterate over all image channels.
             //
-
+    
             for (unsigned int i = 0; i < _ifd->slices.size(); ++i)
             {
                 //
                 // Test if scan line y of this channel contains any data
-        // (the scan line contains data only if y % ySampling == 0).
+               // (the scan line contains data only if y % ySampling == 0).
                 //
-
+    
                 const InSliceInfo &slice = _ifd->slices[i];
-
+    
                 if (modp (y, slice.ySampling) != 0)
                     continue;
-
+    
                 //
                 // Find the x coordinates of the leftmost and rightmost
                 // sampled pixels (i.e. pixels within the data window
                 // for which x % xSampling == 0).
                 //
-
+    
                 int dMinX = divp (_ifd->minX, slice.xSampling);
                 int dMaxX = divp (_ifd->maxX, slice.xSampling);
-
+    
                 //
-        // Fill the frame buffer with pixel data.
+               // Fill the frame buffer with pixel data.
                 //
-
+    
                 if (slice.skip)
                 {
                     //
                     // The file contains data for this channel, but
                     // the frame buffer contains no slice for this channel.
                     //
-
+    
                     skipChannel (readPtr, slice.typeInFile, dMaxX - dMinX + 1);
                 }
                 else
@@ -552,14 +626,14 @@ LineBufferTask::execute ()
                     //
                     // The frame buffer contains a slice for this channel.
                     //
-
+    
                     char *linePtr  = slice.base +
                                         divp (y, slice.ySampling) *
                                         slice.yStride;
-
+    
                     char *writePtr = linePtr + dMinX * slice.xStride;
                     char *endPtr   = linePtr + dMaxX * slice.xStride;
-
+                    
                     copyIntoFrameBuffer (readPtr, writePtr, endPtr,
                                          slice.xStride, slice.fill,
                                          slice.fillValue, _lineBuffer->format,
@@ -588,98 +662,456 @@ LineBufferTask::execute ()
 }
 
 
-LineBufferTask *
-newLineBufferTask
+#ifdef IMF_HAVE_SSE2
+//
+// IIF format is more restricted than a perfectly generic one,
+// so it is possible to perform some optimizations.
+//
+class LineBufferTaskIIF : public Task
+{
+    public:
+        
+        LineBufferTaskIIF (TaskGroup *group,
+                           ScanLineInputFile::Data *ifd,
+                           LineBuffer *lineBuffer,
+                           int scanLineMin,
+                           int scanLineMax,
+                           OptimizationMode optimizationMode);
+                           
+        virtual ~LineBufferTaskIIF ();
+                           
+        virtual void                execute ();
+        
+        template<typename TYPE>
+        void getWritePointer (int y,
+                              unsigned short*& pOutWritePointerRight,
+                              size_t& outPixelsToCopySSE,
+                              size_t& outPixelsToCopyNormal,int bank=0) const;
+                              
+        template<typename TYPE>
+        void getWritePointerStereo (int y,
+                                    unsigned short*& outWritePointerRight,
+                                    unsigned short*& outWritePointerLeft,
+                                    size_t& outPixelsToCopySSE,
+                                    size_t& outPixelsToCopyNormal) const;
+
+    private:
+        
+        ScanLineInputFile::Data *   _ifd;
+        LineBuffer *                _lineBuffer;
+        int                         _scanLineMin;
+        int                         _scanLineMax;
+        OptimizationMode            _optimizationMode;
+  
+};
+
+LineBufferTaskIIF::LineBufferTaskIIF
     (TaskGroup *group,
      ScanLineInputFile::Data *ifd,
-     int number,
+     LineBuffer *lineBuffer,
      int scanLineMin,
-     int scanLineMax)
+     int scanLineMax,
+     OptimizationMode optimizationMode
+    )
+    :
+     Task (group),
+     _ifd (ifd),
+     _lineBuffer (lineBuffer),
+     _scanLineMin (scanLineMin),
+     _scanLineMax (scanLineMax),
+     _optimizationMode (optimizationMode)
 {
-    //
-    // Wait for a line buffer to become available, fill the line
-    // buffer with raw data from the file if necessary, and create
-    // a new LineBufferTask whose execute() method will uncompress
-    // the contents of the buffer and copy the pixels into the
-    // frame buffer.
-    //
+     /*
+     //
+     // indicates the optimised path has been taken
+     //
+     static bool could_optimise=false;
+     if(could_optimise==false)
+     {
+         std::cerr << " optimised path\n";
+         could_optimise=true;
+     }
+     */
+}
+LineBufferTaskIIF::~LineBufferTaskIIF ()
+{
+     //
+     // Signal that the line buffer is now free
+     //
+     
+     _lineBuffer->post ();
+}
+// Return 0 if we are to skip because of sampling
+// channelBank is 0 for the first group of channels, 1 for the second
+template<typename TYPE>
+void LineBufferTaskIIF::getWritePointer 
+                            (int y,
+                             unsigned short*& outWritePointerRight,
+                             size_t& outPixelsToCopySSE,
+                             size_t& outPixelsToCopyNormal,
+                             int channelBank
+                            ) const
+{
+      // Channels are saved alphabetically, so the order is B G R.
+      // The last slice (R) will give us the location of our write pointer.
+      // The only slice that we support skipping is alpha, i.e. the first one.  
+      // This does not impact the write pointer or the pixels to copy at all.
+      
+      size_t nbSlicesInBank = _ifd->optimizationData.size();
+      
+      int sizeOfSingleValue = sizeof(TYPE);
+      
+      if(_ifd->optimizationData.size()>4)
+      {
+          // there are two banks - we only copy one at once
+          nbSlicesInBank/=2;
+      }
+
+      
+      size_t firstChannel = 0;
+      if(channelBank==1)
+      {
+          firstChannel = _ifd->optimizationData.size()/2;
+      }
+      
+       sliceOptimizationData& firstSlice = _ifd->optimizationData[firstChannel];
+      
+      if (modp (y, firstSlice.ySampling) != 0)
+      {
+          outPixelsToCopySSE    = 0;
+          outPixelsToCopyNormal = 0;
+          outWritePointerRight  = 0;
+      }
+      
+      const char* linePtr1  = firstSlice.base +
+      divp (y, firstSlice.ySampling) *
+      firstSlice.yStride;
+      
+      int dMinX1 = divp (_ifd->minX, firstSlice.xSampling);
+      int dMaxX1 = divp (_ifd->maxX, firstSlice.xSampling);
+      
+      // Construct the writePtr so that we start writing at
+      // linePtr + Min offset in the line.
+      outWritePointerRight =  (unsigned short*)(linePtr1 +
+      dMinX1 * firstSlice.xStride );
+      
+      size_t bytesToCopy  = ((linePtr1 + dMaxX1 * firstSlice.xStride ) -
+      (linePtr1 + dMinX1 * firstSlice.xStride )) + 2;
+      size_t shortsToCopy = bytesToCopy / sizeOfSingleValue;
+      size_t pixelsToCopy = (shortsToCopy / nbSlicesInBank ) + 1;
+      
+      // We only support writing to SSE if we have no pixels to copy normally
+      outPixelsToCopySSE    = pixelsToCopy / 8;
+      outPixelsToCopyNormal = pixelsToCopy % 8;
+      
+}
 
-    LineBuffer *lineBuffer = ifd->getLineBuffer (number);
 
-    try
-    {
-    lineBuffer->wait ();
+template<typename TYPE>
+void LineBufferTaskIIF::getWritePointerStereo 
+                          (int y,
+                           unsigned short*& outWritePointerRight,
+                           unsigned short*& outWritePointerLeft,
+                           size_t& outPixelsToCopySSE,
+                           size_t& outPixelsToCopyNormal) const
+{
+   getWritePointer<TYPE>(y,outWritePointerRight,outPixelsToCopySSE,outPixelsToCopyNormal,0);
+   
+   
+   if(outWritePointerRight)
+   {
+       getWritePointer<TYPE>(y,outWritePointerLeft,outPixelsToCopySSE,outPixelsToCopyNormal,1);
+   }
+   
+}
 
-    if (lineBuffer->number != number)
+void
+LineBufferTaskIIF::execute()
+{
+    try
     {
-        lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer;
-        lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1;
-
-        lineBuffer->number = number;
-        lineBuffer->uncompressedData = 0;
-
-        readPixelData (ifd, lineBuffer->minY,
-               lineBuffer->buffer,
-               lineBuffer->dataSize);
-    }
+        //
+        // Uncompress the data, if necessary
+        //
+        
+        if (_lineBuffer->uncompressedData == 0)
+        {
+            int uncompressedSize = 0;
+            int maxY = min (_lineBuffer->maxY, _ifd->maxY);
+            
+            for (int i = _lineBuffer->minY - _ifd->minY;
+            i <= maxY - _ifd->minY;
+            ++i)
+            {
+                uncompressedSize += (int) _ifd->bytesPerLine[i];
+            }
+            
+            if (_lineBuffer->compressor &&
+                _lineBuffer->dataSize < uncompressedSize)
+            {
+                _lineBuffer->format = _lineBuffer->compressor->format();
+                
+                _lineBuffer->dataSize =
+                _lineBuffer->compressor->uncompress (_lineBuffer->buffer,
+                                                     _lineBuffer->dataSize,
+                                                     _lineBuffer->minY,
+                                                     _lineBuffer->uncompressedData);
+            }
+            else
+            {
+                //
+                // If the line is uncompressed, it's in XDR format,
+                // regardless of the compressor's output format.
+                //
+                
+                _lineBuffer->format = Compressor::XDR;
+                _lineBuffer->uncompressedData = _lineBuffer->buffer;
+            }
+        }
+        
+        int yStart, yStop, dy;
+        
+        if (_ifd->lineOrder == INCREASING_Y)
+        {
+            yStart = _scanLineMin;
+            yStop = _scanLineMax + 1;
+            dy = 1;
+        }
+        else
+        {
+            yStart = _scanLineMax;
+            yStop = _scanLineMin - 1;
+            dy = -1;
+        }
+        
+        for (int y = yStart; y != yStop; y += dy)
+        {
+            if (modp (y, _optimizationMode._ySampling) != 0)
+                continue;
+            
+            //
+            // Convert one scan line's worth of pixel data back
+            // from the machine-independent representation, and
+            // store the result in the frame buffer.
+            //
+            
+            // Set the readPtr to read at the start of uncompressedData
+            // but with an offet based on calculated array.
+            // _ifd->offsetInLineBuffer contains offsets based on which
+            // line we are currently processing.
+            // Stride will be taken into consideration later.
+                
+                
+            const char* readPtr = _lineBuffer->uncompressedData +
+            _ifd->offsetInLineBuffer[y - _ifd->minY];
+            
+            size_t pixelsToCopySSE = 0;
+            size_t pixelsToCopyNormal = 0;
+            
+            unsigned short* writePtrLeft = 0;
+            unsigned short* writePtrRight = 0;
+            
+            size_t channels = _ifd->optimizationData.size();
+       
+            if(channels>4)
+            {
+                getWritePointerStereo<half>(y, writePtrRight, writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+            }
+            else 
+            {
+                getWritePointer<half>(y, writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+            }
+            
+            if (writePtrRight == 0 && pixelsToCopySSE == 0 && pixelsToCopyNormal == 0)
+            {
+                continue;
+            }
+            
+            
+            //
+            // support reading up to eight channels
+            //
+            unsigned short* readPointers[8];
+            
+            for (size_t i = 0; i < channels ; ++i)
+            {
+                readPointers[i] = (unsigned short*)readPtr + (_ifd->optimizationData[i].offset * (pixelsToCopySSE * 8 + pixelsToCopyNormal));
+            }
+            
+            //RGB only
+            if(channels==3 || channels == 6 )
+            {
+                    optimizedWriteToRGB(readPointers[0], readPointers[1], readPointers[2], writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+                  
+                    //stereo RGB
+                    if( channels == 6)
+                    {
+                        optimizedWriteToRGB(readPointers[3], readPointers[4], readPointers[5], writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+                    }                
+            //RGBA
+            }else if(channels==4 || channels==8)
+            {
+                
+                if(_ifd->optimizationData[3].fill)
+                {
+                    optimizedWriteToRGBAFillA(readPointers[0], readPointers[1], readPointers[2], _ifd->optimizationData[3].fillValue.bits() , writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+                }else{
+                    optimizedWriteToRGBA(readPointers[0], readPointers[1], readPointers[2], readPointers[3] , writePtrRight, pixelsToCopySSE, pixelsToCopyNormal);
+                }
+                
+                //stereo RGBA
+                if( channels == 8)
+                {
+                    if(_ifd->optimizationData[7].fill)
+                    {
+                        optimizedWriteToRGBAFillA(readPointers[4], readPointers[5], readPointers[6], _ifd->optimizationData[7].fillValue.bits() , writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+                    }else{
+                        optimizedWriteToRGBA(readPointers[4], readPointers[5], readPointers[6], readPointers[7] , writePtrLeft, pixelsToCopySSE, pixelsToCopyNormal);
+                    }
+                }
+            }
+            else {
+                throw(IEX_NAMESPACE::LogicExc("IIF mode called with incorrect channel pattern"));
+            }
+            
+            // If we are in NO_OPTIMIZATION mode, this class will never
+            // get instantiated, so no need to check for it and duplicate
+            // the code.
+        }
     }
     catch (std::exception &e)
     {
-    if (!lineBuffer->hasException)
-    {
-        lineBuffer->exception = e.what();
-        lineBuffer->hasException = true;
-    }
-    lineBuffer->number = -1;
-    lineBuffer->post();\
-    throw;
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = e.what();
+            _lineBuffer->hasException = true;
+        }
     }
     catch (...)
     {
-    //
-    // Reading from the file caused an exception.
-    // Signal that the line buffer is free, and
-    // re-throw the exception.
-    //
-
-    lineBuffer->exception = "unrecognized exception";
-    lineBuffer->hasException = true;
-    lineBuffer->number = -1;
-    lineBuffer->post();
-    throw;
+        if (!_lineBuffer->hasException)
+        {
+            _lineBuffer->exception = "unrecognized exception";
+            _lineBuffer->hasException = true;
+        }
     }
+}
+#endif
 
-    scanLineMin = max (lineBuffer->minY, scanLineMin);
-    scanLineMax = min (lineBuffer->maxY, scanLineMax);
 
-    return new LineBufferTask (group, ifd, lineBuffer,
-                   scanLineMin, scanLineMax);
-}
+Task *
+newLineBufferTask (TaskGroup *group,
+                   InputStreamMutex *streamData,
+                   ScanLineInputFile::Data *ifd,
+                   int number,
+                   int scanLineMin,
+                   int scanLineMax,
+                   OptimizationMode optimizationMode)
+{
+     //
+     // Wait for a line buffer to become available, fill the line
+     // buffer with raw data from the file if necessary, and create
+     // a new LineBufferTask whose execute() method will uncompress
+     // the contents of the buffer and copy the pixels into the
+     // frame buffer.
+     //
+     
+     LineBuffer *lineBuffer = ifd->getLineBuffer (number);
+     
+     try
+     {
+         lineBuffer->wait ();
+         
+         if (lineBuffer->number != number)
+         {
+             lineBuffer->minY = ifd->minY + number * ifd->linesInBuffer;
+             lineBuffer->maxY = lineBuffer->minY + ifd->linesInBuffer - 1;
+             
+             lineBuffer->number = number;
+             lineBuffer->uncompressedData = 0;
+             
+             readPixelData (streamData, ifd, lineBuffer->minY,
+                            lineBuffer->buffer,
+                            lineBuffer->dataSize);
+         }
+     }
+     catch (std::exception &e)
+     {
+         if (!lineBuffer->hasException)
+         {
+             lineBuffer->exception = e.what();
+             lineBuffer->hasException = true;
+         }
+         lineBuffer->number = -1;
+         lineBuffer->post();
+         throw;
+     }
+     catch (...)
+     {
+         //
+         // Reading from the file caused an exception.
+         // Signal that the line buffer is free, and
+         // re-throw the exception.
+         //
+         
+         lineBuffer->exception = "unrecognized exception";
+         lineBuffer->hasException = true;
+         lineBuffer->number = -1;
+         lineBuffer->post();
+         throw;
+     }
+     
+     scanLineMin = max (lineBuffer->minY, scanLineMin);
+     scanLineMax = min (lineBuffer->maxY, scanLineMax);
+     
+     
+     Task* retTask = 0;
+     
+#ifdef IMF_HAVE_SSE2     
+     if (optimizationMode._optimizable)
+     {
+         
+         retTask = new LineBufferTaskIIF (group, ifd, lineBuffer,
+                                          scanLineMin, scanLineMax,
+                                          optimizationMode);
+      
+     }
+     else
+#endif         
+     {
+         retTask = new LineBufferTask (group, ifd, lineBuffer,
+                                       scanLineMin, scanLineMax,
+                                       optimizationMode);
+     }
+     
+     return retTask;
+     
+ }
+  
+
 
 } // namespace
 
 
-ScanLineInputFile::ScanLineInputFile
-    (const Header &header,
-     IStream *is,
-     int numThreads)
-:
-    _data (new Data (is, numThreads))
+void ScanLineInputFile::initialize(const Header& header)
 {
     try
     {
-    _data->header = header;
+        _data->header = header;
 
-    _data->lineOrder = _data->header.lineOrder();
+        _data->lineOrder = _data->header.lineOrder();
 
-    const Box2i &dataWindow = _data->header.dataWindow();
+        const Box2i &dataWindow = _data->header.dataWindow();
 
-    _data->minX = dataWindow.min.x;
-    _data->maxX = dataWindow.max.x;
-    _data->minY = dataWindow.min.y;
-    _data->maxY = dataWindow.max.y;
+        _data->minX = dataWindow.min.x;
+        _data->maxX = dataWindow.max.x;
+        _data->minY = dataWindow.min.y;
+        _data->maxY = dataWindow.max.y;
 
-    size_t maxBytesPerLine = bytesPerLineTable (_data->header,
+        size_t maxBytesPerLine = bytesPerLineTable (_data->header,
                                                     _data->bytesPerLine);
 
         for (size_t i = 0; i < _data->lineBuffers.size(); i++)
@@ -691,43 +1123,106 @@ ScanLineInputFile::ScanLineInputFile
         }
 
         _data->linesInBuffer =
-        numLinesInBuffer (_data->lineBuffers[0]->compressor);
+            numLinesInBuffer (_data->lineBuffers[0]->compressor);
 
         _data->lineBufferSize = maxBytesPerLine * _data->linesInBuffer;
 
-        if (!_data->is->isMemoryMapped())
+        if (!_streamData->is->isMemoryMapped())
+        {
             for (size_t i = 0; i < _data->lineBuffers.size(); i++)
-                _data->lineBuffers[i]->buffer = new char[_data->lineBufferSize];
-
-    _data->nextLineBufferMinY = _data->minY - 1;
-
-    offsetInLineBufferTable (_data->bytesPerLine,
-                 _data->linesInBuffer,
-                 _data->offsetInLineBuffer);
+            {
+                _data->lineBuffers[i]->buffer = (char *) EXRAllocAligned(_data->lineBufferSize*sizeof(char),16);
+            }
+        }
+        _data->nextLineBufferMinY = _data->minY - 1;
 
-    int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
-                  _data->linesInBuffer) / _data->linesInBuffer;
+        offsetInLineBufferTable (_data->bytesPerLine,
+                                 _data->linesInBuffer,
+                                 _data->offsetInLineBuffer);
 
-    _data->lineOffsets.resize (lineOffsetSize);
+        int lineOffsetSize = (dataWindow.max.y - dataWindow.min.y +
+                              _data->linesInBuffer) / _data->linesInBuffer;
 
-    readLineOffsets (*_data->is,
-             _data->lineOrder,
-             _data->lineOffsets,
-             _data->fileIsComplete);
+        _data->lineOffsets.resize (lineOffsetSize);
     }
     catch (...)
     {
-    delete _data;
-    throw;
+        delete _data;
+        _data=NULL;
+        throw;
     }
 }
 
 
+ScanLineInputFile::ScanLineInputFile(InputPartData* part)
+{
+    if (part->header.type() != SCANLINEIMAGE)
+        throw IEX_NAMESPACE::ArgExc("Can't build a ScanLineInputFile from a type-mismatched part.");
+
+    _data = new Data(part->numThreads);
+    _streamData = part->mutex;
+    _data->memoryMapped = _streamData->is->isMemoryMapped();
+
+    _data->version = part->version;
+
+    initialize(part->header);
+
+    _data->lineOffsets = part->chunkOffsets;
+
+    _data->partNumber = part->partNumber;
+    //
+    // (TODO) change this code later.
+    // The completeness of the file should be detected in MultiPartInputFile.
+    //
+    _data->fileIsComplete = true;
+}
+
+
+ScanLineInputFile::ScanLineInputFile
+    (const Header &header,
+     OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+     int numThreads)
+:
+    _data (new Data (numThreads)),
+    _streamData (new InputStreamMutex())
+{
+    _streamData->is = is;
+    _data->memoryMapped = is->isMemoryMapped();
+
+    initialize(header);
+    
+    //
+    // (TODO) this is nasty - we need a better way of working out what type of file has been used.
+    // in any case I believe this constructor only gets used with single part files
+    // and 'version' currently only tracks multipart state, so setting to 0 (not multipart) works for us
+    //
+    
+    _data->version=0;
+    readLineOffsets (*_streamData->is,
+                     _data->lineOrder,
+                     _data->lineOffsets,
+                     _data->fileIsComplete);
+}
+
+
 ScanLineInputFile::~ScanLineInputFile ()
 {
-    if (!_data->is->isMemoryMapped())
+    if (!_data->memoryMapped)
+    {
         for (size_t i = 0; i < _data->lineBuffers.size(); i++)
-            delete [] _data->lineBuffers[i]->buffer;
+        {
+            EXRFreeAligned(_data->lineBuffers[i]->buffer);
+        }
+    }
+            
+
+    //
+    // ScanLineInputFile should never delete the stream,
+    // because it does not own the stream.
+    // We just delete the Mutex here.
+    //
+    if (_data->partNumber == -1)
+        delete _streamData;
 
     delete _data;
 }
@@ -736,7 +1231,7 @@ ScanLineInputFile::~ScanLineInputFile ()
 const char *
 ScanLineInputFile::fileName () const
 {
-    return _data->is->fileName();
+    return _streamData->is->fileName();
 }
 
 
@@ -754,109 +1249,285 @@ ScanLineInputFile::version () const
 }
 
 
-void
-ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
+namespace
 {
-    Lock lock (*_data);
-
+    
+    
+// returns the optimization state for the given arrangement of frame bufers
+// this assumes:
+//   both the file and framebuffer are half float data
+//   both the file and framebuffer have xSampling and ySampling=1
+//   entries in optData are sorted into their interleave order (i.e. by base address)
+//   These tests are done by SetFrameBuffer as it is building optData
+//  
+OptimizationMode
+detectOptimizationMode (const vector<sliceOptimizationData>& optData)
+{
+    OptimizationMode w;
+    
+    // need to be compiled with SSE optimisations: if not, just returns false
+#ifdef IMF_HAVE_SSE2
+    
+    
+    // only handle reading 3,4,6 or 8 channels
+    switch(optData.size())
+    {
+        case 3 : break;
+        case 4 : break;
+        case 6 : break;
+        case 8 : break;
+        default :
+            return w;
+    }
+    
     //
-    // Check if the new frame buffer descriptor is
-    // compatible with the image file header.
+    // the point at which data switches between the primary and secondary bank
     //
+    size_t bankSize = optData.size()>4 ? optData.size()/2 : optData.size();
+    
+    for(size_t i=0;i<optData.size();i++)
+    {
+        const sliceOptimizationData& data = optData[i];
+        // can't fill anything other than channel 3 or channel 7
+        if(data.fill)
+        {
+            if(i!=3 && i!=7)
+            {
+                return w;
+            }
+        }
+        
+        // cannot have gaps in the channel layout, so the stride must be (number of channels written in the bank)*2
+        if(data.xStride !=bankSize*2)
+        {
+            return w;
+        }
+        
+        // each bank of channels must be channel interleaved: each channel base pointer must be (previous channel+2)
+        // this also means channel sampling pattern must be consistent, as must yStride
+        if(i!=0 && i!=bankSize)
+        {
+            if(data.base!=optData[i-1].base+2)
+            {
+                return w;
+            }
+        }
+        if(i!=0)
+        {
+            
+            if(data.yStride!=optData[i-1].yStride)
+            {
+                return w;
+            }
+        }
+    }
+    
 
-    const ChannelList &channels = _data->header.channels();
+    w._ySampling=optData[0].ySampling;
+    w._optimizable=true;
+    
+#endif
+
+    return w;
+}
+
+
+} // Anonymous namespace
+
+void   
+ScanLineInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    Lock lock (*_streamData);
 
+    
+    
+    const ChannelList &channels = _data->header.channels();
     for (FrameBuffer::ConstIterator j = frameBuffer.begin();
-     j != frameBuffer.end();
-     ++j)
+        j != frameBuffer.end();
+        ++j)
     {
-    ChannelList::ConstIterator i = channels.find (j.name());
-
-    if (i == channels.end())
-        continue;
-
-    if (i.channel().xSampling != j.slice().xSampling ||
-        i.channel().ySampling != j.slice().ySampling)
-        THROW (Iex::ArgExc, "X and/or y subsampling factors "
-                "of \"" << i.name() << "\" channel "
-                "of input file \"" << fileName() << "\" are "
-                "not compatible with the frame buffer's "
-                "subsampling factors.");
+       ChannelList::ConstIterator i = channels.find (j.name());
+
+       if (i == channels.end())
+           continue;
+
+       if (i.channel().xSampling != j.slice().xSampling ||
+           i.channel().ySampling != j.slice().ySampling)
+           THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                               "of \"" << i.name() << "\" channel "
+                               "of input file \"" << fileName() << "\" are "
+                               "not compatible with the frame buffer's "
+                               "subsampling factors.");
     }
 
+    // optimization is possible if this is a little endian system
+    // and both inputs and outputs are half floats
+    // 
+    bool optimizationPossible = true;
+    
+    if (!GLOBAL_SYSTEM_LITTLE_ENDIAN)
+    {
+        optimizationPossible =false;
+    }
+    
+    vector<sliceOptimizationData> optData;
+    
+
     //
     // Initialize the slice table for readPixels().
     //
 
     vector<InSliceInfo> slices;
     ChannelList::ConstIterator i = channels.begin();
-
+    
+    // current offset of channel: pixel data starts at offset*width into the
+    // decompressed scanline buffer
+    size_t offset = 0;
+    
     for (FrameBuffer::ConstIterator j = frameBuffer.begin();
-     j != frameBuffer.end();
-     ++j)
-    {
-    while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
-    {
-        //
-        // Channel i is present in the file but not
-        // in the frame buffer; data for channel i
-        // will be skipped during readPixels().
-        //
-
-        slices.push_back (InSliceInfo (i.channel().type,
-                       i.channel().type,
-                       0, // base
-                       0, // xStride
-                       0, // yStride
-                       i.channel().xSampling,
-                       i.channel().ySampling,
-                       false,  // fill
-                       true, // skip
-                       0.0)); // fillValue
-        ++i;
-    }
-
-    bool fill = false;
-
-    if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+        j != frameBuffer.end();
+        ++j)
     {
-        //
-        // Channel i is present in the frame buffer, but not in the file.
-        // In the frame buffer, slice j will be filled with a default value.
-        //
-
-        fill = true;
-    }
-
-    slices.push_back (InSliceInfo (j.slice().type,
-                       fill? j.slice().type:
-                             i.channel().type,
-                       j.slice().base,
-                       j.slice().xStride,
-                       j.slice().yStride,
-                       j.slice().xSampling,
-                       j.slice().ySampling,
-                       fill,
-                       false, // skip
-                       j.slice().fillValue));
-
-    if (i != channels.end() && !fill)
-        ++i;
+       while (i != channels.end() && strcmp (i.name(), j.name()) < 0)
+       {
+           //
+           // Channel i is present in the file but not
+           // in the frame buffer; data for channel i
+           // will be skipped during readPixels().
+           //
+
+           slices.push_back (InSliceInfo (i.channel().type,
+                                          i.channel().type,
+                                          0, // base
+                                          0, // xStride
+                                          0, // yStride
+                                          i.channel().xSampling,
+                                          i.channel().ySampling,
+                                          false,  // fill
+                                          true, // skip
+                                          0.0)); // fillValue
+           
+              switch(i.channel().type)
+              {
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF :
+                      offset++;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                      offset+=2;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT :
+                      offset+=2;
+                      break;
+              }
+              ++i;
+       }
+
+       bool fill = false;
+
+       if (i == channels.end() || strcmp (i.name(), j.name()) > 0)
+       {
+           //
+           // Channel i is present in the frame buffer, but not in the file.
+           // In the frame buffer, slice j will be filled with a default value.
+           //
+
+           fill = true;
+       }
+
+       slices.push_back (InSliceInfo (j.slice().type,
+                                      fill? j.slice().type:
+                                            i.channel().type,
+                                      j.slice().base,
+                                      j.slice().xStride,
+                                      j.slice().yStride,
+                                      j.slice().xSampling,
+                                      j.slice().ySampling,
+                                      fill,
+                                      false, // skip
+                                      j.slice().fillValue));
+
+          if(!fill && i.channel().type!=OPENEXR_IMF_INTERNAL_NAMESPACE::HALF)
+          {
+              optimizationPossible = false;
+          }
+          
+          if(j.slice().type != OPENEXR_IMF_INTERNAL_NAMESPACE::HALF)
+          {
+              optimizationPossible = false;
+          }
+          if(j.slice().xSampling!=1 || j.slice().ySampling!=1)
+          {
+              optimizationPossible = false;
+          }
+
+          
+          if(optimizationPossible)
+          {
+              sliceOptimizationData dat;
+              dat.base = j.slice().base;
+              dat.fill = fill;
+              dat.fillValue = j.slice().fillValue;
+              dat.offset = offset;
+              dat.xStride = j.slice().xStride;
+              dat.yStride = j.slice().yStride;
+              dat.xSampling = j.slice().xSampling;
+              dat.ySampling = j.slice().ySampling;
+              optData.push_back(dat);
+          }
+          
+          if(!fill)
+          {
+              switch(i.channel().type)
+              {
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::HALF :
+                      offset++;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::FLOAT :
+                      offset+=2;
+                      break;
+                  case OPENEXR_IMF_INTERNAL_NAMESPACE::UINT :
+                      offset+=2;
+                      break;
+              }
+          }
+          
+
+          
+       if (i != channels.end() && !fill)
+           ++i;
     }
 
+   
+   if(optimizationPossible)
+   {
+       //
+       // check optimisibility
+       // based on channel ordering and fill channel positions
+       //
+       sort(optData.begin(),optData.end());
+       _data->optimizationMode = detectOptimizationMode(optData);
+   }
+   
+   if(!optimizationPossible || _data->optimizationMode._optimizable==false)
+   {   
+       optData = vector<sliceOptimizationData>();
+       _data->optimizationMode._optimizable=false;
+   }
+    
     //
     // Store the new frame buffer.
     //
 
     _data->frameBuffer = frameBuffer;
     _data->slices = slices;
+    _data->optimizationData = optData;
 }
 
 
 const FrameBuffer &
 ScanLineInputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
     return _data->frameBuffer;
 }
 
@@ -867,24 +1538,33 @@ ScanLineInputFile::isComplete () const
     return _data->fileIsComplete;
 }
 
+bool ScanLineInputFile::isOptimizationEnabled() const
+{
+    if (_data->slices.size() == 0)
+        throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+        "as pixel data destination.");
+    
+    return _data->optimizationMode._optimizable;
+}
 
-void
+
+void   
 ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_streamData);
 
-    if (_data->slices.size() == 0)
-        throw Iex::ArgExc ("No frame buffer specified "
-                   "as pixel data destination.");
+       if (_data->slices.size() == 0)
+           throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                              "as pixel data destination.");
 
-    int scanLineMin = min (scanLine1, scanLine2);
-    int scanLineMax = max (scanLine1, scanLine2);
+       int scanLineMin = min (scanLine1, scanLine2);
+       int scanLineMax = max (scanLine1, scanLine2);
 
-    if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
-        throw Iex::ArgExc ("Tried to read scan line outside "
-                   "the image file's data window.");
+       if (scanLineMin < _data->minY || scanLineMax > _data->maxY)
+           throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
+                              "the image file's data window.");
 
         //
         // We impose a numbering scheme on the lineBuffers where the first
@@ -912,76 +1592,78 @@ ScanLineInputFile::readPixels (int scanLine1, int scanLine2)
 
         //
         // Create a task group for all line buffer tasks.  When the
-    // task group goes out of scope, the destructor waits until
-    // all tasks are complete.
+       // task group goes out of scope, the destructor waits until
+       // all tasks are complete.
         //
-
+        
         {
             TaskGroup taskGroup;
-
+    
             //
             // Add the line buffer tasks.
             //
             // The tasks will execute in the order that they are created
             // because we lock the line buffers during construction and the
             // constructors are called by the main thread.  Hence, in order
-        // for a successive task to execute the previous task which
-        // used that line buffer must have completed already.
+           // for a successive task to execute the previous task which
+           // used that line buffer must have completed already.
             //
-
+    
             for (int l = start; l != stop; l += dl)
             {
                 ThreadPool::addGlobalTask (newLineBufferTask (&taskGroup,
+                                                              _streamData,
                                                               _data, l,
                                                               scanLineMin,
-                                                              scanLineMax));
+                                                              scanLineMax,
+                                                              _data->optimizationMode));
             }
-
-        //
+        
+           //
             // finish all tasks
-        //
+           //
         }
-
-    //
-    // Exeption handling:
-    //
-    // LineBufferTask::execute() may have encountered exceptions, but
-    // those exceptions occurred in another thread, not in the thread
-    // that is executing this call to ScanLineInputFile::readPixels().
-    // LineBufferTask::execute() has caught all exceptions and stored
-    // the exceptions' what() strings in the line buffers.
-    // Now we check if any line buffer contains a stored exception; if
-    // this is the case then we re-throw the exception in this thread.
-    // (It is possible that multiple line buffers contain stored
-    // exceptions.  We re-throw the first exception we find and
-    // ignore all others.)
-    //
-
-    const string *exception = 0;
-
-        for (int i = 0; i < _data->lineBuffers.size(); ++i)
-    {
+        
+       //
+       // Exeption handling:
+       //
+       // LineBufferTask::execute() may have encountered exceptions, but
+       // those exceptions occurred in another thread, not in the thread
+       // that is executing this call to ScanLineInputFile::readPixels().
+       // LineBufferTask::execute() has caught all exceptions and stored
+       // the exceptions' what() strings in the line buffers.
+       // Now we check if any line buffer contains a stored exception; if
+       // this is the case then we re-throw the exception in this thread.
+       // (It is possible that multiple line buffers contain stored
+       // exceptions.  We re-throw the first exception we find and
+       // ignore all others.)
+       //
+
+       const string *exception = 0;
+
+        for (size_t i = 0; i < _data->lineBuffers.size(); ++i)
+       {
             LineBuffer *lineBuffer = _data->lineBuffers[i];
 
-        if (lineBuffer->hasException && !exception)
-        exception = &lineBuffer->exception;
+           if (lineBuffer->hasException && !exception)
+               exception = &lineBuffer->exception;
 
-        lineBuffer->hasException = false;
-    }
+           lineBuffer->hasException = false;
+       }
 
-    if (exception)
-        throw Iex::IoExc (*exception);
+       if (exception)
+           throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error reading pixel data from image "
-                "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error reading pixel data from image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
 
-void
+void   
 ScanLineInputFile::readPixels (int scanLine)
 {
     readPixels (scanLine, scanLine);
@@ -990,33 +1672,67 @@ ScanLineInputFile::readPixels (int scanLine)
 
 void
 ScanLineInputFile::rawPixelData (int firstScanLine,
-                 const char *&pixelData,
-                 int &pixelDataSize)
+                                const char *&pixelData,
+                                int &pixelDataSize)
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_streamData);
 
-    if (firstScanLine < _data->minY || firstScanLine > _data->maxY)
-    {
-        throw Iex::ArgExc ("Tried to read scan line outside "
-                   "the image file's data window.");
-    }
+       if (firstScanLine < _data->minY || firstScanLine > _data->maxY)
+       {
+           throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
+                              "the image file's data window.");
+       }
 
         int minY = lineBufferMinY
-        (firstScanLine, _data->minY, _data->linesInBuffer);
+           (firstScanLine, _data->minY, _data->linesInBuffer);
 
-    readPixelData
-        (_data, minY, _data->lineBuffers[0]->buffer, pixelDataSize);
+       readPixelData
+           (_streamData, _data, minY, _data->lineBuffers[0]->buffer, pixelDataSize);
 
-    pixelData = _data->lineBuffers[0]->buffer;
+       pixelData = _data->lineBuffers[0]->buffer;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+       REPLACE_EXC (e, "Error reading pixel data from image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
-    catch (Iex::BaseExc &e)
+}
+
+
+void ScanLineInputFile::rawPixelDataToBuffer(int scanLine,
+                                             char *pixelData,
+                                             int &pixelDataSize) const
+{
+  if (_data->memoryMapped) {
+    throw IEX_NAMESPACE::ArgExc ("Reading raw pixel data to a buffer "
+                                 "is not supported for memory mapped "
+                                 "streams." );
+  }
+
+  try 
+  {
+    Lock lock (*_streamData);
+    
+    if (scanLine < _data->minY || scanLine > _data->maxY) 
     {
+      throw IEX_NAMESPACE::ArgExc ("Tried to read scan line outside "
+                                   "the image file's data window.");
+    }
+    
+    readPixelData
+      (_streamData, _data, scanLine, pixelData, pixelDataSize);
+    
+  }
+  catch (IEX_NAMESPACE::BaseExc &e) 
+  {
     REPLACE_EXC (e, "Error reading pixel data from image "
-                "file \"" << fileName() << "\". " << e);
+                 "file \"" << fileName() << "\". " << e.what());
     throw;
-    }
+  }
 }
 
-} // namespace Imf
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 70f2f39..3165a71 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
-#include <ImfThreading.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
+#include "ImfThreading.h"
+#include "ImfInputStreamMutex.h"
+#include "ImfInputPartData.h"
+#include "ImfGenericInputFile.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class ScanLineInputFile
+class ScanLineInputFile : public GenericInputFile
 {
   public:
 
@@ -57,7 +62,8 @@ class ScanLineInputFile
     // Constructor
     //------------
 
-    ScanLineInputFile (const Header &header, IStream *is,
+    IMF_EXPORT
+    ScanLineInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
                        int numThreads = globalThreadCount());
 
 
@@ -66,6 +72,7 @@ class ScanLineInputFile
     // structures, but does not close the file.
     //-----------------------------------------
 
+    IMF_EXPORT
     virtual ~ScanLineInputFile ();
 
 
@@ -73,6 +80,7 @@ class ScanLineInputFile
     // Access to the file name
     //------------------------
 
+    IMF_EXPORT
     const char *       fileName () const;
 
 
@@ -80,6 +88,7 @@ class ScanLineInputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &     header () const;
 
 
@@ -87,6 +96,7 @@ class ScanLineInputFile
     // Access to the file format version
     //----------------------------------
 
+    IMF_EXPORT
     int                        version () const;
 
 
@@ -101,6 +111,7 @@ class ScanLineInputFile
     // to readPixels().
     //-----------------------------------------------------------
 
+    IMF_EXPORT
     void               setFrameBuffer (const FrameBuffer &frameBuffer);
 
 
@@ -108,6 +119,7 @@ class ScanLineInputFile
     // Access to the current frame buffer
     //-----------------------------------
 
+    IMF_EXPORT
     const FrameBuffer &        frameBuffer () const;
 
 
@@ -120,8 +132,30 @@ class ScanLineInputFile
     // writing may have been aborted prematurely.)
     //---------------------------------------------------------------
 
+    IMF_EXPORT
     bool               isComplete () const;
 
+    
+    
+    //---------------------------------------------------------------
+    // Check if SSE optimisation is enabled
+    //
+    // Call after setFrameBuffer() to query whether optimised file decoding
+    // is available - decode times will be faster if returns true
+    //
+    // Optimisation depends on the framebuffer channels and channel types
+    // as well as the file/part channels and channel types, as well as
+    // whether SSE2 instruction support was detected at compile time
+    //
+    // Calling before setFrameBuffer will throw an exception
+    //
+    //---------------------------------------------------------------
+    
+    IMF_EXPORT
+    bool                isOptimizationEnabled () const;
+    
+    
+    
 
     //---------------------------------------------------------------
     // Read pixel data:
@@ -145,7 +179,9 @@ class ScanLineInputFile
     //
     //---------------------------------------------------------------
 
+    IMF_EXPORT
     void               readPixels (int scanLine1, int scanLine2);
+    IMF_EXPORT
     void               readPixels (int scanLine);
 
 
@@ -155,18 +191,55 @@ class ScanLineInputFile
     // used to implement OutputFile::copyPixels()).
     //----------------------------------------------
 
+    IMF_EXPORT
     void               rawPixelData (int firstScanLine,
-                      const char *&pixelData,
-                      int &pixelDataSize);
+                                     const char *&pixelData,
+                                     int &pixelDataSize);
 
+   
+    //----------------------------------------------
+    // Read a scanline's worth of raw pixel data 
+    // from the file, without uncompressing it, and 
+    // store in an external buffer, pixelData. 
+    // pixelData should be pre-allocated with space 
+    // for pixelDataSize chars. 
+    //
+    // This function can be used to separate the 
+    // reading of a raw scan line from the 
+    // decompression of that scan line, for
+    // example to allow multiple scan lines to be
+    // decompressed in parallel by an application's
+    // own threads, where it is not convenient to 
+    // use the threading within the library.
+    //----------------------------------------------
+
+    IMF_EXPORT
+    void                rawPixelDataToBuffer(int scanLine,
+                                            char *pixelData,
+                                            int &pixelDataSize) const;
+    
+  
     struct Data;
 
   private:
 
     Data *             _data;
+
+    InputStreamMutex*   _streamData;
+
+    ScanLineInputFile   (InputPartData* part);
+
+    void                initialize(const Header& header);
+
+    friend class MultiPartInputFile;
+    friend class InputFile;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfSimd.h b/3rdparty/openexr/IlmImf/ImfSimd.h
new file mode 100644 (file)
index 0000000..3489bd0
--- /dev/null
@@ -0,0 +1,68 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Autodesk, Inc.
+// 
+// All rights reserved.
+//
+// Implementation of IIF-specific file format and speed optimizations 
+// provided by Innobec Technologies inc on behalf of Autodesk.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_SIMD_H
+#define INCLUDED_IMF_SIMD_H
+
+//
+// Compile time SSE detection:
+//    IMF_HAVE_SSE2 - Defined if it's safe to compile SSE2 optimizations
+//    IMF_HAVE_SSE4_1 - Defined if it's safe to compile SSE4.1 optimizations
+//
+
+
+// GCC and Visual Studio SSE2 compiler flags
+#if defined __SSE2__ || (_MSC_VER >= 1300 && !_M_CEE_PURE)
+    #define IMF_HAVE_SSE2 1
+#endif
+
+#if defined __SSE4_1__
+    #define IMF_HAVE_SSE4_1 1
+#endif
+
+extern "C"
+{
+#ifdef IMF_HAVE_SSE2
+    #include <emmintrin.h>
+    #include <mmintrin.h>
+#endif
+
+#ifdef IMF_HAVE_SSE4_1
+    #include <smmintrin.h>
+#endif
+}
+
+#endif
index ea57020..df952c2 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2003, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #define IMF_STRING(name) #name
 
 #define IMF_STD_ATTRIBUTE_IMP(name,suffix,type)                                 \
-                                     \
+                                                                        \
     void                                                                \
     add##suffix (Header &header, const type &value)                     \
     {                                                                   \
-    header.insert (IMF_STRING (name), TypedAttribute<type> (value)); \
+       header.insert (IMF_STRING (name), TypedAttribute<type> (value)); \
     }                                                                   \
-                                     \
+                                                                        \
     bool                                                                \
     has##suffix (const Header &header)                                  \
     {                                                                   \
-    return header.findTypedAttribute <TypedAttribute <type> >   \
-        (IMF_STRING (name)) != 0;                               \
+       return header.findTypedAttribute <TypedAttribute <type> >        \
+               (IMF_STRING (name)) != 0;                                \
     }                                                                   \
-                                     \
+                                                                        \
     const TypedAttribute<type> &                                        \
     name##Attribute (const Header &header)                              \
     {                                                                   \
-    return header.typedAttribute <TypedAttribute <type> >               \
-        (IMF_STRING (name));                                    \
+       return header.typedAttribute <TypedAttribute <type> >            \
+               (IMF_STRING (name));                                     \
     }                                                                   \
-                                     \
+                                                                        \
     TypedAttribute<type> &                                              \
     name##Attribute (Header &header)                                    \
     {                                                                   \
-    return header.typedAttribute <TypedAttribute <type> >               \
-        (IMF_STRING (name));                                    \
+       return header.typedAttribute <TypedAttribute <type> >            \
+               (IMF_STRING (name));                                     \
     }                                                                   \
-                                     \
+                                                                        \
     const type &                                                        \
     name (const Header &header)                                                 \
     {                                                                   \
-    return name##Attribute(header).value();                             \
+       return name##Attribute(header).value();                          \
     }                                                                   \
-                                     \
+                                                                        \
     type &                                                              \
     name (Header &header)                                               \
     {                                                                   \
-    return name##Attribute(header).value();                             \
+       return name##Attribute(header).value();                          \
     }
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+using namespace IMATH_NAMESPACE;
+using namespace std;
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+   
 IMF_STD_ATTRIBUTE_IMP (chromaticities, Chromaticities, Chromaticities)
 IMF_STD_ATTRIBUTE_IMP (whiteLuminance, WhiteLuminance, float)
-IMF_STD_ATTRIBUTE_IMP (adoptedNeutral, AdoptedNeutral, Imath::V2f)
-IMF_STD_ATTRIBUTE_IMP (renderingTransform, RenderingTransform, std::string)
-IMF_STD_ATTRIBUTE_IMP (lookModTransform, LookModTransform, std::string)
+IMF_STD_ATTRIBUTE_IMP (adoptedNeutral, AdoptedNeutral, V2f)
+IMF_STD_ATTRIBUTE_IMP (renderingTransform, RenderingTransform, string)
+IMF_STD_ATTRIBUTE_IMP (lookModTransform, LookModTransform, string)
 IMF_STD_ATTRIBUTE_IMP (xDensity, XDensity, float)
-IMF_STD_ATTRIBUTE_IMP (owner, Owner, std::string)
-IMF_STD_ATTRIBUTE_IMP (comments, Comments, std::string)
-IMF_STD_ATTRIBUTE_IMP (capDate, CapDate, std::string)
+IMF_STD_ATTRIBUTE_IMP (owner, Owner, string)
+IMF_STD_ATTRIBUTE_IMP (comments, Comments, string)
+IMF_STD_ATTRIBUTE_IMP (capDate, CapDate, string)
 IMF_STD_ATTRIBUTE_IMP (utcOffset, UtcOffset, float)
 IMF_STD_ATTRIBUTE_IMP (longitude, Longitude, float)
 IMF_STD_ATTRIBUTE_IMP (latitude, Latitude, float)
@@ -109,10 +113,13 @@ IMF_STD_ATTRIBUTE_IMP (isoSpeed, IsoSpeed, float)
 IMF_STD_ATTRIBUTE_IMP (envmap, Envmap, Envmap)
 IMF_STD_ATTRIBUTE_IMP (keyCode, KeyCode, KeyCode)
 IMF_STD_ATTRIBUTE_IMP (timeCode, TimeCode, TimeCode)
-IMF_STD_ATTRIBUTE_IMP (wrapmodes, Wrapmodes, std::string)
+IMF_STD_ATTRIBUTE_IMP (wrapmodes, Wrapmodes, string)
 IMF_STD_ATTRIBUTE_IMP (framesPerSecond, FramesPerSecond, Rational)
 IMF_STD_ATTRIBUTE_IMP (multiView, MultiView, StringVector)
-IMF_STD_ATTRIBUTE_IMP (worldToCamera, WorldToCamera, Imath::M44f)
-IMF_STD_ATTRIBUTE_IMP (worldToNDC, WorldToNDC, Imath::M44f)
+IMF_STD_ATTRIBUTE_IMP (worldToCamera, WorldToCamera, M44f)
+IMF_STD_ATTRIBUTE_IMP (worldToNDC, WorldToNDC, M44f)
+IMF_STD_ATTRIBUTE_IMP (deepImageState, DeepImageState, DeepImageState)
+IMF_STD_ATTRIBUTE_IMP (originalDataWindow, OriginalDataWindow, Box2i)
+IMF_STD_ATTRIBUTE_IMP (dwaCompressionLevel, DwaCompressionLevel, float)
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 7273597..4280ac4 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfChromaticitiesAttribute.h>
-#include <ImfEnvmapAttribute.h>
-#include <ImfFloatAttribute.h>
-#include <ImfKeyCodeAttribute.h>
-#include <ImfMatrixAttribute.h>
-#include <ImfRationalAttribute.h>
-#include <ImfStringAttribute.h>
-#include <ImfStringVectorAttribute.h>
-#include <ImfTimeCodeAttribute.h>
-#include <ImfVecAttribute.h>
-
-#define IMF_STD_ATTRIBUTE_DEF(name,suffix,type)                                      \
-                                          \
-    void                        add##suffix (Header &header, const type &v); \
-    bool                        has##suffix (const Header &header);          \
-    const TypedAttribute<type> & name##Attribute (const Header &header);      \
-    TypedAttribute<type> &      name##Attribute (Header &header);            \
-    const type &                name (const Header &header);                 \
-    type &                      name (Header &header);
-
-
-namespace Imf {
+#include "ImfHeader.h"
+#include "ImfBoxAttribute.h"
+#include "ImfChromaticitiesAttribute.h"
+#include "ImfEnvmapAttribute.h"
+#include "ImfDeepImageStateAttribute.h"
+#include "ImfFloatAttribute.h"
+#include "ImfKeyCodeAttribute.h"
+#include "ImfMatrixAttribute.h"
+#include "ImfRationalAttribute.h"
+#include "ImfStringAttribute.h"
+#include "ImfStringVectorAttribute.h"
+#include "ImfTimeCodeAttribute.h"
+#include "ImfVecAttribute.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+#define IMF_STD_ATTRIBUTE_DEF(name,suffix,object)                            \
+                                                                             \
+    OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER                              \
+    IMF_EXPORT void           add##suffix (Header &header, const object &v); \
+    IMF_EXPORT bool           has##suffix (const Header &header);            \
+    IMF_EXPORT const TypedAttribute<object> &                                \
+                              name##Attribute (const Header &header);        \
+    IMF_EXPORT TypedAttribute<object> &                                      \
+                              name##Attribute (Header &header);              \
+    IMF_EXPORT const object &                                                \
+                              name (const Header &header);                   \
+    IMF_EXPORT object &       name (Header &header);                         \
+    OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT                               \
 
 //
 // chromaticities -- for RGB images, specifies the CIE (x,y)
@@ -94,7 +100,7 @@ IMF_STD_ATTRIBUTE_DEF (chromaticities, Chromaticities, Chromaticities)
 // known, then it is possible to convert the image's pixels from RGB
 // to CIE XYZ tristimulus values (see function RGBtoXYZ() in header
 // file ImfChromaticities.h).
-//
+// 
 //
 
 IMF_STD_ATTRIBUTE_DEF (whiteLuminance, WhiteLuminance, float)
@@ -107,14 +113,14 @@ IMF_STD_ATTRIBUTE_DEF (whiteLuminance, WhiteLuminance, float)
 // be mapped to neutral values on the display.
 //
 
-IMF_STD_ATTRIBUTE_DEF (adoptedNeutral, AdoptedNeutral, Imath::V2f)
+IMF_STD_ATTRIBUTE_DEF (adoptedNeutral, AdoptedNeutral, IMATH_NAMESPACE::V2f)
 
 
 //
 // renderingTransform, lookModTransform -- specify the names of the
 // CTL functions that implements the intended color rendering and look
 // modification transforms for this image.
-//
+// 
 
 IMF_STD_ATTRIBUTE_DEF (renderingTransform, RenderingTransform, std::string)
 IMF_STD_ATTRIBUTE_DEF (lookModTransform, LookModTransform, std::string)
@@ -133,7 +139,7 @@ IMF_STD_ATTRIBUTE_DEF (xDensity, XDensity, float)
 //
 
 IMF_STD_ATTRIBUTE_DEF (owner, Owner, std::string)
-
+   
 
 //
 // comments -- additional image information in human-readable
@@ -302,42 +308,75 @@ IMF_STD_ATTRIBUTE_DEF (framesPerSecond, FramesPerSecond, Rational)
 IMF_STD_ATTRIBUTE_DEF (multiView , MultiView, StringVector)
 
 
-//
+// 
 // worldToCamera -- for images generated by 3D computer graphics rendering,
 // a matrix that transforms 3D points from the world to the camera coordinate
 // space of the renderer.
-//
+// 
 // The camera coordinate space is left-handed.  Its origin indicates the
 // location of the camera.  The positive x and y axes correspond to the
 // "right" and "up" directions in the rendered image.  The positive z
 // axis indicates the camera's viewing direction.  (Objects in front of
 // the camera have positive z coordinates.)
-//
+// 
 // Camera coordinate space in OpenEXR is the same as in Pixar's Renderman.
-//
+// 
 
-IMF_STD_ATTRIBUTE_DEF (worldToCamera, WorldToCamera, Imath::M44f)
+IMF_STD_ATTRIBUTE_DEF (worldToCamera, WorldToCamera, IMATH_NAMESPACE::M44f)
 
 
-//
+// 
 // worldToNDC -- for images generated by 3D computer graphics rendering, a
 // matrix that transforms 3D points from the world to the Normalized Device
 // Coordinate (NDC) space of the renderer.
-//
+// 
 // NDC is a 2D coordinate space that corresponds to the image plane, with
 // positive x and pointing to the right and y positive pointing down.  The
 // coordinates (0, 0) and (1, 1) correspond to the upper left and lower right
 // corners of the OpenEXR display window.
-//
+// 
 // To transform a 3D point in word space into a 2D point in NDC space,
 // multiply the 3D point by the worldToNDC matrix and discard the z
 // coordinate.
-//
+// 
 // NDC space in OpenEXR is the same as in Pixar's Renderman.
+// 
+
+IMF_STD_ATTRIBUTE_DEF (worldToNDC, WorldToNDC, IMATH_NAMESPACE::M44f)
+
+
+//
+// deepImageState -- specifies whether the pixels in a deep image are
+// sorted and non-overlapping.
+//
+// Note: this attribute can be set by application code that writes a file
+// in order to tell applications that read the file whether the pixel data
+// must be cleaned up prior to image processing operations such as flattening. 
+// The IlmImf library does not verify that the attribute is consistent with
+// the actual state of the pixels.  Application software may assume that the
+// attribute is valid, as long as the software will not crash or lock up if
+// any pixels are inconsistent with the deepImageState attribute.
+//
+
+IMF_STD_ATTRIBUTE_DEF (deepImageState, DeepImageState, DeepImageState)
+
+
+//
+// originalDataWindow -- if application software crops an image, then it
+// should save the data window of the original, un-cropped image in the
+// originalDataWindow attribute.
+//
+
+IMF_STD_ATTRIBUTE_DEF
+    (originalDataWindow, OriginalDataWindow, IMATH_NAMESPACE::Box2i)
+
+
+//
+// dwaCompressionLevel -- sets the quality level for images compressed
+// with the DWAA or DWAB method.
 //
 
-IMF_STD_ATTRIBUTE_DEF (worldToNDC, WorldToNDC, Imath::M44f)
+IMF_STD_ATTRIBUTE_DEF (dwaCompressionLevel, DwaCompressionLevel, float)
 
-} // namespace Imf
 
 #endif
index 973d60e..91252df 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfStdIO.h>
 #include "Iex.h"
 #include <errno.h>
+#ifdef _MSC_VER
+# define VC_EXTRALEAN
+# include <Windows.h>
+# include <string.h>
+#endif
 
 using namespace std;
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
 namespace {
 
+#ifdef _MSC_VER
+std::wstring WidenFilename (const char *filename)
+{
+    std::wstring ret;
+    int fnlen = static_cast<int>( strlen(filename) );
+    int len = MultiByteToWideChar(CP_UTF8, 0, filename, fnlen, NULL, 0 );
+    if (len > 0)
+    {
+        ret.resize(len);
+        MultiByteToWideChar(CP_UTF8, 0, filename, fnlen, &ret[0], len);
+    }
+    return ret;
+}
+#endif
+
 void
 clearError ()
 {
@@ -61,15 +83,15 @@ checkError (istream &is, streamsize expected = 0)
 {
     if (!is)
     {
-    if (errno)
-        Iex::throwErrnoExc();
-
-    if (is.gcount() < expected)
-    {
-        THROW (Iex::InputExc, "Early end of file: read " << is.gcount()
-            << " out of " << expected << " requested bytes.");
-    }
-    return false;
+       if (errno)
+           IEX_NAMESPACE::throwErrnoExc();
+
+       if (is.gcount() < expected) 
+       {
+               THROW (IEX_NAMESPACE::InputExc, "Early end of file: read " << is.gcount() 
+                       << " out of " << expected << " requested bytes.");
+       }
+       return false;
     }
 
     return true;
@@ -81,10 +103,10 @@ checkError (ostream &os)
 {
     if (!os)
     {
-    if (errno)
-        Iex::throwErrnoExc();
+       if (errno)
+           IEX_NAMESPACE::throwErrnoExc();
 
-    throw Iex::ErrnoExc ("File output failed.");
+       throw IEX_NAMESPACE::ErrnoExc ("File output failed.");
     }
 }
 
@@ -92,20 +114,26 @@ checkError (ostream &os)
 
 
 StdIFStream::StdIFStream (const char fileName[]):
-    IStream (fileName),
-    _is (new ifstream (fileName, ios_base::binary)),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream (fileName),
+    _is (new ifstream (
+#ifdef _MSC_VER
+             WidenFilename(fileName).c_str(),
+#else
+             fileName,
+#endif
+             ios_base::binary)),
     _deleteStream (true)
 {
     if (!*_is)
     {
-    delete _is;
-    Iex::throwErrnoExc();
+       delete _is;
+       IEX_NAMESPACE::throwErrnoExc();
     }
 }
 
-
+    
 StdIFStream::StdIFStream (ifstream &is, const char fileName[]):
-    IStream (fileName),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::IStream (fileName),
     _is (&is),
     _deleteStream (false)
 {
@@ -116,7 +144,7 @@ StdIFStream::StdIFStream (ifstream &is, const char fileName[]):
 StdIFStream::~StdIFStream ()
 {
     if (_deleteStream)
-    delete _is;
+       delete _is;
 }
 
 
@@ -124,7 +152,7 @@ bool
 StdIFStream::read (char c[/*n*/], int n)
 {
     if (!*_is)
-        throw Iex::InputExc ("Unexpected end of file.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected end of file.");
 
     clearError();
     _is->read (c, n);
@@ -155,20 +183,26 @@ StdIFStream::clear ()
 
 
 StdOFStream::StdOFStream (const char fileName[]):
-    OStream (fileName),
-    _os (new ofstream (fileName, ios_base::binary)),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::OStream (fileName),
+    _os (new ofstream (
+#ifdef _MSC_VER
+             WidenFilename(fileName).c_str(),
+#else
+             fileName,
+#endif
+             ios_base::binary)),
     _deleteStream (true)
 {
     if (!*_os)
     {
-    delete _os;
-    Iex::throwErrnoExc();
+       delete _os;
+       IEX_NAMESPACE::throwErrnoExc();
     }
 }
 
 
 StdOFStream::StdOFStream (ofstream &os, const char fileName[]):
-    OStream (fileName),
+    OPENEXR_IMF_INTERNAL_NAMESPACE::OStream (fileName),
     _os (&os),
     _deleteStream (false)
 {
@@ -179,7 +213,7 @@ StdOFStream::StdOFStream (ofstream &os, const char fileName[]):
 StdOFStream::~StdOFStream ()
 {
     if (_deleteStream)
-    delete _os;
+       delete _os;
 }
 
 
@@ -207,7 +241,7 @@ StdOFStream::seekp (Int64 pos)
 }
 
 
-StdOSStream::StdOSStream (): OStream ("(string)")
+StdOSStream::StdOSStream (): OPENEXR_IMF_INTERNAL_NAMESPACE::OStream ("(string)")
 {
     // empty
 }
@@ -237,4 +271,4 @@ StdOSStream::seekp (Int64 pos)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index b9468c2..24c7cb5 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfIO.h>
+#include "ImfIO.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
 #include <fstream>
 #include <sstream>
 
-namespace Imf {
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //-------------------------------------------
 // class StdIFStream -- an implementation of
-// class IStream based on class std::ifstream
+// class OPENEXR_IMF_INTERNAL_NAMESPACE::IStream based on class std::ifstream
 //-------------------------------------------
 
-class StdIFStream: public IStream
+class StdIFStream: public OPENEXR_IMF_INTERNAL_NAMESPACE::IStream
 {
   public:
 
@@ -63,23 +67,30 @@ class StdIFStream: public IStream
     // The destructor will close the file.
     //-------------------------------------------------------
 
+    IMF_EXPORT
     StdIFStream (const char fileName[]);
 
-
+    
     //---------------------------------------------------------
     // A constructor that uses a std::ifstream that has already
     // been opened by the caller.  The StdIFStream's destructor
     // will not close the std::ifstream.
     //---------------------------------------------------------
 
+    IMF_EXPORT
     StdIFStream (std::ifstream &is, const char fileName[]);
 
 
+    IMF_EXPORT
     virtual ~StdIFStream ();
 
+    IMF_EXPORT
     virtual bool       read (char c[/*n*/], int n);
+    IMF_EXPORT
     virtual Int64      tellg ();
+    IMF_EXPORT
     virtual void       seekg (Int64 pos);
+    IMF_EXPORT
     virtual void       clear ();
 
   private:
@@ -91,10 +102,10 @@ class StdIFStream: public IStream
 
 //-------------------------------------------
 // class StdOFStream -- an implementation of
-// class OStream based on class std::ofstream
+// class OPENEXR_IMF_INTERNAL_NAMESPACE::OStream based on class std::ofstream
 //-------------------------------------------
 
-class StdOFStream: public OStream
+class StdOFStream: public OPENEXR_IMF_INTERNAL_NAMESPACE::OStream
 {
   public:
 
@@ -103,8 +114,9 @@ class StdOFStream: public OStream
     // The destructor will close the file.
     //-------------------------------------------------------
 
+    IMF_EXPORT
     StdOFStream (const char fileName[]);
-
+    
 
     //---------------------------------------------------------
     // A constructor that uses a std::ofstream that has already
@@ -112,13 +124,18 @@ class StdOFStream: public OStream
     // will not close the std::ofstream.
     //---------------------------------------------------------
 
+    IMF_EXPORT
     StdOFStream (std::ofstream &os, const char fileName[]);
 
 
+    IMF_EXPORT
     virtual ~StdOFStream ();
 
+    IMF_EXPORT
     virtual void       write (const char c[/*n*/], int n);
+    IMF_EXPORT
     virtual Int64      tellp ();
+    IMF_EXPORT
     virtual void       seekp (Int64 pos);
 
   private:
@@ -130,19 +147,24 @@ class StdOFStream: public OStream
 
 //------------------------------------------------
 // class StdOSStream -- an implementation of class
-// OStream, based on class std::ostringstream
+// OPENEXR_IMF_INTERNAL_NAMESPACE::OStream, based on class std::ostringstream
 //------------------------------------------------
 
-class StdOSStream: public OStream
+class StdOSStream: public OPENEXR_IMF_INTERNAL_NAMESPACE::OStream
 {
   public:
 
+    IMF_EXPORT
     StdOSStream ();
 
+    IMF_EXPORT
     virtual void       write (const char c[/*n*/], int n);
+    IMF_EXPORT
     virtual Int64      tellp ();
+    IMF_EXPORT
     virtual void       seekp (Int64 pos);
 
+    IMF_EXPORT
     std::string                str () const {return _os.str();}
 
   private:
@@ -151,6 +173,6 @@ class StdOSStream: public OStream
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 0f74cc0..cd241ba 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,8 +43,9 @@
 #include <ImfStringAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -56,24 +57,24 @@ StringAttribute::staticTypeName ()
 
 template <>
 void
-StringAttribute::writeValueTo (OStream &os, int) const
+StringAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     int size = _value.size();
 
     for (int i = 0; i < size; i++)
-    Xdr::write <StreamIO> (os, _value[i]);
+       Xdr::write <StreamIO> (os, _value[i]);
 }
 
 
 template <>
 void
-StringAttribute::readValueFrom (IStream &is, int size, int)
+StringAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     _value.resize (size);
 
     for (int i = 0; i < size; i++)
-    Xdr::read <StreamIO> (is, _value[i]);
+       Xdr::read <StreamIO> (is, _value[i]);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 8dc82c2..f5d62d7 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 #include <string>
 
-
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 typedef TypedAttribute<std::string> StringAttribute;
-template <> const char *StringAttribute::staticTypeName ();
-template <> void StringAttribute::writeValueTo (OStream &, int) const;
-template <> void StringAttribute::readValueFrom (IStream &, int, int);
 
+template <>
+IMF_EXPORT
+const char *StringAttribute::staticTypeName ();
 
-} // namespace Imf
+template <>
+IMF_EXPORT
+void StringAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                    int) const;
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfStringAttribute.cpp>
-#endif
+template <>
+IMF_EXPORT
+void StringAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                     int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 0987f34..88fdf8e 100644 (file)
@@ -1,9 +1,9 @@
 ///////////////////////////////////////////////////////////////////////////
 //
 // Copyright (c) 2007, Weta Digital Ltd
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -15,8 +15,8 @@
 // distribution.
 // *       Neither the name of Weta Digital nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 ///////////////////////////////////////////////////////////////////////////
 
 
-
 //-----------------------------------------------------------------------------
 //
-//     class StringAttribute
+//     class StringVectorAttribute
 //
 //-----------------------------------------------------------------------------
 
 #include <ImfStringVectorAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 
 template <>
@@ -55,7 +57,7 @@ StringVectorAttribute::staticTypeName ()
 
 template <>
 void
-StringVectorAttribute::writeValueTo (OStream &os, int) const
+StringVectorAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     int size = _value.size();
 
@@ -63,27 +65,31 @@ StringVectorAttribute::writeValueTo (OStream &os, int) const
     {
         int strSize = _value[i].size();
         Xdr::write <StreamIO> (os, strSize);
-    Xdr::write <StreamIO> (os, &_value[i][0], strSize);
+       Xdr::write <StreamIO> (os, &_value[i][0], strSize);
     }
 }
 
 
 template <>
 void
-StringVectorAttribute::readValueFrom (IStream &is, int size, int)
+StringVectorAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     int read = 0;
 
     while (read < size)
-    {
+    {   
        int strSize;
        Xdr::read <StreamIO> (is, strSize);
-       read += Xdr::size<int>();
+       read += Xdr::size<int>();       
 
        std::string str;
        str.resize (strSize);
-
-       Xdr::read<StreamIO> (is, &str[0], strSize);
+  
+       if( strSize>0 )
+       {
+           Xdr::read<StreamIO> (is, &str[0], strSize);
+       }
+       
        read += strSize;
 
        _value.push_back (str);
@@ -91,4 +97,4 @@ StringVectorAttribute::readValueFrom (IStream &is, int size, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 40fda91..d13ef96 100644 (file)
@@ -1,9 +1,9 @@
 ///////////////////////////////////////////////////////////////////////////
 //
 // Copyright (c) 2007, Weta Digital Ltd
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -15,8 +15,8 @@
 // distribution.
 // *       Neither the name of Weta Digital nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
+#include "ImfNamespace.h"
+
 #include <string>
 #include <vector>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 typedef std::vector<std::string> StringVector;
-typedef TypedAttribute<StringVector> StringVectorAttribute;
-template <> const char *StringVectorAttribute::staticTypeName ();
-template <> void StringVectorAttribute::writeValueTo (OStream &, int) const;
-template <> void StringVectorAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::StringVector> StringVectorAttribute;
 
+template <>
+IMF_EXPORT
+const char *StringVectorAttribute::staticTypeName ();
 
-} // namespace Imf
+template <>
+IMF_EXPORT
+void StringVectorAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                          int) const;
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfStringVectorAttribute.cpp>
-#endif
+template <>
+IMF_EXPORT
+void StringVectorAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                           int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfSystemSpecific.cpp b/3rdparty/openexr/IlmImf/ImfSystemSpecific.cpp
new file mode 100644 (file)
index 0000000..fe1d8a2
--- /dev/null
@@ -0,0 +1,138 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfSimd.h"
+#include "ImfSystemSpecific.h"
+#include "ImfNamespace.h"
+#include "OpenEXRConfig.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+namespace {
+#if defined(IMF_HAVE_SSE2) && defined(__GNUC__) && !defined(__ANDROID__)
+
+    // Helper functions for gcc + SSE enabled
+    void cpuid(int n, int &eax, int &ebx, int &ecx, int &edx)
+    {
+        __asm__ __volatile__ (
+            "cpuid"
+            : /* Output  */ "=a"(eax), "=b"(ebx), "=c"(ecx), "=d"(edx) 
+            : /* Input   */ "a"(n)
+            : /* Clobber */);
+    }
+
+#else // IMF_HAVE_SSE2 && __GNUC__
+
+    // Helper functions for generic compiler - all disabled
+    void cpuid(int n, int &eax, int &ebx, int &ecx, int &edx)
+    {
+        eax = ebx = ecx = edx = 0;
+    }
+
+#endif // IMF_HAVE_SSE2 && __GNUC__
+
+
+#ifdef OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
+
+    void xgetbv(int n, int &eax, int &edx)
+    {
+        __asm__ __volatile__ (
+            "xgetbv"
+            : /* Output  */ "=a"(eax), "=d"(edx) 
+            : /* Input   */ "c"(n)
+            : /* Clobber */);
+    }
+
+#else //  OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
+
+    void xgetbv(int n, int &eax, int &edx)
+    {
+        eax = edx = 0;
+    }
+
+#endif //  OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
+
+} // namespace 
+
+CpuId::CpuId():
+    sse2(false), 
+    sse3(false), 
+    ssse3(false),
+    sse4_1(false), 
+    sse4_2(false), 
+    avx(false), 
+    f16c(false)
+{
+    bool osxsave = false;
+    int  max     = 0;
+    int  eax, ebx, ecx, edx;
+
+    cpuid(0, max, ebx, ecx, edx);
+    if (max > 0)
+    {
+        cpuid(1, eax, ebx, ecx, edx);
+        sse2    = ( edx & (1<<26) );
+        sse3    = ( ecx & (1<< 0) );
+        ssse3   = ( ecx & (1<< 9) );
+        sse4_1  = ( ecx & (1<<19) );
+        sse4_2  = ( ecx & (1<<20) );
+        osxsave = ( ecx & (1<<27) );
+        avx     = ( ecx & (1<<28) );
+        f16c    = ( ecx & (1<<29) );
+
+        if (!osxsave)
+        {
+            avx = f16c = false;
+        }
+        else
+        {
+            xgetbv(0, eax, edx);
+            // eax bit 1 - SSE managed, bit 2 - AVX managed
+            if ((eax & 6) != 6)
+            {
+                avx = f16c = false;
+            }
+        }
+    }
+
+#if defined(IMF_HAVE_SSE2) && defined(__ANDROID__)
+    sse2 = true;
+    sse3 = true;
+#ifdef __x86_64__
+    ssse3 = true;
+    sse4_1 = true;
+#endif
+#endif
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfSystemSpecific.h b/3rdparty/openexr/IlmImf/ImfSystemSpecific.h
new file mode 100644 (file)
index 0000000..ad6b619
--- /dev/null
@@ -0,0 +1,183 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMF_COMPILER_SPECIFIC_H
+#define INCLUDED_IMF_COMPILER_SPECIFIC_H
+
+#include "ImfNamespace.h"
+#include "ImfSimd.h"
+#include <stdlib.h>
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+static unsigned long  systemEndianCheckValue   = 0x12345678;
+static unsigned long* systemEndianCheckPointer = &systemEndianCheckValue;
+
+// EXR files are little endian - check processor architecture is too
+// (optimisation currently not supported for big endian machines)
+static bool GLOBAL_SYSTEM_LITTLE_ENDIAN =
+        (*(unsigned char*)systemEndianCheckPointer == 0x78 ? true : false);
+
+
+#ifdef IMF_HAVE_SSE2
+
+#if defined(__GNUC__)
+// Causes issues on certain gcc versions
+//#define EXR_FORCEINLINE inline __attribute__((always_inline))
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT __restrict
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    // GNUC is used for things like mingw to (cross-)compile for windows
+#ifdef _WIN32
+    return _aligned_malloc(size, alignment);
+#elif defined(__ANDROID__)
+    return memalign(alignment, size);
+#else
+    void* ptr = 0;
+    posix_memalign(&ptr, alignment, size);
+    return ptr;
+#endif
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+#ifdef _WIN32
+    _aligned_free(ptr);
+#else
+    free(ptr);
+#endif
+}
+
+#elif defined _MSC_VER
+
+#define EXR_FORCEINLINE __forceinline
+#define EXR_RESTRICT __restrict
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return _aligned_malloc(size, alignment);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    _aligned_free(ptr);
+}
+
+#elif defined (__INTEL_COMPILER) || \
+        defined(__ICL) || \
+        defined(__ICC) || \
+        defined(__ECC)
+
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT restrict
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return _mm_malloc(size, alignment);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    _mm_free(ptr);
+}
+
+#else
+
+// generic compiler
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return malloc(size);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    free(ptr);
+}
+
+#endif // compiler switch
+
+
+#else // IMF_HAVE_SSE2
+
+
+#define EXR_FORCEINLINE inline
+#define EXR_RESTRICT
+
+static void* EXRAllocAligned(size_t size, size_t alignment)
+{
+    return malloc(size);
+}
+
+
+static void EXRFreeAligned(void* ptr)
+{
+    free(ptr);
+}
+
+
+#endif  // IMF_HAVE_SSE2
+
+// 
+// Simple CPUID based runtime detection of various capabilities
+//
+class IMF_EXPORT CpuId
+{
+    public:
+        CpuId();
+
+        bool sse2;
+        bool sse3;
+        bool ssse3;
+        bool sse4_1;
+        bool sse4_2;
+        bool avx;
+        bool f16c;
+};
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#endif //include guard
index 51e18a7..198a4d5 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfStdIO.h>
 #include <ImfXdr.h>
 #include <ImfVersion.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
-isOpenExrFile (const char fileName[], bool &tiled)
+isOpenExrFile
+    (const char fileName[],
+     bool &tiled,
+     bool &deep,
+     bool &multiPart)
 {
     try
     {
-    StdIFStream is (fileName);
+       StdIFStream is (fileName);
 
-    int magic, version;
-    Xdr::read <StreamIO> (is, magic);
-    Xdr::read <StreamIO> (is, version);
+       int magic, version;
+       Xdr::read <StreamIO> (is, magic);
+       Xdr::read <StreamIO> (is, version);
 
-    tiled = isTiled (version);
-    return magic == MAGIC;
+       tiled = isTiled (version);
+        deep = isNonImage (version);
+        multiPart = isMultiPart (version);
+       return magic == MAGIC;
     }
     catch (...)
     {
-    tiled = false;
-    return false;
+       tiled = false;
+       return false;
     }
 }
 
 
 bool
+isOpenExrFile (const char fileName[], bool &tiled, bool &deep)
+{
+    bool multiPart;
+    return isOpenExrFile (fileName, tiled, deep, multiPart);
+}
+
+
+bool
+isOpenExrFile (const char fileName[], bool &tiled)
+{
+    bool deep, multiPart;
+    return isOpenExrFile (fileName, tiled, deep, multiPart);
+}
+
+
+bool
 isOpenExrFile (const char fileName[])
 {
-    bool tiled;
-    return isOpenExrFile (fileName, tiled);
+    bool tiled, deep, multiPart;
+    return isOpenExrFile (fileName, tiled, deep, multiPart);
 }
 
 
 bool
 isTiledOpenExrFile (const char fileName[])
 {
-    bool exr, tiled;
-    exr = isOpenExrFile (fileName, tiled);
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (fileName, tiled, deep, multiPart);
     return exr && tiled;
 }
 
 
 bool
-isOpenExrFile (IStream &is, bool &tiled)
+isDeepOpenExrFile (const char fileName[])
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (fileName, tiled, deep, multiPart);
+    return exr && deep;
+}
+
+
+bool
+isMultiPartOpenExrFile (const char fileName[])
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (fileName, tiled, deep, multiPart);
+    return exr && multiPart;
+}
+
+
+bool
+isOpenExrFile
+    (IStream &is,
+     bool &tiled,
+     bool &deep,
+     bool &multiPart)
 {
     try
     {
-    Int64 pos = is.tellg();
+       Int64 pos = is.tellg();
 
-    if (pos != 0)
-        is.seekg (0);
+       if (pos != 0)
+           is.seekg (0);
 
-    int magic, version;
-    Xdr::read <StreamIO> (is, magic);
-    Xdr::read <StreamIO> (is, version);
+       int magic, version;
+       Xdr::read <StreamIO> (is, magic);
+       Xdr::read <StreamIO> (is, version);
 
-    is.seekg (pos);
+       is.seekg (pos);
 
-    tiled = isTiled (version);
-    return magic == MAGIC;
+       tiled = isTiled (version);
+       deep = isNonImage (version);
+       multiPart = isMultiPart (version);
+       return magic == MAGIC;
     }
     catch (...)
     {
-    is.clear();
-    tiled = false;
-    return false;
+       is.clear();
+       tiled = false;
+       return false;
     }
 }
 
 
 bool
-isOpenExrFile (IStream &is)
+isOpenExrFile (IStream &is, bool &tiled, bool &deep)
+{
+    bool multiPart;
+    return isOpenExrFile (is, tiled, deep, multiPart);
+}
+
+
+bool
+isOpenExrFile (IStream &is, bool &tiled)
 {
-    bool tiled;
-    return isOpenExrFile (is, tiled);
+    bool deep, multiPart;
+    return isOpenExrFile (is, tiled, deep, multiPart);
 }
 
 
 bool
-isTiledOpenExrFile (IStream &is)
+isOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
 {
-    bool exr, tiled;
-    exr = isOpenExrFile (is, tiled);
+    bool tiled, deep, multiPart;
+    return isOpenExrFile (is, tiled, deep, multiPart);
+}
+
+
+bool
+isTiledOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (is, tiled, deep, multiPart);
     return exr && tiled;
 }
 
-} // namespace Imf
+
+bool
+isDeepOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (is, tiled, deep, multiPart);
+    return exr && deep;
+}
+
+
+bool
+isMultiPartOpenExrFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is)
+{
+    bool exr, tiled, deep, multiPart;
+    exr = isOpenExrFile (is, tiled, deep, multiPart);
+    return exr && multiPart;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index e7e5065..d02d3bc 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+IMF_EXPORT bool isOpenExrFile (const char fileName[]);
+
+IMF_EXPORT bool isOpenExrFile (const char fileName[],
+                               bool &isTiled);
+
+IMF_EXPORT bool isOpenExrFile (const char fileName[],
+                               bool &isTiled,
+                               bool &isDeep);
+
+IMF_EXPORT bool isOpenExrFile (const char fileName[],
+                               bool &isTiled,
+                               bool &isDeep,
+                               bool &isMultiPart);
+
+IMF_EXPORT bool isTiledOpenExrFile (const char fileName[]);
+
+IMF_EXPORT bool isDeepOpenExrFile (const char fileName[]);
+
+IMF_EXPORT bool isMultiPartOpenExrFile (const char fileName[]);
+
+IMF_EXPORT bool isOpenExrFile (IStream &is);
+
+IMF_EXPORT bool isOpenExrFile (IStream &is,
+                               bool &isTiled);
+
+IMF_EXPORT bool isOpenExrFile (IStream &is,
+                               bool &isTiled,
+                               bool &isDeep);
 
-namespace Imf {
+IMF_EXPORT bool isOpenExrFile (IStream &is,
+                               bool &isTiled,
+                               bool &isDeep,
+                               bool &isMultiPart);
 
-class IStream;
+IMF_EXPORT bool isTiledOpenExrFile (IStream &is);
 
+IMF_EXPORT bool isDeepOpenExrFile (IStream &is);
 
-bool isOpenExrFile (const char fileName[], bool &isTiled);
-bool isOpenExrFile (const char fileName[]);
-bool isTiledOpenExrFile (const char fileName[]);
-bool isOpenExrFile (IStream &is, bool &isTiled);
-bool isOpenExrFile (IStream &is);
-bool isTiledOpenExrFile (IStream &is);
+IMF_EXPORT bool isMultiPartOpenExrFile (IStream &is);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index b69741f..a3cf383 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include "IlmThreadPool.h"
 #include "ImfThreading.h"
+#include "IlmThreadPool.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 int
 globalThreadCount ()
 {
-    return IlmThread::ThreadPool::globalThreadPool().numThreads();
+    return ILMTHREAD_NAMESPACE::ThreadPool::globalThreadPool().numThreads();
 }
 
 
 void
 setGlobalThreadCount (int count)
 {
-    IlmThread::ThreadPool::globalThreadPool().setNumThreads (count);
+    ILMTHREAD_NAMESPACE::ThreadPool::globalThreadPool().setNumThreads (count);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index efd9a65..4d1db04 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,6 +35,9 @@
 #ifndef INCLUDED_IMF_THREADING_H
 #define INCLUDED_IMF_THREADING_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 //-----------------------------------------------------------------------------
 //
 //     Threading support for the IlmImf library
@@ -50,7 +53,7 @@
 //     done concurrently through pinelining.  If there are two or more
 //     worker threads, then pipelining as well as concurrent compression
 //     of multiple blocks can be performed.
-//
+// 
 //     Threading in the Imf library is controllable at two granularities:
 //
 //     * The functions in this file query and control the total number
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-----------------------------------------------------------------------------
 // Return the number of Imf-global worker threads used for parallel
 // compression and decompression of OpenEXR files.
 //-----------------------------------------------------------------------------
-
-int     globalThreadCount ();
+    
+IMF_EXPORT int     globalThreadCount ();
 
 
 //-----------------------------------------------------------------------------
 // Change the number of Imf-global worker threads
 //-----------------------------------------------------------------------------
 
-void    setGlobalThreadCount (int count);
+IMF_EXPORT void    setGlobalThreadCount (int count);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 9534133..7b219c8 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -41,8 +41,9 @@
 //     class TileDescription and enum LevelMode
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 enum LevelMode
@@ -50,7 +51,7 @@ enum LevelMode
     ONE_LEVEL = 0,
     MIPMAP_LEVELS = 1,
     RIPMAP_LEVELS = 2,
-
+    
     NUM_LEVELMODES     // number of different level modes
 };
 
@@ -72,31 +73,35 @@ class TileDescription
     unsigned int       ySize;          // size of a tile in the y dimension
     LevelMode          mode;
     LevelRoundingMode  roundingMode;
-
+    
     TileDescription (unsigned int xs = 32,
-             unsigned int ys = 32,
+                    unsigned int ys = 32,
                      LevelMode m = ONE_LEVEL,
-             LevelRoundingMode r = ROUND_DOWN)
+                    LevelRoundingMode r = ROUND_DOWN)
     :
         xSize (xs),
-    ySize (ys),
-    mode (m),
-    roundingMode (r)
+       ySize (ys),
+       mode (m),
+       roundingMode (r)
     {
-    // empty
+       // empty
     }
 
     bool
     operator == (const TileDescription &other) const
     {
-    return xSize        == other.xSize &&
-           ySize        == other.ySize &&
-           mode         == other.mode &&
-           roundingMode == other.roundingMode;
+       return xSize        == other.xSize &&
+              ySize        == other.ySize &&
+              mode         == other.mode &&
+              roundingMode == other.roundingMode;
     }
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index e2545f5..18aead5 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,8 +42,9 @@
 #include <ImfTileDescriptionAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -55,7 +56,7 @@ TileDescriptionAttribute::staticTypeName ()
 
 template <>
 void
-TileDescriptionAttribute::writeValueTo (OStream &os, int) const
+TileDescriptionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.xSize);
     Xdr::write <StreamIO> (os, _value.ySize);
@@ -67,9 +68,9 @@ TileDescriptionAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-TileDescriptionAttribute::readValueFrom (IStream &is,
-                     int,
-                     int)
+TileDescriptionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                        int size,
+                                        int version)
 {
     Xdr::read <StreamIO> (is, _value.xSize);
     Xdr::read <StreamIO> (is, _value.ySize);
@@ -78,8 +79,8 @@ TileDescriptionAttribute::readValueFrom (IStream &is,
     Xdr::read <StreamIO> (is, tmp);
     _value.mode = LevelMode (tmp & 0x0f);
     _value.roundingMode = LevelRoundingMode ((tmp >> 4) & 0x0f);
-
+    
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index cb1ff2b..a8b69b9 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfTileDescription.h>
+#include "ImfAttribute.h"
+#include "ImfTileDescription.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-
-typedef TypedAttribute<TileDescription> TileDescriptionAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::TileDescription> TileDescriptionAttribute;
 
 template <>
+IMF_EXPORT 
 const char *
 TileDescriptionAttribute::staticTypeName ();
 
 template <>
+IMF_EXPORT 
 void
-TileDescriptionAttribute::writeValueTo (OStream &, int) const;
+TileDescriptionAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                        int) const;
 
 template <>
+IMF_EXPORT 
 void
-TileDescriptionAttribute::readValueFrom (IStream &, int, int);
-
+TileDescriptionAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                         int, int);
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfTileDescriptionAttribute.cpp>
-#endif
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 0eba39b..b0b40f6 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include <ImfXdr.h>
 #include <ImfIO.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
+#include <algorithm>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 TileOffsets::TileOffsets (LevelMode mode,
-              int numXLevels, int numYLevels,
-              const int *numXTiles, const int *numYTiles)
+                         int numXLevels, int numYLevels,
+                         const int *numXTiles, const int *numYTiles)
 :
     _mode (mode),
     _numXLevels (numXLevels),
@@ -67,7 +69,7 @@ TileOffsets::TileOffsets (LevelMode mode,
             _offsets[l].resize (numYTiles[l]);
 
             for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
-        {
+           {
                 _offsets[l][dy].resize (numXTiles[l]);
             }
         }
@@ -77,20 +79,23 @@ TileOffsets::TileOffsets (LevelMode mode,
 
         _offsets.resize (_numXLevels * _numYLevels);
 
-        for (unsigned int ly = 0; ly < _numYLevels; ++ly)
+        for (int ly = 0; ly < _numYLevels; ++ly)
         {
-            for (unsigned int lx = 0; lx < _numXLevels; ++lx)
+            for (int lx = 0; lx < _numXLevels; ++lx)
             {
                 int l = ly * _numXLevels + lx;
                 _offsets[l].resize (numYTiles[ly]);
 
-                for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+                for (size_t dy = 0; dy < _offsets[l].size(); ++dy)
                 {
                     _offsets[l][dy].resize (numXTiles[lx]);
                 }
             }
         }
         break;
+
+      case NUM_LEVELMODES :
+          throw IEX_NAMESPACE::ArgExc("Bad initialisation of TileOffsets object");
     }
 }
 
@@ -99,55 +104,76 @@ bool
 TileOffsets::anyOffsetsAreInvalid () const
 {
     for (unsigned int l = 0; l < _offsets.size(); ++l)
-    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
-        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
-        if (_offsets[l][dy][dx] <= 0)
-            return true;
-
+       for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+           for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
+               if (_offsets[l][dy][dx] <= 0)
+                   return true;
+    
     return false;
 }
 
 
 void
-TileOffsets::findTiles (IStream &is)
+TileOffsets::findTiles (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool isMultiPartFile, bool isDeep, bool skipOnly)
 {
     for (unsigned int l = 0; l < _offsets.size(); ++l)
     {
-    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
-    {
-        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
-        {
-        Int64 tileOffset = is.tellg();
+       for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+       {
+           for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
+           {
+               Int64 tileOffset = is.tellg();
 
-        int tileX;
-        Xdr::read <StreamIO> (is, tileX);
+               if (isMultiPartFile)
+               {
+                   int partNumber;
+                   OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, partNumber);
+               }
 
-        int tileY;
-        Xdr::read <StreamIO> (is, tileY);
+               int tileX;
+               OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tileX);
 
-        int levelX;
-        Xdr::read <StreamIO> (is, levelX);
+               int tileY;
+               OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tileY);
 
-        int levelY;
-        Xdr::read <StreamIO> (is, levelY);
+               int levelX;
+               OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelX);
 
-        int dataSize;
-        Xdr::read <StreamIO> (is, dataSize);
+               int levelY;
+               OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelY);
 
-        Xdr::skip <StreamIO> (is, dataSize);
+                if(isDeep)
+                {
+                     Int64 packed_offset_table_size;
+                     Int64 packed_sample_size;
+                     
+                     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset_table_size);
+                     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample_size);
+                     
+                     // next Int64 is unpacked sample size - skip that too
+                     Xdr::skip <StreamIO> (is, packed_offset_table_size+packed_sample_size+8);
+                    
+                }else{
+                    
+                    int dataSize;
+                    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, dataSize);
+
+                    Xdr::skip <StreamIO> (is, dataSize);
+                }
+               if (skipOnly) continue;
 
-        if (!isValidTile(tileX, tileY, levelX, levelY))
-            return;
+               if (!isValidTile(tileX, tileY, levelX, levelY))
+                   return;
 
-        operator () (tileX, tileY, levelX, levelY) = tileOffset;
-        }
-    }
+               operator () (tileX, tileY, levelX, levelY) = tileOffset;
+           }
+       }
     }
 }
 
 
 void
-TileOffsets::reconstructFromFile (IStream &is)
+TileOffsets::reconstructFromFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,bool isMultiPart,bool isDeep)
 {
     //
     // Try to reconstruct a missing tile offset table by sequentially
@@ -159,14 +185,14 @@ TileOffsets::reconstructFromFile (IStream &is)
 
     try
     {
-    findTiles (is);
+       findTiles (is,isMultiPart,isDeep,false);
     }
     catch (...)
     {
         //
         // Suppress all exceptions.  This function is called only to
-    // reconstruct the tile offset table for incomplete files,
-    // and exceptions are likely.
+       // reconstruct the tile offset table for incomplete files,
+       // and exceptions are likely.
         //
     }
 
@@ -176,16 +202,16 @@ TileOffsets::reconstructFromFile (IStream &is)
 
 
 void
-TileOffsets::readFrom (IStream &is, bool &complete)
+TileOffsets::readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool &complete,bool isMultiPartFile, bool isDeep)
 {
     //
     // Read in the tile offsets from the file's tile offset table
     //
 
     for (unsigned int l = 0; l < _offsets.size(); ++l)
-    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
-        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
-        Xdr::read <StreamIO> (is, _offsets[l][dy][dx]);
+       for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+           for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
+               OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _offsets[l][dy][dx]);
 
     //
     // Check if any tile offsets are invalid.
@@ -203,48 +229,182 @@ TileOffsets::readFrom (IStream &is, bool &complete)
 
     if (anyOffsetsAreInvalid())
     {
-    complete = false;
-    reconstructFromFile (is);
+       complete = false;
+       reconstructFromFile (is,isMultiPartFile,isDeep);
     }
     else
     {
-    complete = true;
+       complete = true;
     }
 
 }
 
 
+void
+TileOffsets::readFrom (std::vector<Int64> chunkOffsets,bool &complete)
+{
+    size_t totalSize = 0;
+    for (unsigned int l = 0; l < _offsets.size(); ++l)
+        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+            totalSize += _offsets[l][dy].size();
+
+    if (chunkOffsets.size() != totalSize)
+        throw IEX_NAMESPACE::ArgExc ("Wrong offset count, not able to read from this array");
+
+
+
+    int pos = 0;
+    for (size_t l = 0; l < _offsets.size(); ++l)
+        for (size_t dy = 0; dy < _offsets[l].size(); ++dy)
+            for (size_t dx = 0; dx < _offsets[l][dy].size(); ++dx)
+            {
+                _offsets[l][dy][dx] = chunkOffsets[pos];
+                pos++;
+            }
+
+    complete = !anyOffsetsAreInvalid();
+
+}
+
+
 Int64
-TileOffsets::writeTo (OStream &os) const
+TileOffsets::writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os) const
 {
     //
     // Write the tile offset table to the file, and
     // return the position of the start of the table
     // in the file.
     //
-
+    
     Int64 pos = os.tellp();
 
     if (pos == -1)
-    Iex::throwErrnoExc ("Cannot determine current file position (%T).");
+       IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
 
     for (unsigned int l = 0; l < _offsets.size(); ++l)
-    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
-        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
-        Xdr::write <StreamIO> (os, _offsets[l][dy][dx]);
+       for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+           for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
+               OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _offsets[l][dy][dx]);
 
     return pos;
 }
 
+namespace {
+struct tilepos{
+    Int64 filePos;
+    int dx;
+    int dy;
+    int l;
+    bool operator <(const tilepos & other) const
+    {
+        return filePos < other.filePos;
+    }
+};
+}
+//-------------------------------------
+// fill array with tile coordinates in the order they appear in the file
+//
+// each input array must be of size (totalTiles)
+// 
+//
+// if the tile order is not RANDOM_Y, it is more efficient to compute the
+// tile ordering rather than using this function
+//
+//-------------------------------------
+void TileOffsets::getTileOrder(int dx_table[],int dy_table[],int lx_table[],int ly_table[]) const
+{
+    // 
+    // helper class
+    // 
+
+    // how many entries?
+    size_t entries=0;
+    for (unsigned int l = 0; l < _offsets.size(); ++l)
+        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+           entries+=_offsets[l][dy].size();
+        
+    std::vector<struct tilepos> table(entries);
+    
+    size_t i = 0;
+    for (unsigned int l = 0; l < _offsets.size(); ++l)
+        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+            for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
+            {
+                table[i].filePos = _offsets[l][dy][dx];
+                table[i].dx = dx;
+                table[i].dy = dy;
+                table[i].l = l;
+
+                ++i;
+                
+            }
+              
+    std::sort(table.begin(),table.end());
+    
+    //
+    // write out the values
+    //
+    
+    // pass 1: write out dx and dy, since these are independent of level mode
+    
+    for(size_t i=0;i<entries;i++)
+    {
+        dx_table[i] = table[i].dx;
+        dy_table[i] = table[i].dy;
+    }
+
+    // now write out the levels, which depend on the level mode
+    
+    switch (_mode)
+    {
+        case ONE_LEVEL:
+        {
+            for(size_t i=0;i<entries;i++)
+            {
+                lx_table[i] = 0;
+                ly_table[i] = 0;               
+            }
+            break;            
+        }
+        case MIPMAP_LEVELS:
+        {
+            for(size_t i=0;i<entries;i++)
+            {
+                lx_table[i]= table[i].l;
+                ly_table[i] =table[i].l;               
+                
+            }
+            break;
+        }
+            
+        case RIPMAP_LEVELS:
+        {
+            for(size_t i=0;i<entries;i++)
+            {
+                lx_table[i]= table[i].l % _numXLevels;
+                ly_table[i] = table[i].l / _numXLevels; 
+                
+            }
+            break;
+        }
+        case NUM_LEVELMODES :
+            throw IEX_NAMESPACE::LogicExc("Bad level mode getting tile order");
+    }
+    
+    
+    
+}
+
 
 bool
 TileOffsets::isEmpty () const
 {
     for (unsigned int l = 0; l < _offsets.size(); ++l)
-    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
-        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
-        if (_offsets[l][dy][dx] != 0)
-            return false;
+       for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
+           for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
+               if (_offsets[l][dy][dx] != 0)
+                   return false;
     return true;
 }
 
@@ -252,44 +412,45 @@ TileOffsets::isEmpty () const
 bool
 TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
 {
+    if(lx<0 || ly < 0 || dx<0 || dy < 0) return false;
     switch (_mode)
     {
       case ONE_LEVEL:
 
         if (lx == 0 &&
-        ly == 0 &&
-        _offsets.size() > 0 &&
-            _offsets[0].size() > dy &&
-            _offsets[0][dy].size() > dx)
-    {
+           ly == 0 &&
+           _offsets.size() > 0 &&
+            int(_offsets[0].size()) > dy &&
+            int(_offsets[0][dy].size()) > dx)
+       {
             return true;
-    }
+       }
 
         break;
 
       case MIPMAP_LEVELS:
 
         if (lx < _numXLevels &&
-        ly < _numYLevels &&
-            _offsets.size() > lx &&
-            _offsets[lx].size() > dy &&
-            _offsets[lx][dy].size() > dx)
-    {
+           ly < _numYLevels &&
+            int(_offsets.size()) > lx &&
+            int(_offsets[lx].size()) > dy &&
+            int(_offsets[lx][dy].size()) > dx)
+       {
             return true;
-    }
+       }
 
         break;
 
       case RIPMAP_LEVELS:
 
         if (lx < _numXLevels &&
-        ly < _numYLevels &&
-            _offsets.size() > lx + ly * _numXLevels &&
-            _offsets[lx + ly * _numXLevels].size() > dy &&
-            _offsets[lx + ly * _numXLevels][dy].size() > dx)
-    {
+           ly < _numYLevels &&
+           (_offsets.size() > (size_t) lx+  ly *  (size_t) _numXLevels) &&
+            int(_offsets[lx + ly * _numXLevels].size()) > dy &&
+            int(_offsets[lx + ly * _numXLevels][dy].size()) > dx)
+       {
             return true;
-    }
+       }
 
         break;
 
@@ -297,7 +458,7 @@ TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
 
         return false;
     }
-
+    
     return false;
 }
 
@@ -330,7 +491,7 @@ TileOffsets::operator () (int dx, int dy, int lx, int ly)
 
       default:
 
-        throw Iex::ArgExc ("Unknown LevelMode format.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 }
 
@@ -370,7 +531,7 @@ TileOffsets::operator () (int dx, int dy, int lx, int ly) const
 
       default:
 
-        throw Iex::ArgExc ("Unknown LevelMode format.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 }
 
@@ -381,5 +542,11 @@ TileOffsets::operator () (int dx, int dy, int l) const
     return operator () (dx, dy, l, l);
 }
 
+const std::vector<std::vector<std::vector <Int64> > >&
+TileOffsets::getOffsets() const
+{
+    return _offsets;
+}
+
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 13026c9..383dfc4 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfTileDescription.h>
-#include <ImfInt64.h>
+#include "ImfTileDescription.h"
+#include "ImfInt64.h"
 #include <vector>
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
 
-namespace Imf {
-
-class IStream;
-class OStream;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class TileOffsets
 {
   public:
 
+    IMF_EXPORT
     TileOffsets (LevelMode mode = ONE_LEVEL,
-         int numXLevels = 0,
-         int numYLevels = 0,
-         const int *numXTiles = 0,
-         const int *numYTiles = 0);
+                int numXLevels = 0,
+                int numYLevels = 0,
+                const int *numXTiles = 0,
+                const int *numYTiles = 0);    
 
     // --------
     // File I/O
     // --------
 
-    void               readFrom (IStream &is, bool &complete);
-    Int64              writeTo (OStream &os) const;
+    IMF_EXPORT
+    void               readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,  bool &complete,bool isMultiPart,bool isDeep);
+    IMF_EXPORT
+    void        readFrom (std::vector<Int64> chunkOffsets,bool &complete);
+    IMF_EXPORT
+    Int64              writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os) const;
 
 
     //-----------------------------------------------------------
     // Test if the tileOffsets array is empty (all entries are 0)
     //-----------------------------------------------------------
 
+    IMF_EXPORT
     bool               isEmpty () const;
-
-
+    
+    
+    
+    //-----------------------------------------------------------
+    // populate 'list' with tiles coordinates in the order they appear
+    // in the offset table (assumes full table!
+    // each array myst be at leat totalTiles long
+    //-----------------------------------------------------------
+    IMF_EXPORT
+    void getTileOrder(int dx_table[], int dy_table[], int lx_table[], int ly_table[]) const;
+    
+    
     //-----------------------
     // Access to the elements
     //-----------------------
 
+    IMF_EXPORT
     Int64 &            operator () (int dx, int dy, int lx, int ly);
+    IMF_EXPORT
     Int64 &            operator () (int dx, int dy, int l);
+    IMF_EXPORT
     const Int64 &      operator () (int dx, int dy, int lx, int ly) const;
+    IMF_EXPORT
     const Int64 &      operator () (int dx, int dy, int l) const;
-
+    IMF_EXPORT
+    bool        isValidTile (int dx, int dy, int lx, int ly) const;
+    IMF_EXPORT
+    const std::vector<std::vector<std::vector <Int64> > >& getOffsets() const;
+    
   private:
 
-    void               findTiles (IStream &is);
-    void               reconstructFromFile (IStream &is);
-    bool               readTile (IStream &is);
+    void               findTiles (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool isMultiPartFile,
+                                   bool isDeep,
+                                  bool skipOnly);
+    void               reconstructFromFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,bool isMultiPartFile,bool isDeep);
+    bool               readTile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is);
     bool               anyOffsetsAreInvalid () const;
-    bool               isValidTile (int dx, int dy, int lx, int ly) const;
 
     LevelMode          _mode;
     int                        _numXLevels;
     int                        _numYLevels;
 
     std::vector<std::vector<std::vector <Int64> > > _offsets;
+    
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index 69cb276..b5fbeb7 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfTiledInputFile.h>
-#include <ImfTileDescriptionAttribute.h>
-#include <ImfChannelList.h>
-#include <ImfMisc.h>
-#include <ImfTiledMisc.h>
-#include <ImfStdIO.h>
-#include <ImfCompressor.h>
-#include "ImathBox.h"
-#include <ImfXdr.h>
-#include <ImfConvert.h>
-#include <ImfVersion.h>
-#include <ImfTileOffsets.h>
-#include <ImfThreading.h>
+#include "ImfTiledInputFile.h"
+#include "ImfTileDescriptionAttribute.h"
+#include "ImfChannelList.h"
+#include "ImfMisc.h"
+#include "ImfTiledMisc.h"
+#include "ImfStdIO.h"
+#include "ImfCompressor.h"
+#include "ImfXdr.h"
+#include "ImfConvert.h"
+#include "ImfVersion.h"
+#include "ImfTileOffsets.h"
+#include "ImfThreading.h"
+#include "ImfPartType.h"
+#include "ImfMultiPartInputFile.h"
+#include "ImfInputStreamMutex.h"
 #include "IlmThreadPool.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
 #include <vector>
 #include <algorithm>
 #include <assert.h>
+#include "ImfInputPartData.h"
+#include "ImfNamespace.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-namespace Imf {
-
-using Imath::Box2i;
-using Imath::V2i;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 using std::string;
 using std::vector;
 using std::min;
 using std::max;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
 
 namespace {
 
@@ -157,6 +160,7 @@ struct TileBuffer
 
 TileBuffer::TileBuffer (Compressor *comp):
     uncompressedData (0),
+    buffer (0),
     dataSize (0),
     compressor (comp),
     format (defaultFormat (compressor)),
@@ -180,6 +184,9 @@ TileBuffer::~TileBuffer ()
 } // namespace
 
 
+class MultiPartInputFile;
+
+
 //
 // struct TiledInputFile::Data stores things that will be
 // needed between calls to readTile()
@@ -187,61 +194,70 @@ TileBuffer::~TileBuffer ()
 
 struct TiledInputFile::Data: public Mutex
 {
-    Header         header;                 // the image header
-    TileDescription tileDesc;              // describes the tile layout
-    int                    version;                // file's version
-    FrameBuffer            frameBuffer;            // framebuffer to write into
-    LineOrder      lineOrder;              // the file's lineorder
-    int                    minX;                   // data window's min x coord
-    int                    maxX;                   // data window's max x coord
-    int                    minY;                   // data window's min y coord
-    int                    maxY;                   // data window's max x coord
+    Header         header;                         // the image header
+    TileDescription tileDesc;                      // describes the tile layout
+    int                    version;                        // file's version
+    FrameBuffer            frameBuffer;                    // framebuffer to write into
+    LineOrder      lineOrder;                      // the file's lineorder
+    int                    minX;                           // data window's min x coord
+    int                    maxX;                           // data window's max x coord
+    int                    minY;                           // data window's min y coord
+    int                    maxY;                           // data window's max x coord
 
-    int                    numXLevels;             // number of x levels
-    int                    numYLevels;             // number of y levels
-    int *          numXTiles;              // number of x tiles at a level
-    int *          numYTiles;              // number of y tiles at a level
+    int                    numXLevels;                     // number of x levels
+    int                    numYLevels;                     // number of y levels
+    int *          numXTiles;                      // number of x tiles at a level
+    int *          numYTiles;                      // number of y tiles at a level
 
-    TileOffsets            tileOffsets;            // stores offsets in file for
-                        // each tile
+    TileOffsets            tileOffsets;                    // stores offsets in file for
+    // each tile
 
-    bool           fileIsComplete;         // True if no tiles are missing
-                            // in the file
+    bool           fileIsComplete;                 // True if no tiles are missing
+                                                    // in the file
 
-    Int64          currentPosition;        // file offset for current tile,
-                        // used to prevent unnecessary
-                        // seeking
+    vector<TInSliceInfo> slices;                   // info about channels in file
 
-    vector<TInSliceInfo> slices;           // info about channels in file
-    IStream *      is;                     // file stream to read from
+    size_t         bytesPerPixel;                  // size of an uncompressed pixel
 
-    bool           deleteStream;           // should we delete the stream
-                        // ourselves? or does someone
-                        // else do it?
+    size_t         maxBytesPerTileLine;            // combined size of a line
+                                                    // over all channels
 
-    size_t         bytesPerPixel;          // size of an uncompressed pixel
+    int             partNumber;                     // part number
 
-    size_t         maxBytesPerTileLine;    // combined size of a line
-                        // over all channels
+    bool            multiPartBackwardSupport;       // if we are reading a multipart file
+                                                    // using OpenEXR 1.7 API
 
+    int             numThreads;                     // number of threads
 
-    vector<TileBuffer*> tileBuffers;        // each holds a single tile
-    size_t          tileBufferSize;        // size of the tile buffers
+    MultiPartInputFile* multiPartFile;              // the MultiPartInputFile used to
+                                                    // support backward compatibility
+    
+    vector<TileBuffer*> tileBuffers;                // each holds a single tile
+    size_t          tileBufferSize;                // size of the tile buffers
 
-     Data (bool deleteStream, int numThreads);
+    bool            memoryMapped;                   // if the stream is memory mapped
+
+    InputStreamMutex * _streamData;
+    bool                _deleteStream;
+
+     Data (int numThreads);
     ~Data ();
 
     inline TileBuffer * getTileBuffer (int number);
-                        // hash function from tile indices
-                        // into our vector of tile buffers
+                                           // hash function from tile indices
+                                           // into our vector of tile buffers
 };
 
 
-TiledInputFile::Data::Data (bool del, int numThreads):
+TiledInputFile::Data::Data (int numThreads):
     numXTiles (0),
     numYTiles (0),
-    is (0),
-    deleteStream (del)
+    partNumber (-1),
+    multiPartBackwardSupport(false),
+    numThreads(numThreads),
+    memoryMapped(false),
+    _streamData(NULL),
+    _deleteStream(false)
 {
     //
     // We need at least one tileBuffer, but if threading is used,
@@ -257,11 +273,11 @@ TiledInputFile::Data::~Data ()
     delete [] numXTiles;
     delete [] numYTiles;
 
-    if (deleteStream)
-    delete is;
-
     for (size_t i = 0; i < tileBuffers.size(); i++)
         delete tileBuffers[i];
+
+    if (multiPartBackwardSupport)
+        delete multiPartFile;
 }
 
 
@@ -275,9 +291,10 @@ TiledInputFile::Data::getTileBuffer (int number)
 namespace {
 
 void
-readTileData (TiledInputFile::Data *ifd,
-          int dx, int dy,
-          int lx, int ly,
+readTileData (InputStreamMutex *streamData,
+              TiledInputFile::Data *ifd,
+             int dx, int dy,
+             int lx, int ly,
               char *&buffer,
               int &dataSize)
 {
@@ -292,103 +309,144 @@ readTileData (TiledInputFile::Data *ifd,
     // Look up the location for this tile in the Index and
     // seek to that position if necessary
     //
-
+    
     Int64 tileOffset = ifd->tileOffsets (dx, dy, lx, ly);
 
     if (tileOffset == 0)
     {
-        THROW (Iex::InputExc, "Tile (" << dx << ", " << dy << ", " <<
-                  lx << ", " << ly << ") is missing.");
+        THROW (IEX_NAMESPACE::InputExc, "Tile (" << dx << ", " << dy << ", " <<
+                             lx << ", " << ly << ") is missing.");
     }
 
-    if (ifd->currentPosition != tileOffset)
-        ifd->is->seekg (tileOffset);
+
+    //
+    // In a multi-part file, the next chunk does not need to
+    // belong to the same part, so we have to compare the
+    // offset here.
+    //
+
+    if (!isMultiPart(ifd->version))
+    {
+        if (streamData->currentPosition != tileOffset)
+            streamData->is->seekg (tileOffset);
+    }
+    else
+    {
+        //
+        // In a multi-part file, the file pointer may be moved by other
+        // parts, so we have to ask tellg() where we are.
+        //
+        if (streamData->is->tellg() != tileOffset)
+            streamData->is->seekg (tileOffset);
+    }
 
     //
     // Read the first few bytes of the tile (the header).
     // Verify that the tile coordinates and the level number
     // are correct.
     //
-
+    
     int tileXCoord, tileYCoord, levelX, levelY;
 
-    Xdr::read <StreamIO> (*ifd->is, tileXCoord);
-    Xdr::read <StreamIO> (*ifd->is, tileYCoord);
-    Xdr::read <StreamIO> (*ifd->is, levelX);
-    Xdr::read <StreamIO> (*ifd->is, levelY);
-    Xdr::read <StreamIO> (*ifd->is, dataSize);
+    if (isMultiPart(ifd->version))
+    {
+        int partNumber;
+        Xdr::read <StreamIO> (*streamData->is, partNumber);
+        if (partNumber != ifd->partNumber)
+        {
+            THROW (IEX_NAMESPACE::ArgExc, "Unexpected part number " << partNumber
+                   << ", should be " << ifd->partNumber << ".");
+        }
+    }
+
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, tileXCoord);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, tileYCoord);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, levelX);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, levelY);
+    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (*streamData->is, dataSize);
 
     if (tileXCoord != dx)
-        throw Iex::InputExc ("Unexpected tile x coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x coordinate.");
 
     if (tileYCoord != dy)
-        throw Iex::InputExc ("Unexpected tile y coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y coordinate.");
 
     if (levelX != lx)
-        throw Iex::InputExc ("Unexpected tile x level number coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile x level number coordinate.");
 
     if (levelY != ly)
-        throw Iex::InputExc ("Unexpected tile y level number coordinate.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile y level number coordinate.");
 
     if (dataSize > (int) ifd->tileBufferSize)
-        throw Iex::InputExc ("Unexpected tile block length.");
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile block length.");
 
     //
     // Read the pixel data.
     //
 
-    if (ifd->is->isMemoryMapped ())
-        buffer = ifd->is->readMemoryMapped (dataSize);
+    if (streamData->is->isMemoryMapped ())
+        buffer = streamData->is->readMemoryMapped (dataSize);
     else
-        ifd->is->read (buffer, dataSize);
+        streamData->is->read (buffer, dataSize);
 
     //
     // Keep track of which tile is the next one in
     // the file, so that we can avoid redundant seekg()
     // operations (seekg() can be fairly expensive).
     //
-
-    ifd->currentPosition = tileOffset + 5 * Xdr::size<int>() + dataSize;
+    
+    streamData->currentPosition = tileOffset + 5 * Xdr::size<int>() + dataSize;
 }
 
 
 void
-readNextTileData (TiledInputFile::Data *ifd,
-          int &dx, int &dy,
-          int &lx, int &ly,
+readNextTileData (InputStreamMutex *streamData,
+                  TiledInputFile::Data *ifd,
+                 int &dx, int &dy,
+                 int &lx, int &ly,
                   char * & buffer,
-          int &dataSize)
+                 int &dataSize)
 {
     //
     // Read the next tile block from the file
     //
 
+    if(isMultiPart(ifd->version))
+    {
+        int part;
+        Xdr::read <StreamIO> (*streamData->is, part);
+        if(part!=ifd->partNumber)
+        {
+           throw IEX_NAMESPACE::InputExc("Unexpected part number in readNextTileData");
+        }
+    }
+
     //
     // Read the first few bytes of the tile (the header).
     //
 
-    Xdr::read <StreamIO> (*ifd->is, dx);
-    Xdr::read <StreamIO> (*ifd->is, dy);
-    Xdr::read <StreamIO> (*ifd->is, lx);
-    Xdr::read <StreamIO> (*ifd->is, ly);
-    Xdr::read <StreamIO> (*ifd->is, dataSize);
+    Xdr::read <StreamIO> (*streamData->is, dx);
+    Xdr::read <StreamIO> (*streamData->is, dy);
+    Xdr::read <StreamIO> (*streamData->is, lx);
+    Xdr::read <StreamIO> (*streamData->is, ly);
+    Xdr::read <StreamIO> (*streamData->is, dataSize);
 
     if (dataSize > (int) ifd->tileBufferSize)
-        throw Iex::InputExc ("Unexpected tile block length.");
-
+        throw IEX_NAMESPACE::InputExc ("Unexpected tile block length.");
+    
     //
     // Read the pixel data.
     //
 
-    ifd->is->read (buffer, dataSize);
-
+    streamData->is->read (buffer, dataSize);
+    
     //
     // Keep track of which tile is the next one in
     // the file, so that we can avoid redundant seekg()
     // operations (seekg() can be fairly expensive).
     //
 
-    ifd->currentPosition += 5 * Xdr::size<int>() + dataSize;
+    streamData->currentPosition += 5 * Xdr::size<int>() + dataSize;
 }
 
 
@@ -403,12 +461,12 @@ class TileBufferTask : public Task
 
     TileBufferTask (TaskGroup *group,
                     TiledInputFile::Data *ifd,
-            TileBuffer *tileBuffer);
-
+                   TileBuffer *tileBuffer);
+                    
     virtual ~TileBufferTask ();
 
     virtual void               execute ();
-
+    
   private:
 
     TiledInputFile::Data *     _ifd;
@@ -447,34 +505,35 @@ TileBufferTask::execute ()
         //
         // Calculate information about the tile
         //
-
-        Box2i tileRange = Imf::dataWindowForTile (_ifd->tileDesc,
-                                                  _ifd->minX, _ifd->maxX,
-                                                  _ifd->minY, _ifd->maxY,
-                                                  _tileBuffer->dx,
-                                                  _tileBuffer->dy,
-                                                  _tileBuffer->lx,
-                                                  _tileBuffer->ly);
+    
+        Box2i tileRange =  OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _ifd->tileDesc,
+                _ifd->minX, _ifd->maxX,
+                _ifd->minY, _ifd->maxY,
+                _tileBuffer->dx,
+                _tileBuffer->dy,
+                _tileBuffer->lx,
+                _tileBuffer->ly);
 
         int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1;
-
+    
         int numPixelsInTile = numPixelsPerScanLine *
                             (tileRange.max.y - tileRange.min.y + 1);
-
+    
         int sizeOfTile = _ifd->bytesPerPixel * numPixelsInTile;
-
-
+    
+    
         //
         // Uncompress the data, if necessary
         //
-
+    
         if (_tileBuffer->compressor && _tileBuffer->dataSize < sizeOfTile)
         {
             _tileBuffer->format = _tileBuffer->compressor->format();
 
             _tileBuffer->dataSize = _tileBuffer->compressor->uncompressTile
-        (_tileBuffer->buffer, _tileBuffer->dataSize,
-         tileRange, _tileBuffer->uncompressedData);
+               (_tileBuffer->buffer, _tileBuffer->dataSize,
+                tileRange, _tileBuffer->uncompressedData);
         }
         else
         {
@@ -482,54 +541,54 @@ TileBufferTask::execute ()
             // If the line is uncompressed, it's in XDR format,
             // regardless of the compressor's output format.
             //
-
+    
             _tileBuffer->format = Compressor::XDR;
             _tileBuffer->uncompressedData = _tileBuffer->buffer;
         }
-
+    
         //
         // Convert the tile of pixel data back from the machine-independent
-    // representation, and store the result in the frame buffer.
+       // representation, and store the result in the frame buffer.
         //
-
+    
         const char *readPtr = _tileBuffer->uncompressedData;
                                                         // points to where we
                                                         // read from in the
                                                         // tile block
-
+        
         //
         // Iterate over the scan lines in the tile.
         //
-
+    
         for (int y = tileRange.min.y; y <= tileRange.max.y; ++y)
         {
             //
             // Iterate over all image channels.
             //
-
+            
             for (unsigned int i = 0; i < _ifd->slices.size(); ++i)
             {
                 const TInSliceInfo &slice = _ifd->slices[i];
-
+    
                 //
                 // These offsets are used to facilitate both
                 // absolute and tile-relative pixel coordinates.
                 //
-
+            
                 int xOffset = slice.xTileCoords * tileRange.min.x;
                 int yOffset = slice.yTileCoords * tileRange.min.y;
-
+    
                 //
                 // Fill the frame buffer with pixel data.
                 //
-
+    
                 if (slice.skip)
                 {
                     //
                     // The file contains data for this channel, but
                     // the frame buffer contains no slice for this channel.
                     //
-
+    
                     skipChannel (readPtr, slice.typeInFile,
                                  numPixelsPerScanLine);
                 }
@@ -538,7 +597,7 @@ TileBufferTask::execute ()
                     //
                     // The frame buffer contains a slice for this channel.
                     //
-
+    
                     char *writePtr = slice.base +
                                      (y - yOffset) * slice.yStride +
                                      (tileRange.min.x - xOffset) *
@@ -546,7 +605,7 @@ TileBufferTask::execute ()
 
                     char *endPtr = writePtr +
                                    (numPixelsPerScanLine - 1) * slice.xStride;
-
+                                    
                     copyIntoFrameBuffer (readPtr, writePtr, endPtr,
                                          slice.xStride,
                                          slice.fill, slice.fillValue,
@@ -579,6 +638,7 @@ TileBufferTask::execute ()
 TileBufferTask *
 newTileBufferTask
     (TaskGroup *group,
+     InputStreamMutex *streamData,
      TiledInputFile::Data *ifd,
      int number,
      int dx, int dy,
@@ -596,29 +656,29 @@ newTileBufferTask
 
     try
     {
-    tileBuffer->wait();
-
-    tileBuffer->dx = dx;
-    tileBuffer->dy = dy;
-    tileBuffer->lx = lx;
-    tileBuffer->ly = ly;
-
-    tileBuffer->uncompressedData = 0;
-
-    readTileData (ifd, dx, dy, lx, ly,
-              tileBuffer->buffer,
-              tileBuffer->dataSize);
+       tileBuffer->wait();
+       
+       tileBuffer->dx = dx;
+       tileBuffer->dy = dy;
+       tileBuffer->lx = lx;
+       tileBuffer->ly = ly;
+
+       tileBuffer->uncompressedData = 0;
+
+       readTileData (streamData, ifd, dx, dy, lx, ly,
+                     tileBuffer->buffer,
+                     tileBuffer->dataSize);
     }
     catch (...)
     {
-    //
-    // Reading from the file caused an exception.
-    // Signal that the tile buffer is free, and
-    // re-throw the exception.
-    //
-
-    tileBuffer->post();
-    throw;
+       //
+       // Reading from the file caused an exception.
+       // Signal that the tile buffer is free, and
+       // re-throw the exception.
+       //
+
+       tileBuffer->post();
+       throw;
     }
 
     return new TileBufferTask (group, ifd, tileBuffer);
@@ -629,92 +689,229 @@ newTileBufferTask
 
 
 TiledInputFile::TiledInputFile (const char fileName[], int numThreads):
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads))
 {
+    _data->_streamData=NULL;
+    _data->_deleteStream=true;
+    
     //
     // This constructor is called when a user
     // explicitly wants to read a tiled file.
     //
 
+
+    IStream* is = 0;
     try
     {
-    _data->is = new StdIFStream (fileName);
-    _data->header.readFrom (*_data->is, _data->version);
-    initialize();
+        is = new StdIFStream (fileName);
+       readMagicNumberAndVersionField(*is, _data->version);
+
+       //
+        // Backward compatibility to read multpart file.
+        //
+       if (isMultiPart(_data->version))
+       {
+           compatibilityInitialize(*is);
+           return;
+       }
+
+       _data->_streamData = new InputStreamMutex();
+       _data->_streamData->is = is;
+       _data->header.readFrom (*_data->_streamData->is, _data->version);
+       initialize();
+        //read tile offsets - we are not multipart or deep
+        _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+       _data->_streamData->currentPosition = _data->_streamData->is->tellg();
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        if (_data->_streamData != 0)
+        {
+            if (_data->_streamData->is != 0)
+            {
+                delete _data->_streamData->is;
+                _data->_streamData->is = is = 0;
+            }
 
-    REPLACE_EXC (e, "Cannot open image file "
-            "\"" << fileName << "\". " << e);
-    throw;
+            delete _data->_streamData;
+        }
+
+        if (is != 0)
+            delete is;
+
+       REPLACE_EXC (e, "Cannot open image file "
+                 "\"" << fileName << "\". " << e.what());
+       throw;
     }
     catch (...)
     {
-    delete _data;
+        if ( _data->_streamData != 0)
+        {
+            if ( _data->_streamData->is != 0)
+            {
+                delete _data->_streamData->is;
+                _data->_streamData->is = is = 0;
+            }
+
+            delete _data->_streamData;
+        }
+
+        if (is != 0)
+            delete is;
         throw;
     }
 }
 
 
-TiledInputFile::TiledInputFile (IStream &is, int numThreads):
-    _data (new Data (false, numThreads))
+TiledInputFile::TiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
+    _data (new Data (numThreads))
 {
+    _data->_deleteStream=false;
     //
     // This constructor is called when a user
     // explicitly wants to read a tiled file.
     //
 
+    bool streamDataCreated = false;
+
     try
     {
-    _data->is = &is;
-    _data->header.readFrom (*_data->is, _data->version);
-    initialize();
+       readMagicNumberAndVersionField(is, _data->version);
+
+       //
+       // Backward compatibility to read multpart file.
+       //
+       if (isMultiPart(_data->version))
+        {
+           compatibilityInitialize(is);
+            return;
+        }
+
+       streamDataCreated = true;
+       _data->_streamData = new InputStreamMutex();
+       _data->_streamData->is = &is;
+       _data->header.readFrom (*_data->_streamData->is, _data->version);
+       initialize();
+        // file is guaranteed to be single part, regular image
+        _data->tileOffsets.readFrom (*(_data->_streamData->is), _data->fileIsComplete,false,false);
+       _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+       _data->_streamData->currentPosition = _data->_streamData->is->tellg();
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        if (streamDataCreated) delete _data->_streamData;
+       delete _data;
 
-    REPLACE_EXC (e, "Cannot open image file "
-            "\"" << is.fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Cannot open image file "
+                 "\"" << is.fileName() << "\". " << e.what());
+       throw;
     }
     catch (...)
     {
-    delete _data;
+        if (streamDataCreated) delete _data->_streamData;
+       delete _data;
         throw;
     }
 }
 
 
-TiledInputFile::TiledInputFile
-    (const Header &header,
-     IStream *is,
-     int version,
-     int numThreads)
-:
-    _data (new Data (false, numThreads))
+TiledInputFile::TiledInputFile (const Header &header,
+                                OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is,
+                                int version,
+                                int numThreads) :
+    _data (new Data (numThreads))
 {
+    _data->_deleteStream=false;
+    _data->_streamData = new InputStreamMutex();
     //
     // This constructor called by class Imf::InputFile
     // when a user wants to just read an image file, and
     // doesn't care or know if the file is tiled.
+    // No need to have backward compatibility here, because
+    // we have somehow got the header.
     //
 
-    _data->is = is;
+    _data->_streamData->is = is;
     _data->header = header;
     _data->version = version;
     initialize();
+    _data->tileOffsets.readFrom (*(_data->_streamData->is),_data->fileIsComplete,false,false);
+    _data->memoryMapped = is->isMemoryMapped();
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
+
+TiledInputFile::TiledInputFile (InputPartData* part) 
+{
+    _data = new Data (part->numThreads);
+    _data->_deleteStream=false;
+    multiPartInitialize(part);
 }
 
 
 void
-TiledInputFile::initialize ()
+TiledInputFile::compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is)
 {
-    if (!isTiled (_data->version))
-    throw Iex::ArgExc ("Expected a tiled file but the file is not tiled.");
+    is.seekg(0);
+    //
+    // Construct a MultiPartInputFile, initialize TiledInputFile
+    // with the part 0 data.
+    // (TODO) maybe change the third parameter of the constructor of MultiPartInputFile later.
+    //
+    _data->multiPartBackwardSupport = true;
+    _data->multiPartFile = new MultiPartInputFile(is, _data->numThreads);
+    InputPartData* part = _data->multiPartFile->getPart(0);
 
+    multiPartInitialize(part);
+}
+
+
+void
+TiledInputFile::multiPartInitialize(InputPartData* part)
+{
+    if (part->header.type() != TILEDIMAGE)
+        throw IEX_NAMESPACE::ArgExc("Can't build a TiledInputFile from a type-mismatched part.");
+
+    _data->_streamData = part->mutex;
+    _data->header = part->header;
+    _data->version = part->version;
+    _data->partNumber = part->partNumber;
+    _data->memoryMapped = _data->_streamData->is->isMemoryMapped();
+    initialize();
+    _data->tileOffsets.readFrom(part->chunkOffsets,_data->fileIsComplete);
+    _data->_streamData->currentPosition = _data->_streamData->is->tellg();
+}
+
+
+void
+TiledInputFile::initialize ()
+{
+    // fix bad types in header (arises when a tool built against an older version of
+    // OpenEXR converts a scanline image to tiled)
+    // only applies when file is a single part, regular image, tiled file
+    //
+    if(!isMultiPart(_data->version) &&
+       !isNonImage(_data->version) && 
+       isTiled(_data->version) && 
+       _data->header.hasType() )
+    {
+        _data->header.setType(TILEDIMAGE);
+    }
+    
+    if (_data->partNumber == -1)
+    {
+        if (!isTiled (_data->version))
+            throw IEX_NAMESPACE::ArgExc ("Expected a tiled file but the file is not tiled.");
+        
+    }
+    else
+    {
+        if(_data->header.hasType() && _data->header.type()!=TILEDIMAGE)
+        {
+            throw IEX_NAMESPACE::ArgExc ("TiledInputFile used for non-tiledimage part.");
+        }
+    }
+    
     _data->header.sanityCheck (true);
 
     _data->tileDesc = _data->header.tileDescription();
@@ -723,7 +920,7 @@ TiledInputFile::initialize ()
     //
     // Save the dataWindow information
     //
-
+    
     const Box2i &dataWindow = _data->header.dataWindow();
     _data->minX = dataWindow.min.x;
     _data->maxX = dataWindow.max.x;
@@ -735,10 +932,10 @@ TiledInputFile::initialize ()
     //
 
     precalculateTileInfo (_data->tileDesc,
-              _data->minX, _data->maxX,
-              _data->minY, _data->maxY,
-              _data->numXTiles, _data->numYTiles,
-              _data->numXLevels, _data->numYLevels);
+                         _data->minX, _data->maxX,
+                         _data->minY, _data->maxY,
+                         _data->numXTiles, _data->numYTiles,
+                         _data->numXLevels, _data->numYLevels);    
 
     _data->bytesPerPixel = calculateBytesPerPixel (_data->header);
 
@@ -753,33 +950,35 @@ TiledInputFile::initialize ()
     for (size_t i = 0; i < _data->tileBuffers.size(); i++)
     {
         _data->tileBuffers[i] = new TileBuffer (newTileCompressor
-                          (_data->header.compression(),
-                           _data->maxBytesPerTileLine,
-                           _data->tileDesc.ySize,
-                           _data->header));
+                                                 (_data->header.compression(),
+                                                  _data->maxBytesPerTileLine,
+                                                  _data->tileDesc.ySize,
+                                                  _data->header));
 
-        if (!_data->is->isMemoryMapped ())
+        if (!_data->_streamData->is->isMemoryMapped ())
             _data->tileBuffers[i]->buffer = new char [_data->tileBufferSize];
     }
 
     _data->tileOffsets = TileOffsets (_data->tileDesc.mode,
-                      _data->numXLevels,
-                      _data->numYLevels,
-                      _data->numXTiles,
-                      _data->numYTiles);
-
-    _data->tileOffsets.readFrom (*(_data->is), _data->fileIsComplete);
-
-    _data->currentPosition = _data->is->tellg();
+                                     _data->numXLevels,
+                                     _data->numYLevels,
+                                     _data->numXTiles,
+                                     _data->numYTiles);
 }
 
 
 TiledInputFile::~TiledInputFile ()
 {
-    if (!_data->is->isMemoryMapped())
+    if (!_data->memoryMapped)
         for (size_t i = 0; i < _data->tileBuffers.size(); i++)
             delete [] _data->tileBuffers[i]->buffer;
 
+    if (_data->_deleteStream)
+        delete _data->_streamData->is;
+
+    if (_data->partNumber == -1)
+        delete _data->_streamData;
+
     delete _data;
 }
 
@@ -787,7 +986,7 @@ TiledInputFile::~TiledInputFile ()
 const char *
 TiledInputFile::fileName () const
 {
-    return _data->is->fileName();
+    return _data->_streamData->is->fileName();
 }
 
 
@@ -805,10 +1004,10 @@ TiledInputFile::version () const
 }
 
 
-void
+void   
 TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
 
     //
     // Set the frame buffer
@@ -832,11 +1031,11 @@ TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
         if (i.channel().xSampling != j.slice().xSampling ||
             i.channel().ySampling != j.slice().ySampling)
-            THROW (Iex::ArgExc, "X and/or y subsampling factors "
-                "of \"" << i.name() << "\" channel "
-                "of input file \"" << fileName() << "\" are "
-                "not compatible with the frame buffer's "
-                "subsampling factors.");
+            THROW (IEX_NAMESPACE::ArgExc, "X and/or y subsampling factors "
+                               "of \"" << i.name() << "\" channel "
+                               "of input file \"" << fileName() << "\" are "
+                               "not compatible with the frame buffer's "
+                               "subsampling factors.");
     }
 
     //
@@ -859,13 +1058,13 @@ TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
             //
 
             slices.push_back (TInSliceInfo (i.channel().type,
-                        i.channel().type,
-                        0,      // base
-                        0,      // xStride
-                        0,      // yStride
-                        false,  // fill
-                        true,   // skip
-                        0.0));  // fillValue
+                                           i.channel().type,
+                                           0,      // base
+                                           0,      // xStride
+                                           0,      // yStride
+                                           false,  // fill
+                                           true,   // skip
+                                           0.0));  // fillValue
             ++i;
         }
 
@@ -898,21 +1097,21 @@ TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 
     while (i != channels.end())
     {
-    //
-    // Channel i is present in the file but not
-    // in the frame buffer; data for channel i
-    // will be skipped during readPixels().
-    //
-
-    slices.push_back (TInSliceInfo (i.channel().type,
-                    i.channel().type,
-                    0, // base
-                    0, // xStride
-                    0, // yStride
-                    false,  // fill
-                    true, // skip
-                    0.0)); // fillValue
-    ++i;
+       //
+       // Channel i is present in the file but not
+       // in the frame buffer; data for channel i
+       // will be skipped during readPixels().
+       //
+
+       slices.push_back (TInSliceInfo (i.channel().type,
+                                       i.channel().type,
+                                       0, // base
+                                       0, // xStride
+                                       0, // yStride
+                                       false,  // fill
+                                       true, // skip
+                                       0.0)); // fillValue
+       ++i;
     }
 
     //
@@ -927,7 +1126,7 @@ TiledInputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 TiledInputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_data->_streamData);
     return _data->frameBuffer;
 }
 
@@ -948,27 +1147,33 @@ TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
 
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_data->_streamData);
 
         if (_data->slices.size() == 0)
-            throw Iex::ArgExc ("No frame buffer specified "
-                   "as pixel data destination.");
+            throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                              "as pixel data destination.");
+        
+        if (!isValidLevel (lx, ly))
+            THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
 
         //
         // Determine the first and last tile coordinates in both dimensions.
         // We always attempt to read the range of tiles in the order that
         // they are stored in the file.
         //
-
+                               
         if (dx1 > dx2)
             std::swap (dx1, dx2);
-
+        
         if (dy1 > dy2)
             std::swap (dy1, dy2);
-
+        
         int dyStart = dy1;
-    int dyStop  = dy2 + 1;
-    int dY      = 1;
+       int dyStop  = dy2 + 1;
+       int dY      = 1;
 
         if (_data->lineOrder == DECREASING_Y)
         {
@@ -979,24 +1184,25 @@ TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
 
         //
         // Create a task group for all tile buffer tasks.  When the
-    // task group goes out of scope, the destructor waits until
-    // all tasks are complete.
+       // task group goes out of scope, the destructor waits until
+       // all tasks are complete.
         //
-
+        
         {
             TaskGroup taskGroup;
             int tileNumber = 0;
-
+    
             for (int dy = dyStart; dy != dyStop; dy += dY)
             {
                 for (int dx = dx1; dx <= dx2; dx++)
                 {
                     if (!isValidTile (dx, dy, lx, ly))
-                        THROW (Iex::ArgExc,
-                   "Tile (" << dx << ", " << dy << ", " <<
-                   lx << "," << ly << ") is not a valid tile.");
-
+                        THROW (IEX_NAMESPACE::ArgExc,
+                              "Tile (" << dx << ", " << dy << ", " <<
+                              lx << "," << ly << ") is not a valid tile.");
+                    
                     ThreadPool::addGlobalTask (newTileBufferTask (&taskGroup,
+                                                                  _data->_streamData,
                                                                   _data,
                                                                   tileNumber++,
                                                                   dx, dy,
@@ -1004,65 +1210,65 @@ TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
                 }
             }
 
-        //
+           //
             // finish all tasks
-        //
+           //
         }
 
-    //
-    // Exeption handling:
-    //
-    // TileBufferTask::execute() may have encountered exceptions, but
-    // those exceptions occurred in another thread, not in the thread
-    // that is executing this call to TiledInputFile::readTiles().
-    // TileBufferTask::execute() has caught all exceptions and stored
-    // the exceptions' what() strings in the tile buffers.
-    // Now we check if any tile buffer contains a stored exception; if
-    // this is the case then we re-throw the exception in this thread.
-    // (It is possible that multiple tile buffers contain stored
-    // exceptions.  We re-throw the first exception we find and
-    // ignore all others.)
-    //
-
-    const string *exception = 0;
-
-        for (int i = 0; i < _data->tileBuffers.size(); ++i)
-    {
+       //
+       // Exeption handling:
+       //
+       // TileBufferTask::execute() may have encountered exceptions, but
+       // those exceptions occurred in another thread, not in the thread
+       // that is executing this call to TiledInputFile::readTiles().
+       // TileBufferTask::execute() has caught all exceptions and stored
+       // the exceptions' what() strings in the tile buffers.
+       // Now we check if any tile buffer contains a stored exception; if
+       // this is the case then we re-throw the exception in this thread.
+       // (It is possible that multiple tile buffers contain stored
+       // exceptions.  We re-throw the first exception we find and
+       // ignore all others.)
+       //
+
+       const string *exception = 0;
+
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
+       {
             TileBuffer *tileBuffer = _data->tileBuffers[i];
 
-        if (tileBuffer->hasException && !exception)
-        exception = &tileBuffer->exception;
+           if (tileBuffer->hasException && !exception)
+               exception = &tileBuffer->exception;
 
-        tileBuffer->hasException = false;
-    }
+           tileBuffer->hasException = false;
+       }
 
-    if (exception)
-        throw Iex::IoExc (*exception);
+       if (exception)
+           throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
         REPLACE_EXC (e, "Error reading pixel data from image "
-                        "file \"" << fileName() << "\". " << e);
+                     "file \"" << fileName() << "\". " << e.what());
         throw;
     }
 }
 
 
-void
+void   
 TiledInputFile::readTiles (int dx1, int dx2, int dy1, int dy2, int l)
 {
     readTiles (dx1, dx2, dy1, dy2, l, l);
 }
 
 
-void
+void   
 TiledInputFile::readTile (int dx, int dy, int lx, int ly)
 {
     readTiles (dx, dx, dy, dy, lx, ly);
 }
 
 
-void
+void   
 TiledInputFile::readTile (int dx, int dy, int l)
 {
     readTile (dx, dy, l, l);
@@ -1071,30 +1277,48 @@ TiledInputFile::readTile (int dx, int dy, int l)
 
 void
 TiledInputFile::rawTileData (int &dx, int &dy,
-                 int &lx, int &ly,
+                            int &lx, int &ly,
                              const char *&pixelData,
-                 int &pixelDataSize)
+                            int &pixelDataSize)
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_data->_streamData);
 
         if (!isValidTile (dx, dy, lx, ly))
-            throw Iex::ArgExc ("Tried to read a tile outside "
-                   "the image file's data window.");
+            throw IEX_NAMESPACE::ArgExc ("Tried to read a tile outside "
+                              "the image file's data window.");
 
         TileBuffer *tileBuffer = _data->getTileBuffer (0);
 
-        readNextTileData (_data, dx, dy, lx, ly,
-              tileBuffer->buffer,
+        //
+        // if file is a multipart file, we have to seek to the required tile
+        // since we don't know where the file pointer is
+        //
+        int old_dx=dx;
+        int old_dy=dy;
+        int old_lx=lx;
+        int old_ly=ly;
+        if(isMultiPart(version()))
+        {
+            _data->_streamData->is->seekg(_data->tileOffsets(dx,dy,lx,ly));
+        }
+        readNextTileData (_data->_streamData, _data, dx, dy, lx, ly,
+                         tileBuffer->buffer,
                           pixelDataSize);
-
+        if(isMultiPart(version()))
+        {
+            if (old_dx!=dx || old_dy !=dy || old_lx!=lx || old_ly!=ly)
+            {
+                throw IEX_NAMESPACE::ArgExc ("rawTileData read the wrong tile");
+            }
+        }
         pixelData = tileBuffer->buffer;
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
         REPLACE_EXC (e, "Error reading pixel data from image "
-            "file \"" << fileName() << "\". " << e);
+                     "file \"" << fileName() << "\". " << e.what());
         throw;
     }
 }
@@ -1132,10 +1356,10 @@ int
 TiledInputFile::numLevels () const
 {
     if (levelMode() == RIPMAP_LEVELS)
-    THROW (Iex::LogicExc, "Error calling numLevels() on image "
-                  "file \"" << fileName() << "\" "
-                  "(numLevels() is not defined for files "
-                  "with RIPMAP level mode).");
+       THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
+                             "file \"" << fileName() << "\" "
+                             "(numLevels() is not defined for files "
+                             "with RIPMAP level mode).");
 
     return _data->numXLevels;
 }
@@ -1155,17 +1379,17 @@ TiledInputFile::numYLevels () const
 }
 
 
-bool
+bool   
 TiledInputFile::isValidLevel (int lx, int ly) const
 {
     if (lx < 0 || ly < 0)
-    return false;
+       return false;
 
     if (levelMode() == MIPMAP_LEVELS && lx != ly)
-    return false;
+       return false;
 
     if (lx >= numXLevels() || ly >= numYLevels())
-    return false;
+       return false;
 
     return true;
 }
@@ -1177,13 +1401,13 @@ TiledInputFile::levelWidth (int lx) const
     try
     {
         return levelSize (_data->minX, _data->maxX, lx,
-              _data->tileDesc.roundingMode);
+                         _data->tileDesc.roundingMode);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling levelWidth() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling levelWidth() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1196,11 +1420,11 @@ TiledInputFile::levelHeight (int ly) const
         return levelSize (_data->minY, _data->maxY, ly,
                           _data->tileDesc.roundingMode);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling levelHeight() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling levelHeight() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1210,12 +1434,12 @@ TiledInputFile::numXTiles (int lx) const
 {
     if (lx < 0 || lx >= _data->numXLevels)
     {
-        THROW (Iex::ArgExc, "Error calling numXTiles() on image "
-                "file \"" << _data->is->fileName() << "\" "
-                "(Argument is not in valid range).");
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numXTiles() on image "
+                           "file \"" << _data->_streamData->is->fileName() << "\" "
+                           "(Argument is not in valid range).");
 
     }
-
+    
     return _data->numXTiles[lx];
 }
 
@@ -1225,11 +1449,11 @@ TiledInputFile::numYTiles (int ly) const
 {
     if (ly < 0 || ly >= _data->numYLevels)
     {
-        THROW (Iex::ArgExc, "Error calling numYTiles() on image "
-                "file \"" << _data->is->fileName() << "\" "
-                "(Argument is not in valid range).");
+        THROW (IEX_NAMESPACE::ArgExc, "Error calling numYTiles() on image "
+                           "file \"" << _data->_streamData->is->fileName() << "\" "
+                           "(Argument is not in valid range).");
     }
-
+    
     return _data->numYTiles[ly];
 }
 
@@ -1246,16 +1470,17 @@ TiledInputFile::dataWindowForLevel (int lx, int ly) const
 {
     try
     {
-    return Imf::dataWindowForLevel (_data->tileDesc,
-                        _data->minX, _data->maxX,
-                        _data->minY, _data->maxY,
-                        lx, ly);
+       return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+               _data->tileDesc,
+               _data->minX, _data->maxX,
+               _data->minY, _data->maxY,
+               lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1272,19 +1497,20 @@ TiledInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 {
     try
     {
-    if (!isValidTile (dx, dy, lx, ly))
-        throw Iex::ArgExc ("Arguments not in valid range.");
-
-        return Imf::dataWindowForTile (_data->tileDesc,
-                       _data->minX, _data->maxX,
-                       _data->minY, _data->maxY,
-                       dx, dy, lx, ly);
+       if (!isValidTile (dx, dy, lx, ly))
+           throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
+
+        return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+                _data->tileDesc,
+                _data->minX, _data->maxX,
+                _data->minY, _data->maxY,
+                dx, dy, lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1298,5 +1524,10 @@ TiledInputFile::isValidTile (int dx, int dy, int lx, int ly) const
             (dy < _data->numYTiles[ly] && dy >= 0));
 }
 
+void TiledInputFile::tileOrder(int dx[], int dy[], int lx[], int ly[]) const
+{
+   return _data->tileOffsets.getTileOrder(dx,dy,lx,ly);
+}
+
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index eac9968..5ea872d 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
 #include "ImathBox.h"
-#include <ImfTileDescription.h>
-#include <ImfThreading.h>
+#include "ImfTileDescription.h"
+#include "ImfThreading.h"
+#include "ImfGenericInputFile.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class TiledInputFile
+class TiledInputFile : public GenericInputFile
 {
   public:
 
     //--------------------------------------------------------------------
     // A constructor that opens the file with the specified name, and
-    // reads the file header.  The constructor throws an Iex::ArgExc
+    // reads the file header.  The constructor throws an IEX_NAMESPACE::ArgExc
     // exception if the file is not tiled.
     // The numThreads parameter specifies how many worker threads this
     // file will try to keep busy when decompressing individual tiles.
@@ -65,25 +69,28 @@ class TiledInputFile
     // automatically closes the corresponding files.
     //--------------------------------------------------------------------
 
+    IMF_EXPORT
     TiledInputFile (const char fileName[],
                     int numThreads = globalThreadCount ());
 
-
+    
     // ----------------------------------------------------------
     // A constructor that attaches the new TiledInputFile object
-    // to a file that has already been opened.
+    // to a file that has already been opened.  
     // Destroying TiledInputFile objects constructed with this
     // constructor does not automatically close the corresponding
     // files.
     // ----------------------------------------------------------
 
-    TiledInputFile (IStream &is, int numThreads = globalThreadCount ());
+    IMF_EXPORT
+    TiledInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount ());
 
 
     //-----------
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~TiledInputFile ();
 
 
@@ -91,6 +98,7 @@ class TiledInputFile
     // Access to the file name
     //------------------------
 
+    IMF_EXPORT
     const char *       fileName () const;
 
 
@@ -98,6 +106,7 @@ class TiledInputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &     header () const;
 
 
@@ -105,6 +114,7 @@ class TiledInputFile
     // Access to the file format version
     //----------------------------------
 
+    IMF_EXPORT
     int                        version () const;
 
 
@@ -119,6 +129,7 @@ class TiledInputFile
     // to readTile().
     //-----------------------------------------------------------
 
+    IMF_EXPORT
     void               setFrameBuffer (const FrameBuffer &frameBuffer);
 
 
@@ -126,6 +137,7 @@ class TiledInputFile
     // Access to the current frame buffer
     //-----------------------------------
 
+    IMF_EXPORT
     const FrameBuffer &        frameBuffer () const;
 
 
@@ -139,6 +151,7 @@ class TiledInputFile
     // prematurely.)
     //------------------------------------------------------------
 
+    IMF_EXPORT
     bool               isComplete () const;
 
 
@@ -152,9 +165,13 @@ class TiledInputFile
     // fields of the file header's TileDescriptionAttribute.
     //---------------------------------------------------------
 
+    IMF_EXPORT
     unsigned int       tileXSize () const;
+    IMF_EXPORT
     unsigned int       tileYSize () const;
+    IMF_EXPORT
     LevelMode          levelMode () const;
+    IMF_EXPORT
     LevelRoundingMode  levelRoundingMode () const;
 
 
@@ -194,16 +211,20 @@ class TiledInputFile
     //      return value is the same as for numXLevels()
     //
     // if levelMode() == RIPMAP_LEVELS:
-    //      an Iex::LogicExc exception is thrown
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
     //
-    // isValidLevel(lx, ly) returns true if the file contains
+    // isValidLevel(lx, ly) returns true if the file contains 
     // a level with level number (lx, ly), false if not.
     //
     //--------------------------------------------------------------------
 
+    IMF_EXPORT
     int                        numLevels () const;
+    IMF_EXPORT
     int                        numXLevels () const;
+    IMF_EXPORT
     int                        numYLevels () const;
+    IMF_EXPORT
     bool               isValidLevel (int lx, int ly) const;
 
 
@@ -225,7 +246,9 @@ class TiledInputFile
     //
     //----------------------------------------------------------
 
+    IMF_EXPORT
     int                        levelWidth  (int lx) const;
+    IMF_EXPORT
     int                        levelHeight (int ly) const;
 
 
@@ -249,7 +272,9 @@ class TiledInputFile
     //
     //--------------------------------------------------------------
 
+    IMF_EXPORT
     int                        numXTiles (int lx = 0) const;
+    IMF_EXPORT
     int                        numYTiles (int ly = 0) const;
 
 
@@ -272,8 +297,10 @@ class TiledInputFile
     //
     //---------------------------------------------------------------
 
-    Imath::Box2i       dataWindowForLevel (int l = 0) const;
-    Imath::Box2i       dataWindowForLevel (int lx, int ly) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int lx, int ly) const;
 
 
     //-------------------------------------------------------------------
@@ -297,9 +324,11 @@ class TiledInputFile
     //
     //-------------------------------------------------------------------
 
-    Imath::Box2i       dataWindowForTile (int dx, int dy, int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy, int l = 0) const;
 
-    Imath::Box2i       dataWindowForTile (int dx, int dy,
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy,
                                            int lx, int ly) const;
 
     //------------------------------------------------------------
@@ -331,12 +360,16 @@ class TiledInputFile
     //
     //------------------------------------------------------------
 
+    IMF_EXPORT
     void               readTile  (int dx, int dy, int l = 0);
+    IMF_EXPORT
     void               readTile  (int dx, int dy, int lx, int ly);
 
+    IMF_EXPORT
     void               readTiles (int dx1, int dx2, int dy1, int dy2,
                                    int lx, int ly);
 
+    IMF_EXPORT
     void               readTiles (int dx1, int dx2, int dy1, int dy2,
                                    int l = 0);
 
@@ -345,37 +378,54 @@ class TiledInputFile
     // Read a tile of raw pixel data from the file,
     // without uncompressing it (this function is
     // used to implement TiledOutputFile::copyPixels()).
+    //
+    // for single part files, reads the next tile in the file
+    // for multipart files, reads the tile specified by dx,dy,lx,ly
+    //
     //--------------------------------------------------
 
+    IMF_EXPORT
     void               rawTileData (int &dx, int &dy,
-                     int &lx, int &ly,
-                     const char *&pixelData,
-                     int &pixelDataSize);
+                                    int &lx, int &ly,
+                                    const char *&pixelData,
+                                    int &pixelDataSize);
 
     struct Data;
 
   private:
 
     friend class InputFile;
+    friend class MultiPartInputFile;
+
+    TiledInputFile (InputPartData* part);
 
     TiledInputFile (const TiledInputFile &);             // not implemented
     TiledInputFile & operator = (const TiledInputFile &); // not implemented
 
-    TiledInputFile (const Header &header, IStream *is, int version,
+    TiledInputFile (const Header &header, OPENEXR_IMF_INTERNAL_NAMESPACE::IStream *is, int version,
                     int numThreads);
 
     void               initialize ();
+    void                multiPartInitialize(InputPartData* part);
+    void                compatibilityInitialize(OPENEXR_IMF_INTERNAL_NAMESPACE::IStream& is);
 
     bool               isValidTile (int dx, int dy,
-                     int lx, int ly) const;
+                                    int lx, int ly) const;
 
     size_t             bytesPerLineForTile (int dx, int dy,
-                         int lx, int ly) const;
+                                            int lx, int ly) const;
 
+    void                tileOrder(int dx[],int dy[],int lx[],int ly[]) const;
     Data *             _data;
+
+    friend void TiledOutputFile::copyPixels(TiledInputFile &);
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfTiledInputPart.cpp b/3rdparty/openexr/IlmImf/ImfTiledInputPart.cpp
new file mode 100644 (file)
index 0000000..3f89d95
--- /dev/null
@@ -0,0 +1,208 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfTiledInputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+TiledInputPart::TiledInputPart(MultiPartInputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getInputPart<TiledInputFile>(partNumber);
+}
+
+const char *
+TiledInputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+TiledInputPart::header () const
+{
+    return file->header();
+}
+
+int
+TiledInputPart::version () const
+{
+    return file->version();
+}
+
+void
+TiledInputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+TiledInputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+bool
+TiledInputPart::isComplete () const
+{
+    return file->isComplete();
+}
+
+unsigned int
+TiledInputPart::tileXSize () const
+{
+    return file->tileXSize();
+}
+
+unsigned int
+TiledInputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+LevelMode
+TiledInputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+LevelRoundingMode
+TiledInputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+int
+TiledInputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+int
+TiledInputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+int
+TiledInputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+bool
+TiledInputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+int
+TiledInputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+int
+TiledInputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+int
+TiledInputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+int
+TiledInputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForTile (int dx, int dy, int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledInputPart::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+void
+TiledInputPart::readTile  (int dx, int dy, int l)
+{
+    file->readTile(dx, dy, l);
+}
+
+void
+TiledInputPart::readTile  (int dx, int dy, int lx, int ly)
+{
+    file->readTile(dx, dy, lx, ly);
+}
+
+void
+TiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+void
+TiledInputPart::readTiles (int dx1, int dx2, int dy1, int dy2, int l)
+{
+    file->readTiles(dx1, dx2, dy1, dy2, l);
+}
+
+void
+TiledInputPart::rawTileData (int &dx, int &dy, int &lx, int &ly,
+             const char *&pixelData, int &pixelDataSize)
+{
+    file->rawTileData(dx, dy, lx, ly, pixelData, pixelDataSize);
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfTiledInputPart.h b/3rdparty/openexr/IlmImf/ImfTiledInputPart.h
new file mode 100644 (file)
index 0000000..4132ab8
--- /dev/null
@@ -0,0 +1,128 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFTILEDINPUTPART_H_
+#define IMFTILEDINPUTPART_H_
+
+#include "ImfMultiPartInputFile.h"
+#include "ImfTiledInputFile.h"
+#include "ImfNamespace.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//-----------------------------------------------------------------------------
+// class TiledInputPart:
+//
+// Same interface as TiledInputFile. Please have a reference to TiledInputFile.
+//-----------------------------------------------------------------------------
+
+class TiledInputPart
+{
+    public:
+        IMF_EXPORT
+        TiledInputPart(MultiPartInputFile& multiPartFile, int partNumber);
+
+        IMF_EXPORT
+        const char *        fileName () const;
+        IMF_EXPORT
+        const Header &      header () const;
+        IMF_EXPORT
+        int                 version () const;
+        IMF_EXPORT
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        IMF_EXPORT
+        const FrameBuffer & frameBuffer () const;
+        IMF_EXPORT
+        bool                isComplete () const;
+        IMF_EXPORT
+        unsigned int        tileXSize () const;
+        IMF_EXPORT
+        unsigned int        tileYSize () const;
+        IMF_EXPORT
+        LevelMode           levelMode () const;
+        IMF_EXPORT
+        LevelRoundingMode   levelRoundingMode () const;
+        IMF_EXPORT
+        int                 numLevels () const;
+        IMF_EXPORT
+        int                 numXLevels () const;
+        IMF_EXPORT
+        int                 numYLevels () const;
+        IMF_EXPORT
+        bool                isValidLevel (int lx, int ly) const;
+        IMF_EXPORT
+        int                 levelWidth  (int lx) const;
+        IMF_EXPORT
+        int                 levelHeight (int ly) const;
+        IMF_EXPORT
+        int                 numXTiles (int lx = 0) const;
+        IMF_EXPORT
+        int                 numYTiles (int ly = 0) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy, int l = 0) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                               int lx, int ly) const;
+        IMF_EXPORT
+        void                readTile  (int dx, int dy, int l = 0);
+        IMF_EXPORT
+        void                readTile  (int dx, int dy, int lx, int ly);
+        IMF_EXPORT
+        void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                       int lx, int ly);
+        IMF_EXPORT
+        void                readTiles (int dx1, int dx2, int dy1, int dy2,
+                                       int l = 0);
+        IMF_EXPORT
+        void                rawTileData (int &dx, int &dy,
+                                         int &lx, int &ly,
+                                         const char *&pixelData,
+                                         int &pixelDataSize);
+
+    private:
+        TiledInputFile* file;
+      // for internal use - allow TiledOutputFile access to file for copyPixels
+      friend class TiledOutputFile;
+      
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFTILEDINPUTPART_H_ */
index 9588e78..d72d823 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include "Iex.h"
 #include <ImfMisc.h>
 #include <ImfChannelList.h>
-#include <algorithm> // for std::max()
+#include <ImfTileDescription.h>
+#include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using Imath::Box2i;
-using Imath::V2i;
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 
 
 int
 levelSize (int min, int max, int l, LevelRoundingMode rmode)
 {
     if (l < 0)
-    throw Iex::ArgExc ("Argument not in valid range.");
+       throw IEX_NAMESPACE::ArgExc ("Argument not in valid range.");
 
     int a = max - min + 1;
     int b = (1 << l);
     int size = a / b;
 
     if (rmode == ROUND_UP && size * b < a)
-    size += 1;
+       size += 1;
 
     return std::max (size, 1);
 }
@@ -71,15 +73,15 @@ levelSize (int min, int max, int l, LevelRoundingMode rmode)
 
 Box2i
 dataWindowForLevel (const TileDescription &tileDesc,
-            int minX, int maxX,
-            int minY, int maxY,
-            int lx, int ly)
+                   int minX, int maxX,
+                   int minY, int maxY,
+                   int lx, int ly)
 {
     V2i levelMin = V2i (minX, minY);
 
     V2i levelMax = levelMin +
-           V2i (levelSize (minX, maxX, lx, tileDesc.roundingMode) - 1,
-            levelSize (minY, maxY, ly, tileDesc.roundingMode) - 1);
+                  V2i (levelSize (minX, maxX, lx, tileDesc.roundingMode) - 1,
+                       levelSize (minY, maxY, ly, tileDesc.roundingMode) - 1);
 
     return Box2i(levelMin, levelMax);
 }
@@ -87,21 +89,21 @@ dataWindowForLevel (const TileDescription &tileDesc,
 
 Box2i
 dataWindowForTile (const TileDescription &tileDesc,
-           int minX, int maxX,
-           int minY, int maxY,
-           int dx, int dy,
-           int lx, int ly)
+                  int minX, int maxX,
+                  int minY, int maxY,
+                  int dx, int dy,
+                  int lx, int ly)
 {
     V2i tileMin = V2i (minX + dx * tileDesc.xSize,
-               minY + dy * tileDesc.ySize);
+                      minY + dy * tileDesc.ySize);
 
     V2i tileMax = tileMin + V2i (tileDesc.xSize - 1, tileDesc.ySize - 1);
 
     V2i levelMax = dataWindowForLevel
-               (tileDesc, minX, maxX, minY, maxY, lx, ly).max;
+                      (tileDesc, minX, maxX, minY, maxY, lx, ly).max;
 
     tileMax = V2i (std::min (tileMax[0], levelMax[0]),
-           std::min (tileMax[1], levelMax[1]));
+                  std::min (tileMax[1], levelMax[1]));
 
     return Box2i (tileMin, tileMax);
 }
@@ -115,16 +117,50 @@ calculateBytesPerPixel (const Header &header)
     size_t bytesPerPixel = 0;
 
     for (ChannelList::ConstIterator c = channels.begin();
-     c != channels.end();
-     ++c)
+        c != channels.end();
+        ++c)
     {
-    bytesPerPixel += pixelTypeSize (c.channel().type);
+       bytesPerPixel += pixelTypeSize (c.channel().type);
     }
 
     return bytesPerPixel;
 }
 
 
+void
+calculateBytesPerLine (const Header &header,
+                       char* sampleCountBase,
+                       int sampleCountXStride,
+                       int sampleCountYStride,
+                       int minX, int maxX,
+                       int minY, int maxY,
+                       std::vector<int>& xOffsets,
+                       std::vector<int>& yOffsets,
+                       std::vector<Int64>& bytesPerLine)
+{
+    const ChannelList &channels = header.channels();
+
+    int pos = 0;
+    for (ChannelList::ConstIterator c = channels.begin();
+         c != channels.end();
+         ++c, ++pos)
+    {
+        int xOffset = xOffsets[pos];
+        int yOffset = yOffsets[pos];
+        int i = 0;
+        for (int y = minY - yOffset; y <= maxY - yOffset; y++, i++)
+            for (int x = minX - xOffset; x <= maxX - xOffset; x++)
+            {
+                bytesPerLine[i] += sampleCount(sampleCountBase,
+                                               sampleCountXStride,
+                                               sampleCountYStride,
+                                               x, y)
+                                   * pixelTypeSize (c.channel().type);
+            }
+    }
+}
+
+
 namespace {
 
 int
@@ -138,8 +174,8 @@ floorLog2 (int x)
 
     while (x > 1)
     {
-    y +=  1;
-    x >>= 1;
+       y +=  1;
+       x >>= 1;
     }
 
     return y;
@@ -158,11 +194,11 @@ ceilLog2 (int x)
 
     while (x > 1)
     {
-    if (x & 1)
-        r = 1;
+       if (x & 1)
+           r = 1;
 
-    y +=  1;
-    x >>= 1;
+       y +=  1;
+       x >>= 1;
     }
 
     return y + r;
@@ -178,8 +214,8 @@ roundLog2 (int x, LevelRoundingMode rmode)
 
 int
 calculateNumXLevels (const TileDescription& tileDesc,
-             int minX, int maxX,
-             int minY, int maxY)
+                    int minX, int maxX,
+                    int minY, int maxY)
 {
     int num = 0;
 
@@ -187,29 +223,29 @@ calculateNumXLevels (const TileDescription& tileDesc,
     {
       case ONE_LEVEL:
 
-    num = 1;
-    break;
+       num = 1;
+       break;
 
       case MIPMAP_LEVELS:
 
-    {
-      int w = maxX - minX + 1;
-      int h = maxY - minY + 1;
-      num = roundLog2 (std::max (w, h), tileDesc.roundingMode) + 1;
-    }
+       {
+         int w = maxX - minX + 1;
+         int h = maxY - minY + 1;
+         num = roundLog2 (std::max (w, h), tileDesc.roundingMode) + 1;
+       }
         break;
 
       case RIPMAP_LEVELS:
 
-    {
-      int w = maxX - minX + 1;
-      num = roundLog2 (w, tileDesc.roundingMode) + 1;
-    }
-    break;
+       {
+         int w = maxX - minX + 1;
+         num = roundLog2 (w, tileDesc.roundingMode) + 1;
+       }
+       break;
 
       default:
 
-    throw Iex::ArgExc ("Unknown LevelMode format.");
+       throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 
     return num;
@@ -218,8 +254,8 @@ calculateNumXLevels (const TileDescription& tileDesc,
 
 int
 calculateNumYLevels (const TileDescription& tileDesc,
-             int minX, int maxX,
-             int minY, int maxY)
+                    int minX, int maxX,
+                    int minY, int maxY)
 {
     int num = 0;
 
@@ -227,29 +263,29 @@ calculateNumYLevels (const TileDescription& tileDesc,
     {
       case ONE_LEVEL:
 
-    num = 1;
-    break;
+       num = 1;
+       break;
 
       case MIPMAP_LEVELS:
 
-    {
-      int w = maxX - minX + 1;
-      int h = maxY - minY + 1;
-      num = roundLog2 (std::max (w, h), tileDesc.roundingMode) + 1;
-    }
+       {
+         int w = maxX - minX + 1;
+         int h = maxY - minY + 1;
+         num = roundLog2 (std::max (w, h), tileDesc.roundingMode) + 1;
+       }
         break;
 
       case RIPMAP_LEVELS:
 
-    {
-      int h = maxY - minY + 1;
-      num = roundLog2 (h, tileDesc.roundingMode) + 1;
-    }
-    break;
+       {
+         int h = maxY - minY + 1;
+         num = roundLog2 (h, tileDesc.roundingMode) + 1;
+       }
+       break;
 
       default:
 
-    throw Iex::ArgExc ("Unknown LevelMode format.");
+       throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
     }
 
     return num;
@@ -258,14 +294,14 @@ calculateNumYLevels (const TileDescription& tileDesc,
 
 void
 calculateNumTiles (int *numTiles,
-           int numLevels,
-           int min, int max,
-           int size,
-           LevelRoundingMode rmode)
+                  int numLevels,
+                  int min, int max,
+                  int size,
+                  LevelRoundingMode rmode)
 {
     for (int i = 0; i < numLevels; i++)
     {
-    numTiles[i] = (levelSize (min, max, i, rmode) + size - 1) / size;
+       numTiles[i] = (levelSize (min, max, i, rmode) + size - 1) / size;
     }
 }
 
@@ -274,29 +310,80 @@ calculateNumTiles (int *numTiles,
 
 void
 precalculateTileInfo (const TileDescription& tileDesc,
-              int minX, int maxX,
-              int minY, int maxY,
-              int *&numXTiles, int *&numYTiles,
-              int &numXLevels, int &numYLevels)
+                     int minX, int maxX,
+                     int minY, int maxY,
+                     int *&numXTiles, int *&numYTiles,
+                     int &numXLevels, int &numYLevels)
 {
     numXLevels = calculateNumXLevels(tileDesc, minX, maxX, minY, maxY);
     numYLevels = calculateNumYLevels(tileDesc, minX, maxX, minY, maxY);
-
+    
     numXTiles = new int[numXLevels];
     numYTiles = new int[numYLevels];
 
     calculateNumTiles (numXTiles,
-               numXLevels,
-               minX, maxX,
-               tileDesc.xSize,
-               tileDesc.roundingMode);
+                      numXLevels,
+                      minX, maxX,
+                      tileDesc.xSize,
+                      tileDesc.roundingMode);
 
     calculateNumTiles (numYTiles,
-               numYLevels,
-               minY, maxY,
-               tileDesc.ySize,
-               tileDesc.roundingMode);
+                      numYLevels,
+                      minY, maxY,
+                      tileDesc.ySize,
+                      tileDesc.roundingMode);
+}
+
+
+int
+getTiledChunkOffsetTableSize(const Header& header)
+{
+    //
+    // Save the dataWindow information
+    //
+
+    const Box2i &dataWindow = header.dataWindow();
+    
+    //
+    // Precompute level and tile information.
+    //
+
+    int* numXTiles;
+    int* numYTiles;
+    int numXLevels;
+    int numYLevels;
+    precalculateTileInfo (header.tileDescription(),
+                          dataWindow.min.x, dataWindow.max.x,
+                          dataWindow.min.y, dataWindow.max.y,
+                          numXTiles, numYTiles,
+                          numXLevels, numYLevels);
+
+    //
+    // Calculate lineOffsetSize.
+    //
+    int lineOffsetSize = 0;
+    const TileDescription &desc = header.tileDescription();
+    switch (desc.mode)
+    {
+        case ONE_LEVEL:
+        case MIPMAP_LEVELS:
+            for (int i = 0; i < numXLevels; i++)
+                lineOffsetSize += numXTiles[i] * numYTiles[i];
+            break;
+        case RIPMAP_LEVELS:
+            for (int i = 0; i < numXLevels; i++)
+                for (int j = 0; j < numYLevels; j++)
+                    lineOffsetSize += numXTiles[i] * numYTiles[j];
+            break;
+        case NUM_LEVELMODES :
+            throw IEX_NAMESPACE::LogicExc("Bad level mode getting chunk offset table size");
+    }
+
+    delete[] numXTiles;
+    delete[] numYTiles;
+
+    return lineOffsetSize;
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 7a83f1e..2696663 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include "ImathBox.h"
-#include <ImfHeader.h>
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+
 #include <stdio.h>
+#include <vector>
+
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
+IMF_EXPORT 
 int levelSize (int min, int max, int l, LevelRoundingMode rmode);
 
-Imath::Box2i dataWindowForLevel (const TileDescription &tileDesc,
-                 int minX, int maxX,
-                 int minY, int maxY,
-                 int lx, int ly);
+IMF_EXPORT 
+IMATH_NAMESPACE::Box2i dataWindowForLevel (const TileDescription &tileDesc,
+                                int minX, int maxX,
+                                int minY, int maxY,
+                                int lx, int ly);
 
-Imath::Box2i dataWindowForTile (const TileDescription &tileDesc,
-                int minX, int maxX,
-                int minY, int maxY,
-                int dx, int dy,
-                int lx, int ly);
+IMF_EXPORT 
+IMATH_NAMESPACE::Box2i dataWindowForTile (const TileDescription &tileDesc,
+                               int minX, int maxX,
+                               int minY, int maxY,
+                               int dx, int dy,
+                               int lx, int ly);
 
+IMF_EXPORT 
 size_t calculateBytesPerPixel (const Header &header);
 
+//
+// Calculate the count of bytes for each lines in range [minY, maxY],
+// and pixels in range [minX, maxX].
+// Data will be saved in bytesPerLine.
+// sampleCountBase, sampleCountXStride and sampleCountYStride are
+// used to get the sample count values.
+//
+
+IMF_EXPORT 
+void calculateBytesPerLine (const Header &header,
+                            char* sampleCountBase,
+                            int sampleCountXStride,
+                            int sampleCountYStride,
+                            int minX, int maxX,
+                            int minY, int maxY,
+                            std::vector<int>& xOffsets,
+                            std::vector<int>& yOffsets,
+                            std::vector<Int64>& bytesPerLine);
+
+IMF_EXPORT 
 void precalculateTileInfo (const TileDescription& tileDesc,
-               int minX, int maxX,
-               int minY, int maxY,
-               int *&numXTiles, int *&numYTiles,
-               int &numXLevels, int &numYLevels);
+                          int minX, int maxX,
+                          int minY, int maxY,
+                          int *&numXTiles, int *&numYTiles,
+                          int &numXLevels, int &numYLevels);
+
+IMF_EXPORT 
+int getTiledChunkOffsetTableSize(const Header& header);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
index 0bc3cb3..b9572d0 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -40,7 +40,9 @@
 
 #include <ImfTiledOutputFile.h>
 #include <ImfTiledInputFile.h>
+#include <ImfTiledInputPart.h>
 #include <ImfInputFile.h>
+#include <ImfInputPart.h>
 #include <ImfTileDescriptionAttribute.h>
 #include <ImfPreviewImageAttribute.h>
 #include <ImfChannelList.h>
 #include <ImfVersion.h>
 #include <ImfTileOffsets.h>
 #include <ImfThreading.h>
+#include <ImfPartType.h>
 #include "IlmThreadPool.h"
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadMutex.h"
+#include "ImfOutputStreamMutex.h"
+#include "ImfOutputPartData.h"
 #include "Iex.h"
 #include <string>
 #include <vector>
 #include <fstream>
 #include <assert.h>
 #include <map>
-#include <algorithm> // for std::max()
+#include <algorithm>
 
+#include "ImfNamespace.h"
 
-namespace Imf {
 
-using Imath::Box2i;
-using Imath::V2i;
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+using IMATH_NAMESPACE::Box2i;
+using IMATH_NAMESPACE::V2i;
 using std::string;
 using std::vector;
 using std::ofstream;
@@ -77,12 +84,12 @@ using std::map;
 using std::min;
 using std::max;
 using std::swap;
-using IlmThread::Mutex;
-using IlmThread::Lock;
-using IlmThread::Semaphore;
-using IlmThread::Task;
-using IlmThread::TaskGroup;
-using IlmThread::ThreadPool;
+using ILMTHREAD_NAMESPACE::Mutex;
+using ILMTHREAD_NAMESPACE::Lock;
+using ILMTHREAD_NAMESPACE::Semaphore;
+using ILMTHREAD_NAMESPACE::Task;
+using ILMTHREAD_NAMESPACE::TaskGroup;
+using ILMTHREAD_NAMESPACE::ThreadPool;
 
 namespace {
 
@@ -97,19 +104,19 @@ struct TOutSliceInfo
     int                 yTileCoords;
 
     TOutSliceInfo (PixelType type = HALF,
-               const char *base = 0,
-               size_t xStride = 0,
-               size_t yStride = 0,
-               bool zero = false,
+                  const char *base = 0,
+                  size_t xStride = 0,
+                  size_t yStride = 0,
+                  bool zero = false,
                    int xTileCoords = 0,
                    int yTileCoords = 0);
 };
 
 
 TOutSliceInfo::TOutSliceInfo (PixelType t,
-                      const char *b,
-                  size_t xs, size_t ys,
-                  bool z,
+                             const char *b,
+                             size_t xs, size_t ys,
+                             bool z,
                               int xtc,
                               int ytc)
 :
@@ -131,25 +138,25 @@ struct TileCoord
     int                dy;
     int                lx;
     int                ly;
-
+    
 
     TileCoord (int xTile = 0, int yTile = 0,
-           int xLevel = 0, int yLevel = 0)
+              int xLevel = 0, int yLevel = 0)
     :
         dx (xTile),  dy (yTile),
-    lx (xLevel), ly (yLevel)
+       lx (xLevel), ly (yLevel)
     {
         // empty
     }
-
+    
 
     bool
     operator < (const TileCoord &other) const
     {
         return (ly < other.ly) ||
-           (ly == other.ly && lx < other.lx) ||
-           ((ly == other.ly && lx == other.lx) &&
-            ((dy < other.dy) || (dy == other.dy && dx < other.dx)));
+              (ly == other.ly && lx < other.lx) ||
+              ((ly == other.ly && lx == other.lx) &&
+                   ((dy < other.dy) || (dy == other.dy && dx < other.dx)));
     }
 
 
@@ -157,9 +164,9 @@ struct TileCoord
     operator == (const TileCoord &other) const
     {
         return lx == other.lx &&
-           ly == other.ly &&
-           dx == other.dx &&
-           dy == other.dy;
+              ly == other.ly &&
+              dx == other.dx &&
+              dy == other.dy;
     }
 };
 
@@ -170,16 +177,16 @@ struct BufferedTile
     int                pixelDataSize;
 
     BufferedTile (const char *data, int size):
-    pixelData (0),
-    pixelDataSize(size)
+       pixelData (0),
+       pixelDataSize(size)
     {
-    pixelData = new char[pixelDataSize];
-    memcpy (pixelData, data, pixelDataSize);
+       pixelData = new char[pixelDataSize];
+       memcpy (pixelData, data, pixelDataSize);
     }
 
     ~BufferedTile()
     {
-    delete [] pixelData;
+       delete [] pixelData;
     }
 };
 
@@ -230,10 +237,11 @@ TileBuffer::~TileBuffer ()
 } // namespace
 
 
-struct TiledOutputFile::Data: public Mutex
+struct TiledOutputFile::Data
 {
     Header             header;                 // the image header
     int                        version;                // file format version
+    bool                multipart;              // part came from a multipart file
     TileDescription    tileDesc;               // describes the tile layout
     FrameBuffer                frameBuffer;            // framebuffer to write into
     Int64              previewPosition;
@@ -249,44 +257,43 @@ struct TiledOutputFile::Data: public Mutex
     int *              numYTiles;              // number of y tiles at a level
 
     TileOffsets                tileOffsets;            // stores offsets in file for
-                        // each tile
+                                               // each tile
 
     Compressor::Format format;                 // compressor's data format
     vector<TOutSliceInfo> slices;              // info about channels in file
-    OStream *          os;                     // file stream to write to
-    bool               deleteStream;
 
     size_t             maxBytesPerTileLine;    // combined size of a tile line
-                        // over all channels
-
+                                               // over all channels
 
+    
     vector<TileBuffer*> tileBuffers;
     size_t             tileBufferSize;         // size of a tile buffer
 
     Int64              tileOffsetsPosition;    // position of the tile index
-    Int64              currentPosition;        // current position in the file
-
+    
     TileMap            tileMap;
     TileCoord          nextTileToWrite;
 
-     Data (bool del, int numThreads);
-    ~Data ();
+    int                 partNumber;             // the output part number
 
+     Data (int numThreads);
+    ~Data ();
+    
     inline TileBuffer *        getTileBuffer (int number);
-                            // hash function from tile
-                        // buffer coords into our
-                        // vector of tile buffers
-
+                                               // hash function from tile
+                                               // buffer coords into our
+                                               // vector of tile buffers
+    
     TileCoord          nextTileCoord (const TileCoord &a);
 };
 
 
-TiledOutputFile::Data::Data (bool del, int numThreads):
+TiledOutputFile::Data::Data (int numThreads):
+    multipart(false),
     numXTiles(0),
     numYTiles(0),
-    os (0),
-    deleteStream (del),
-    tileOffsetsPosition (0)
+    tileOffsetsPosition (0),
+    partNumber(-1)
 {
     //
     // We need at least one tileBuffer, but if threading is used,
@@ -302,15 +309,12 @@ TiledOutputFile::Data::~Data ()
     delete [] numXTiles;
     delete [] numYTiles;
 
-    if (deleteStream)
-    delete os;
-
     //
     // Delete all the tile buffers, if any still happen to exist
     //
-
+    
     for (TileMap::iterator i = tileMap.begin(); i != tileMap.end(); ++i)
-    delete i->second;
+       delete i->second;
 
     for (size_t i = 0; i < tileBuffers.size(); i++)
         delete tileBuffers[i];
@@ -328,7 +332,7 @@ TileCoord
 TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
 {
     TileCoord b = a;
-
+    
     if (lineOrder == INCREASING_Y)
     {
         b.dx++;
@@ -340,9 +344,9 @@ TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
 
             if (b.dy >= numYTiles[b.ly])
             {
-        //
-        // the next tile is in the next level
-        //
+               //
+               // the next tile is in the next level
+               //
 
                 b.dy = 0;
 
@@ -364,11 +368,14 @@ TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
                         b.lx = 0;
                         b.ly++;
 
-            #ifdef DEBUG
-                assert (b.ly <= numYLevels);
-            #endif
+                       #ifdef DEBUG
+                           assert (b.ly <= numYLevels);
+                       #endif
                     }
                     break;
+                  case  NUM_LEVELMODES:
+                      throw(IEX_NAMESPACE::ArgExc("Invalid tile description"));
+                      
                 }
             }
         }
@@ -384,9 +391,9 @@ TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
 
             if (b.dy < 0)
             {
-        //
-        // the next tile is in the next level
-        //
+               //
+               // the next tile is in the next level
+               //
 
                 switch (tileDesc.mode)
                 {
@@ -406,29 +413,33 @@ TiledOutputFile::Data::nextTileCoord (const TileCoord &a)
                         b.lx = 0;
                         b.ly++;
 
-            #ifdef DEBUG
-                assert (b.ly <= numYLevels);
-            #endif
+                       #ifdef DEBUG
+                           assert (b.ly <= numYLevels);
+                       #endif
                     }
                     break;
+                  case  NUM_LEVELMODES:
+                      throw(IEX_NAMESPACE::ArgExc("Invalid tile description"));
+                      
                 }
 
-        if (b.ly < numYLevels)
-            b.dy = numYTiles[b.ly] - 1;
+               if (b.ly < numYLevels)
+                   b.dy = numYTiles[b.ly] - 1;
             }
         }
     }
-
-    return b;
+    
+    return b;   
 }
 
 
 namespace {
 
 void
-writeTileData (TiledOutputFile::Data *ofd,
+writeTileData (OutputStreamMutex *streamData,
+               TiledOutputFile::Data *ofd,
                int dx, int dy,
-           int lx, int ly,
+              int lx, int ly, 
                const char pixelData[],
                int pixelDataSize)
 {
@@ -438,46 +449,56 @@ writeTileData (TiledOutputFile::Data *ofd,
     // without calling tellp() (tellp() can be fairly expensive).
     //
 
-    Int64 currentPosition = ofd->currentPosition;
-    ofd->currentPosition = 0;
+    Int64 currentPosition = streamData->currentPosition;
+    streamData->currentPosition = 0;
 
     if (currentPosition == 0)
-        currentPosition = ofd->os->tellp();
+        currentPosition = streamData->os->tellp();
 
     ofd->tileOffsets (dx, dy, lx, ly) = currentPosition;
 
     #ifdef DEBUG
-    assert (ofd->os->tellp() == currentPosition);
+       assert (streamData->os->tellp() == currentPosition);
     #endif
 
     //
     // Write the tile header.
     //
 
-    Xdr::write <StreamIO> (*ofd->os, dx);
-    Xdr::write <StreamIO> (*ofd->os, dy);
-    Xdr::write <StreamIO> (*ofd->os, lx);
-    Xdr::write <StreamIO> (*ofd->os, ly);
-    Xdr::write <StreamIO> (*ofd->os, pixelDataSize);
+    if (ofd->multipart)
+    {
+        Xdr::write <StreamIO> (*streamData->os, ofd->partNumber);
+    }
+    Xdr::write <StreamIO> (*streamData->os, dx);
+    Xdr::write <StreamIO> (*streamData->os, dy);
+    Xdr::write <StreamIO> (*streamData->os, lx);
+    Xdr::write <StreamIO> (*streamData->os, ly);
+    Xdr::write <StreamIO> (*streamData->os, pixelDataSize);
 
-    ofd->os->write (pixelData, pixelDataSize);
+    streamData->os->write (pixelData, pixelDataSize);
 
     //
-    // Keep current position in the file so that we can avoid
+    // Keep current position in the file so that we can avoid 
     // redundant seekg() operations (seekg() can be fairly expensive).
     //
 
-    ofd->currentPosition = currentPosition +
+    streamData->currentPosition = currentPosition +
                            5 * Xdr::size<int>() +
                            pixelDataSize;
+
+    if (ofd->multipart)
+    {
+        streamData->currentPosition += Xdr::size<int>();
+    }
 }
 
 
 
 void
-bufferedTileWrite (TiledOutputFile::Data *ofd,
+bufferedTileWrite (OutputStreamMutex *streamData,
+                   TiledOutputFile::Data *ofd,
                    int dx, int dy,
-           int lx, int ly,
+                  int lx, int ly, 
                    const char pixelData[],
                    int pixelDataSize)
 {
@@ -487,22 +508,22 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
 
     if (ofd->tileOffsets (dx, dy, lx, ly))
     {
-    THROW (Iex::ArgExc,
-           "Attempt to write tile "
-           "(" << dx << ", " << dy << ", " << lx << "," << ly << ") "
-           "more than once.");
+       THROW (IEX_NAMESPACE::ArgExc,
+              "Attempt to write tile "
+              "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
+              "more than once.");
     }
 
     //
     // If tiles can be written in random order, then don't buffer anything.
     //
-
+    
     if (ofd->lineOrder == RANDOM_Y)
     {
-        writeTileData (ofd, dx, dy, lx, ly, pixelData, pixelDataSize);
+        writeTileData (streamData, ofd, dx, dy, lx, ly, pixelData, pixelDataSize);
         return;
     }
-
+    
     //
     // If the tiles cannot be written in random order, then check if a
     // tile with coordinates (dx,dy,lx,ly) has already been buffered.
@@ -512,10 +533,10 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
 
     if (ofd->tileMap.find (currentTile) != ofd->tileMap.end())
     {
-    THROW (Iex::ArgExc,
-           "Attempt to write tile "
-           "(" << dx << ", " << dy << ", " << lx << "," << ly << ") "
-           "more than once.");
+       THROW (IEX_NAMESPACE::ArgExc,
+              "Attempt to write tile "
+              "(" << dx << ", " << dy << ", " << lx << ", " << ly << ") "
+              "more than once.");
     }
 
     //
@@ -525,38 +546,39 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
     //
     // Otherwise, buffer the tile so it can be written to file later.
     //
-
+    
     if (ofd->nextTileToWrite == currentTile)
     {
-        writeTileData (ofd, dx, dy, lx, ly, pixelData, pixelDataSize);
+        writeTileData (streamData, ofd, dx, dy, lx, ly, pixelData, pixelDataSize);
         ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite);
 
         TileMap::iterator i = ofd->tileMap.find (ofd->nextTileToWrite);
-
+        
         //
         // Step through the tiles and write all successive buffered tiles after
         // the current one.
         //
-
+        
         while(i != ofd->tileMap.end())
         {
             //
             // Write the tile, and then delete the tile's buffered data
             //
 
-            writeTileData (ofd,
-               i->first.dx, i->first.dy,
-               i->first.lx, i->first.ly,
-               i->second->pixelData,
-               i->second->pixelDataSize);
+            writeTileData (streamData,
+                           ofd,
+                          i->first.dx, i->first.dy,
+                          i->first.lx, i->first.ly,
+                          i->second->pixelData,
+                          i->second->pixelDataSize);
 
             delete i->second;
             ofd->tileMap.erase (i);
-
+            
             //
             // Proceed to the next tile
             //
-
+            
             ofd->nextTileToWrite = ofd->nextTileCoord (ofd->nextTileToWrite);
             i = ofd->tileMap.find (ofd->nextTileToWrite);
         }
@@ -568,8 +590,8 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
         // insert it into the tileMap.
         //
 
-    ofd->tileMap[currentTile] =
-        new BufferedTile ((const char *)pixelData, pixelDataSize);
+       ofd->tileMap[currentTile] =
+           new BufferedTile ((const char *)pixelData, pixelDataSize);
     }
 }
 
@@ -577,11 +599,11 @@ bufferedTileWrite (TiledOutputFile::Data *ofd,
 void
 convertToXdr (TiledOutputFile::Data *ofd,
               Array<char>& tileBuffer,
-          int numScanLines,
-          int numPixelsPerScanLine)
+             int numScanLines,
+             int numPixelsPerScanLine)
 {
     //
-    // Convert the contents of a TiledOutputFile's tileBuffer from the
+    // Convert the contents of a TiledOutputFile's tileBuffer from the 
     // machine's native representation to Xdr format. This function is called
     // by writeTile(), below, if the compressor wanted its input pixel data
     // in the machine's native format, but then failed to compress the data
@@ -607,26 +629,26 @@ convertToXdr (TiledOutputFile::Data *ofd,
 
     for (int y = 0; y < numScanLines; ++y)
     {
-    //
-    // Iterate over all slices in the file.
-    //
-
-    for (unsigned int i = 0; i < ofd->slices.size(); ++i)
-    {
-        const TOutSliceInfo &slice = ofd->slices[i];
-
-        //
-        // Convert the samples in place.
-        //
-
+       //
+       // Iterate over all slices in the file.
+       //
+
+       for (unsigned int i = 0; i < ofd->slices.size(); ++i)
+       {
+           const TOutSliceInfo &slice = ofd->slices[i];
+
+           //
+           // Convert the samples in place.
+           //
+            
             convertInPlace (writePtr, readPtr, slice.type,
                             numPixelsPerScanLine);
-    }
+       }
     }
 
     #ifdef DEBUG
 
-    assert (writePtr == readPtr);
+       assert (writePtr == readPtr);
 
     #endif
 }
@@ -641,17 +663,17 @@ convertToXdr (TiledOutputFile::Data *ofd,
 class TileBufferTask: public Task
 {
   public:
-
+                    
     TileBufferTask (TaskGroup *group,
                     TiledOutputFile::Data *ofd,
                     int number,
-            int dx, int dy,
-            int lx, int ly);
-
+                   int dx, int dy,
+                   int lx, int ly);
+                    
     virtual ~TileBufferTask ();
 
     virtual void               execute ();
-
+    
   private:
 
     TiledOutputFile::Data *    _ofd;
@@ -696,51 +718,51 @@ TileBufferTask::execute ()
     {
         //
         // First copy the pixel data from the frame buffer
-    // into the tile buffer
+       // into the tile buffer
         //
         // Convert one tile's worth of pixel data to
         // a machine-independent representation, and store
         // the result in _tileBuffer->buffer.
         //
-
+    
         char *writePtr = _tileBuffer->buffer;
-
-        Box2i tileRange = Imf::dataWindowForTile (_ofd->tileDesc,
+    
+        Box2i tileRange = dataWindowForTile (_ofd->tileDesc,
                                                   _ofd->minX, _ofd->maxX,
                                                   _ofd->minY, _ofd->maxY,
                                                   _tileBuffer->tileCoord.dx,
                                                   _tileBuffer->tileCoord.dy,
                                                   _tileBuffer->tileCoord.lx,
                                                   _tileBuffer->tileCoord.ly);
-
+    
         int numScanLines = tileRange.max.y - tileRange.min.y + 1;
         int numPixelsPerScanLine = tileRange.max.x - tileRange.min.x + 1;
-
+    
         //
         // Iterate over the scan lines in the tile.
         //
-
+        
         for (int y = tileRange.min.y; y <= tileRange.max.y; ++y)
         {
             //
             // Iterate over all image channels.
             //
-
+    
             for (unsigned int i = 0; i < _ofd->slices.size(); ++i)
             {
                 const TOutSliceInfo &slice = _ofd->slices[i];
-
+    
                 //
                 // These offsets are used to facilitate both absolute
                 // and tile-relative pixel coordinates.
                 //
-
+            
                 int xOffset = slice.xTileCoords * tileRange.min.x;
                 int yOffset = slice.yTileCoords * tileRange.min.y;
-
-        //
-        // Fill the tile buffer with pixel data.
-        //
+    
+               //
+               // Fill the tile buffer with pixel data.
+               //
 
                 if (slice.zero)
                 {
@@ -748,7 +770,7 @@ TileBufferTask::execute ()
                     // The frame buffer contains no data for this channel.
                     // Store zeroes in _data->tileBuffer.
                     //
-
+                    
                     fillChannelWithZeroes (writePtr, _ofd->format, slice.type,
                                            numPixelsPerScanLine);
                 }
@@ -757,7 +779,7 @@ TileBufferTask::execute ()
                     //
                     // The frame buffer contains data for this channel.
                     //
-
+    
                     const char *readPtr = slice.base +
                                           (y - yOffset) * slice.yStride +
                                           (tileRange.min.x - xOffset) *
@@ -766,22 +788,22 @@ TileBufferTask::execute ()
                     const char *endPtr  = readPtr +
                                           (numPixelsPerScanLine - 1) *
                                           slice.xStride;
-
+                                        
                     copyFromFrameBuffer (writePtr, readPtr, endPtr,
                                          slice.xStride, _ofd->format,
                                          slice.type);
                 }
             }
         }
-
+        
         //
-        // Compress the contents of the tileBuffer,
+        // Compress the contents of the tileBuffer, 
         // and store the compressed data in the output file.
         //
-
+    
         _tileBuffer->dataSize = writePtr - _tileBuffer->buffer;
         _tileBuffer->dataPtr = _tileBuffer->buffer;
-
+    
         if (_tileBuffer->compressor)
         {
             const char *compPtr;
@@ -790,7 +812,7 @@ TileBufferTask::execute ()
                                                 (_tileBuffer->dataPtr,
                                                  _tileBuffer->dataSize,
                                                  tileRange, compPtr);
-
+    
             if (compSize < _tileBuffer->dataSize)
             {
                 _tileBuffer->dataSize = compSize;
@@ -803,7 +825,7 @@ TileBufferTask::execute ()
                 // we cannot write to the file using native format,
                 // so we need to convert the lineBuffer to Xdr.
                 //
-
+    
                 convertToXdr (_ofd, _tileBuffer->buffer, numScanLines,
                               numPixelsPerScanLine);
             }
@@ -835,58 +857,115 @@ TiledOutputFile::TiledOutputFile
      const Header &header,
      int numThreads)
 :
-    _data (new Data (true, numThreads))
+    _data (new Data (numThreads)),
+    _streamData (new OutputStreamMutex()),
+    _deleteStream (true)
 {
     try
     {
-    header.sanityCheck (true);
-    _data->os = new StdOFStream (fileName);
-    initialize (header);
+        header.sanityCheck (true);
+        _streamData->os = new StdOFStream (fileName);
+        _data->multipart=false; // since we opened with one header we can't be multipart        
+        initialize (header);
+        _streamData->currentPosition = _streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_streamData->os, _data->header);
+        _data->previewPosition = _data->header.writeTo (*_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_streamData->os);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        // ~TiledOutputFile will not run, so free memory here
+        delete _streamData->os;
+        delete _streamData;
+        delete _data;
 
-    REPLACE_EXC (e, "Cannot open image file "
-            "\"" << fileName << "\". " << e);
-    throw;
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << fileName << "\". " << e.what());
+        throw;
     }
     catch (...)
     {
-    delete _data;
+        // ~TiledOutputFile will not run, so free memory here
+        delete _streamData->os;
+        delete _streamData;
+        delete _data;
         throw;
     }
 }
 
 
 TiledOutputFile::TiledOutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      int numThreads)
 :
-    _data (new Data (false, numThreads))
+    _data (new Data (numThreads)),
+    _streamData (new OutputStreamMutex()),
+    _deleteStream (false)
 {
     try
     {
-    header.sanityCheck(true);
-    _data->os = &os;
-    initialize (header);
+        header.sanityCheck(true);
+        _streamData->os = &os;
+        _data->multipart=false; // since we opened with one header we can't be multipart
+        initialize (header);
+        _streamData->currentPosition = _streamData->os->tellp();
+
+        // Write header and empty offset table to the file.
+        writeMagicNumberAndVersionField(*_streamData->os, _data->header);
+        _data->previewPosition = _data->header.writeTo (*_streamData->os, true);
+        _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_streamData->os);
+    
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    delete _data;
+        delete _streamData;
+        delete _data;
 
-    REPLACE_EXC (e, "Cannot open image file "
-            "\"" << os.fileName() << "\". " << e);
-    throw;
+        REPLACE_EXC (e, "Cannot open image file "
+                     "\"" << os.fileName() << "\". " << e.what());
+        throw;
     }
     catch (...)
     {
-    delete _data;
+        delete _streamData;
+        delete _data;
         throw;
     }
 }
 
+TiledOutputFile::TiledOutputFile(const OutputPartData* part) :
+    _deleteStream (false)
+{
+    try
+    {
+        if (part->header.type() != TILEDIMAGE)
+            throw IEX_NAMESPACE::ArgExc("Can't build a TiledOutputFile from a type-mismatched part.");
+
+        _streamData = part->mutex;
+        _data = new Data(part->numThreads);
+        _data->multipart=part->multipart;
+        initialize(part->header);
+        _data->partNumber = part->partNumber;
+        _data->tileOffsetsPosition = part->chunkOffsetTablePosition;
+        _data->previewPosition = part->previewPosition;
+    }
+    catch (IEX_NAMESPACE::BaseExc &e)
+    {
+        delete _data;
+
+        REPLACE_EXC (e, "Cannot initialize output part "
+                     "\"" << part->partNumber << "\". " << e.what());
+        throw;
+    }
+    catch (...)
+    {
+        delete _data;
+        throw;
+    }
+}
 
 void
 TiledOutputFile::initialize (const Header &header)
@@ -894,12 +973,25 @@ TiledOutputFile::initialize (const Header &header)
     _data->header = header;
     _data->lineOrder = _data->header.lineOrder();
 
+    
+    
     //
     // Check that the file is indeed tiled
     //
 
     _data->tileDesc = _data->header.tileDescription();
 
+    
+    //
+    // 'Fix' the type attribute if it exists but is incorrectly set
+    // (attribute is optional, but ensure it is correct if it exists)
+    //
+    if(_data->header.hasType())
+    {
+        _data->header.setType(TILEDIMAGE);
+    }
+
+    
     //
     // Save the dataWindow information
     //
@@ -915,25 +1007,25 @@ TiledOutputFile::initialize (const Header &header)
     //
 
     precalculateTileInfo (_data->tileDesc,
-              _data->minX, _data->maxX,
-              _data->minY, _data->maxY,
-              _data->numXTiles, _data->numYTiles,
-              _data->numXLevels, _data->numYLevels);
-
+                         _data->minX, _data->maxX,
+                         _data->minY, _data->maxY,
+                         _data->numXTiles, _data->numYTiles,
+                         _data->numXLevels, _data->numYLevels);       
+    
     //
     // Determine the first tile coordinate that we will be writing
     // if the file is not RANDOM_Y.
     //
-
+    
     _data->nextTileToWrite = (_data->lineOrder == INCREASING_Y)?
-                   TileCoord (0, 0, 0, 0):
-                   TileCoord (0, _data->numYTiles[0] - 1, 0, 0);
+                              TileCoord (0, 0, 0, 0):
+                              TileCoord (0, _data->numYTiles[0] - 1, 0, 0);
 
     _data->maxBytesPerTileLine =
-        calculateBytesPerPixel (_data->header) * _data->tileDesc.xSize;
+           calculateBytesPerPixel (_data->header) * _data->tileDesc.xSize;
 
     _data->tileBufferSize = _data->maxBytesPerTileLine * _data->tileDesc.ySize;
-
+     
     //
     // Create all the TileBuffers and allocate their internal buffers
     //
@@ -941,10 +1033,10 @@ TiledOutputFile::initialize (const Header &header)
     for (size_t i = 0; i < _data->tileBuffers.size(); i++)
     {
         _data->tileBuffers[i] = new TileBuffer (newTileCompressor
-                          (_data->header.compression(),
-                           _data->maxBytesPerTileLine,
-                           _data->tileDesc.ySize,
-                           _data->header));
+                                                 (_data->header.compression(),
+                                                  _data->maxBytesPerTileLine,
+                                                  _data->tileDesc.ySize,
+                                                  _data->header));
 
         _data->tileBuffers[i]->buffer.resizeErase(_data->tileBufferSize);
     }
@@ -952,15 +1044,10 @@ TiledOutputFile::initialize (const Header &header)
     _data->format = defaultFormat (_data->tileBuffers[0]->compressor);
 
     _data->tileOffsets = TileOffsets (_data->tileDesc.mode,
-                      _data->numXLevels,
-                      _data->numYLevels,
-                      _data->numXTiles,
-                      _data->numYTiles);
-
-    _data->previewPosition = _data->header.writeTo (*_data->os, true);
-
-    _data->tileOffsetsPosition = _data->tileOffsets.writeTo (*_data->os);
-    _data->currentPosition = _data->os->tellp();
+                                     _data->numXLevels,
+                                     _data->numYLevels,
+                                     _data->numXTiles,
+                                     _data->numYTiles);
 }
 
 
@@ -969,12 +1056,20 @@ TiledOutputFile::~TiledOutputFile ()
     if (_data)
     {
         {
+            Lock lock(*_streamData);
+            Int64 originalPosition = _streamData->os->tellp();
+
             if (_data->tileOffsetsPosition > 0)
             {
                 try
                 {
-                    _data->os->seekp (_data->tileOffsetsPosition);
-                    _data->tileOffsets.writeTo (*_data->os);
+                    _streamData->os->seekp (_data->tileOffsetsPosition);
+                    _data->tileOffsets.writeTo (*_streamData->os);
+
+                    //
+                    // Restore the original position.
+                    //
+                    _streamData->os->seekp (originalPosition);
                 }
                 catch (...)
                 {
@@ -987,6 +1082,12 @@ TiledOutputFile::~TiledOutputFile ()
                 }
             }
         }
+        
+        if (_deleteStream && _streamData)
+            delete _streamData->os;
+
+        if (_data->partNumber == -1)
+            delete _streamData;
 
         delete _data;
     }
@@ -996,7 +1097,7 @@ TiledOutputFile::~TiledOutputFile ()
 const char *
 TiledOutputFile::fileName () const
 {
-    return _data->os->fileName();
+    return _streamData->os->fileName();
 }
 
 
@@ -1007,10 +1108,10 @@ TiledOutputFile::header () const
 }
 
 
-void
+void   
 TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     //
     // Check if the new frame buffer descriptor
@@ -1020,25 +1121,25 @@ TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
     const ChannelList &channels = _data->header.channels();
 
     for (ChannelList::ConstIterator i = channels.begin();
-     i != channels.end();
-     ++i)
+        i != channels.end();
+        ++i)
     {
-    FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+       FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
 
-    if (j == frameBuffer.end())
-        continue;
+       if (j == frameBuffer.end())
+           continue;
 
-    if (i.channel().type != j.slice().type)
-        THROW (Iex::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
-                "of output file \"" << fileName() << "\" is "
-                "not compatible with the frame buffer's "
-                "pixel type.");
+       if (i.channel().type != j.slice().type)
+           THROW (IEX_NAMESPACE::ArgExc, "Pixel type of \"" << i.name() << "\" channel "
+                               "of output file \"" << fileName() << "\" is "
+                               "not compatible with the frame buffer's "
+                               "pixel type.");
 
-    if (j.slice().xSampling != 1 || j.slice().ySampling != 1)
-        THROW (Iex::ArgExc, "All channels in a tiled file must have"
-                "sampling (1,1).");
+       if (j.slice().xSampling != 1 || j.slice().ySampling != 1)
+           THROW (IEX_NAMESPACE::ArgExc, "All channels in a tiled file must have"
+                               "sampling (1,1).");
     }
-
+    
     //
     // Initialize slice table for writePixels().
     //
@@ -1046,38 +1147,38 @@ TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
     vector<TOutSliceInfo> slices;
 
     for (ChannelList::ConstIterator i = channels.begin();
-     i != channels.end();
-     ++i)
-    {
-    FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
-
-    if (j == frameBuffer.end())
-    {
-        //
-        // Channel i is not present in the frame buffer.
-        // In the file, channel i will contain only zeroes.
-        //
-
-        slices.push_back (TOutSliceInfo (i.channel().type,
-                         0, // base
-                         0, // xStride,
-                         0, // yStride,
-                         true)); // zero
-    }
-    else
+        i != channels.end();
+        ++i)
     {
-        //
-        // Channel i is present in the frame buffer.
-        //
-
-        slices.push_back (TOutSliceInfo (j.slice().type,
-                         j.slice().base,
-                         j.slice().xStride,
-                         j.slice().yStride,
-                         false, // zero
+       FrameBuffer::ConstIterator j = frameBuffer.find (i.name());
+
+       if (j == frameBuffer.end())
+       {
+           //
+           // Channel i is not present in the frame buffer.
+           // In the file, channel i will contain only zeroes.
+           //
+
+           slices.push_back (TOutSliceInfo (i.channel().type,
+                                            0, // base
+                                            0, // xStride,
+                                            0, // yStride,
+                                            true)); // zero
+       }
+       else
+       {
+           //
+           // Channel i is present in the frame buffer.
+           //
+
+           slices.push_back (TOutSliceInfo (j.slice().type,
+                                            j.slice().base,
+                                            j.slice().xStride,
+                                            j.slice().yStride,
+                                            false, // zero
                                              (j.slice().xTileCoords)? 1: 0,
                                              (j.slice().yTileCoords)? 1: 0));
-    }
+       }
     }
 
     //
@@ -1092,67 +1193,72 @@ TiledOutputFile::setFrameBuffer (const FrameBuffer &frameBuffer)
 const FrameBuffer &
 TiledOutputFile::frameBuffer () const
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
     return _data->frameBuffer;
 }
 
 
-void
+void   
 TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
                              int lx, int ly)
 {
     try
     {
-        Lock lock (*_data);
+        Lock lock (*_streamData);
 
         if (_data->slices.size() == 0)
-        throw Iex::ArgExc ("No frame buffer specified "
-                   "as pixel data source.");
+           throw IEX_NAMESPACE::ArgExc ("No frame buffer specified "
+                              "as pixel data source.");
 
-    if (!isValidTile (dx1, dy1, lx, ly) || !isValidTile (dx2, dy2, lx, ly))
-        throw Iex::ArgExc ("Tile coordinates are invalid.");
+       if (!isValidTile (dx1, dy1, lx, ly) || !isValidTile (dx2, dy2, lx, ly))
+           throw IEX_NAMESPACE::ArgExc ("Tile coordinates are invalid.");
 
+       if (!isValidLevel (lx, ly))
+           THROW (IEX_NAMESPACE::ArgExc,
+                   "Level coordinate "
+                   "(" << lx << ", " << ly << ") "
+                   "is invalid.");
         //
         // Determine the first and last tile coordinates in both dimensions
         // based on the file's lineOrder
         //
-
+                               
         if (dx1 > dx2)
             swap (dx1, dx2);
-
+        
         if (dy1 > dy2)
             swap (dy1, dy2);
-
+        
         int dyStart = dy1;
-    int dyStop  = dy2 + 1;
-    int dY      = 1;
-
+       int dyStop  = dy2 + 1;
+       int dY      = 1;
+    
         if (_data->lineOrder == DECREASING_Y)
         {
             dyStart = dy2;
             dyStop  = dy1 - 1;
             dY      = -1;
         }
-
+        
         int numTiles = (dx2 - dx1 + 1) * (dy2 - dy1 + 1);
         int numTasks = min ((int)_data->tileBuffers.size(), numTiles);
 
         //
         // Create a task group for all tile buffer tasks.  When the
-    // task group goes out of scope, the destructor waits until
-    // all tasks are complete.
+       // task group goes out of scope, the destructor waits until
+       // all tasks are complete.
         //
 
         {
             TaskGroup taskGroup;
-
+    
             //
             // Add in the initial compression tasks to the thread pool
             //
-
+    
             int nextCompBuffer = 0;
-        int dxComp         = dx1;
-        int dyComp         = dyStart;
+           int dxComp         = dx1;
+           int dyComp         = dyStart;
 
             while (nextCompBuffer < numTasks)
             {
@@ -1169,61 +1275,61 @@ TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
                     dyComp += dY;
                 }
             }
-
+            
             //
             // Write the compressed buffers and add in more compression
-        // tasks until done
+           // tasks until done
             //
-
+    
             int nextWriteBuffer = 0;
-        int dxWrite         = dx1;
-        int dyWrite         = dyStart;
+           int dxWrite         = dx1;
+           int dyWrite         = dyStart;
 
             while (nextWriteBuffer < numTiles)
             {
-        //
+               //
                 // Wait until the nextWriteBuffer is ready to be written
-        //
+               //
 
                 TileBuffer* writeBuffer =
                                     _data->getTileBuffer (nextWriteBuffer);
 
                 writeBuffer->wait();
-
-        //
+    
+               //
                 // Write the tilebuffer
-        //
+               //
 
-                bufferedTileWrite (_data, dxWrite, dyWrite, lx, ly,
+                bufferedTileWrite (_streamData, _data, dxWrite, dyWrite, lx, ly,
                                    writeBuffer->dataPtr,
                                    writeBuffer->dataSize);
-
-        //
+                
+               //
                 // Release the lock on nextWriteBuffer
-        //
+               //
 
                 writeBuffer->post();
-
-        //
+                
+               //
                 // If there are no more tileBuffers to compress, then
-        // only continue to write out remaining tileBuffers,
-        // otherwise keep adding compression tasks.
-        //
+               // only continue to write out remaining tileBuffers,
+               // otherwise keep adding compression tasks.
+               //
 
                 if (nextCompBuffer < numTiles)
                 {
-            //
+                   //
                     // add nextCompBuffer as a compression Task
-            //
+                   //
 
                     ThreadPool::addGlobalTask
-            (new TileBufferTask (&taskGroup,
-                         _data,
-                         nextCompBuffer,
+                       (new TileBufferTask (&taskGroup,
+                                            _data,
+                                            nextCompBuffer,
                                              dxComp, dyComp,
-                         lx, ly));
+                                            lx, ly));
                 }
-
+    
                 nextWriteBuffer++;
                 dxWrite++;
 
@@ -1232,7 +1338,7 @@ TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
                     dxWrite = dx1;
                     dyWrite += dY;
                 }
-
+                    
                 nextCompBuffer++;
                 dxComp++;
 
@@ -1243,58 +1349,58 @@ TiledOutputFile::writeTiles (int dx1, int dx2, int dy1, int dy2,
                 }
             }
 
-        //
+           //
             // finish all tasks
-        //
+           //
         }
 
-    //
-    // Exeption handling:
-    //
-    // TileBufferTask::execute() may have encountered exceptions, but
-    // those exceptions occurred in another thread, not in the thread
-    // that is executing this call to TiledOutputFile::writeTiles().
-    // TileBufferTask::execute() has caught all exceptions and stored
-    // the exceptions' what() strings in the tile buffers.
-    // Now we check if any tile buffer contains a stored exception; if
-    // this is the case then we re-throw the exception in this thread.
-    // (It is possible that multiple tile buffers contain stored
-    // exceptions.  We re-throw the first exception we find and
-    // ignore all others.)
-    //
-
-    const string *exception = 0;
-
-        for (int i = 0; i < _data->tileBuffers.size(); ++i)
-    {
+       //
+       // Exeption handling:
+       //
+       // TileBufferTask::execute() may have encountered exceptions, but
+       // those exceptions occurred in another thread, not in the thread
+       // that is executing this call to TiledOutputFile::writeTiles().
+       // TileBufferTask::execute() has caught all exceptions and stored
+       // the exceptions' what() strings in the tile buffers.
+       // Now we check if any tile buffer contains a stored exception; if
+       // this is the case then we re-throw the exception in this thread.
+       // (It is possible that multiple tile buffers contain stored
+       // exceptions.  We re-throw the first exception we find and
+       // ignore all others.)
+       //
+
+       const string *exception = 0;
+
+        for (size_t i = 0; i < _data->tileBuffers.size(); ++i)
+       {
             TileBuffer *tileBuffer = _data->tileBuffers[i];
 
-        if (tileBuffer->hasException && !exception)
-        exception = &tileBuffer->exception;
+           if (tileBuffer->hasException && !exception)
+               exception = &tileBuffer->exception;
 
-        tileBuffer->hasException = false;
-    }
+           tileBuffer->hasException = false;
+       }
 
-    if (exception)
-        throw Iex::IoExc (*exception);
+       if (exception)
+           throw IEX_NAMESPACE::IoExc (*exception);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
         REPLACE_EXC (e, "Failed to write pixel data to image "
-                        "file \"" << fileName() << "\". " << e);
+                     "file \"" << fileName() << "\". " << e.what());
         throw;
     }
 }
 
 
-void
+void   
 TiledOutputFile::writeTiles (int dx1, int dxMax, int dyMin, int dyMax, int l)
 {
     writeTiles (dx1, dxMax, dyMin, dyMax, l, l);
 }
 
 
-void
+void   
 TiledOutputFile::writeTile (int dx, int dy, int lx, int ly)
 {
     writeTiles (dx, dx, dy, dy, lx, ly);
@@ -1308,10 +1414,10 @@ TiledOutputFile::writeTile (int dx, int dy, int l)
 }
 
 
-void
+void   
 TiledOutputFile::copyPixels (TiledInputFile &in)
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     //
     // Check if this file's and and the InputFile's
@@ -1319,43 +1425,43 @@ TiledOutputFile::copyPixels (TiledInputFile &in)
     //
 
     const Header &hdr = _data->header;
-    const Header &inHdr = in.header();
+    const Header &inHdr = in.header(); 
 
     if (!hdr.hasTileDescription() || !inHdr.hasTileDescription())
-        THROW (Iex::ArgExc, "Cannot perform a quick pixel copy from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\".  The "
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot perform a quick pixel copy from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\".  The "
                             "output file is tiled, but the input file is not.  "
                             "Try using OutputFile::copyPixels() instead.");
 
     if (!(hdr.tileDescription() == inHdr.tileDescription()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\" failed. "
-                "The files have different tile descriptions.");
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\" failed. "
+                           "The files have different tile descriptions.");
 
     if (!(hdr.dataWindow() == inHdr.dataWindow()))
-        THROW (Iex::ArgExc, "Cannot copy pixels from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\". The "
+        THROW (IEX_NAMESPACE::ArgExc, "Cannot copy pixels from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\". The "
                             "files have different data windows.");
 
     if (!(hdr.lineOrder() == inHdr.lineOrder()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\" failed. "
-                "The files have different line orders.");
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\" failed. "
+                           "The files have different line orders.");
 
     if (!(hdr.compression() == inHdr.compression()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
-                "file \"" << in.fileName() << "\" to image "
-                "file \"" << fileName() << "\" failed. "
-                "The files use different compression methods.");
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                           "file \"" << in.fileName() << "\" to image "
+                           "file \"" << fileName() << "\" failed. "
+                           "The files use different compression methods.");
 
     if (!(hdr.channels() == inHdr.channels()))
-        THROW (Iex::ArgExc, "Quick pixel copy from image "
-                 "file \"" << in.fileName() << "\" to image "
-                 "file \"" << fileName() << "\" "
+        THROW (IEX_NAMESPACE::ArgExc, "Quick pixel copy from image "
+                            "file \"" << in.fileName() << "\" to image "
+                            "file \"" << fileName() << "\" "
                              "failed.  The files have different channel "
                              "lists.");
 
@@ -1364,9 +1470,9 @@ TiledOutputFile::copyPixels (TiledInputFile &in)
     //
 
     if (!_data->tileOffsets.isEmpty())
-        THROW (Iex::LogicExc, "Quick pixel copy from image "
-                  "file \"" << in.fileName() << "\" to image "
-                  "file \"" << _data->os->fileName() << "\" "
+        THROW (IEX_NAMESPACE::LogicExc, "Quick pixel copy from image "
+                             "file \"" << in.fileName() << "\" to image "
+                             "file \"" << _streamData->os->fileName() << "\" "
                               "failed. \"" << fileName() << "\" "
                               "already contains pixel data.");
 
@@ -1381,47 +1487,91 @@ TiledOutputFile::copyPixels (TiledInputFile &in)
       case ONE_LEVEL:
       case MIPMAP_LEVELS:
 
-        for (size_t i_l = 0; i_l < numLevels (); ++i_l)
+        for (int i_l = 0; i_l < numLevels (); ++i_l)
             numAllTiles += numXTiles (i_l) * numYTiles (i_l);
 
         break;
 
       case RIPMAP_LEVELS:
 
-        for (size_t i_ly = 0; i_ly < numYLevels (); ++i_ly)
-            for (size_t i_lx = 0; i_lx < numXLevels (); ++i_lx)
+        for (int i_ly = 0; i_ly < numYLevels (); ++i_ly)
+            for (int i_lx = 0; i_lx < numXLevels (); ++i_lx)
                 numAllTiles += numXTiles (i_lx) * numYTiles (i_ly);
 
         break;
 
       default:
 
-        throw Iex::ArgExc ("Unknown LevelMode format.");
+        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
+    }
+
+     bool random_y = _data->lineOrder==RANDOM_Y;
+
+    std::vector<int> dx_table(random_y ? numAllTiles : 1);
+    std::vector<int> dy_table(random_y ? numAllTiles : 1);
+    std::vector<int> lx_table(random_y ? numAllTiles : 1);
+    std::vector<int> ly_table(random_y ? numAllTiles : 1);
+    
+    if(random_y)
+    {
+        in.tileOrder(&dx_table[0],&dy_table[0],&lx_table[0],&ly_table[0]);
+        _data->nextTileToWrite.dx=dx_table[0];
+        _data->nextTileToWrite.dy=dy_table[0];
+        _data->nextTileToWrite.lx=lx_table[0];
+        _data->nextTileToWrite.ly=ly_table[0];
     }
 
     for (int i = 0; i < numAllTiles; ++i)
     {
         const char *pixelData;
         int pixelDataSize;
-
+        
         int dx = _data->nextTileToWrite.dx;
         int dy = _data->nextTileToWrite.dy;
         int lx = _data->nextTileToWrite.lx;
         int ly = _data->nextTileToWrite.ly;
 
+        
         in.rawTileData (dx, dy, lx, ly, pixelData, pixelDataSize);
-        writeTileData (_data, dx, dy, lx, ly, pixelData, pixelDataSize);
+        writeTileData (_streamData, _data, dx, dy, lx, ly, pixelData, pixelDataSize);
+        
+        if(random_y)
+        {
+            if(i<numAllTiles-1)
+            {
+               _data->nextTileToWrite.dx=dx_table[i+1];
+               _data->nextTileToWrite.dy=dy_table[i+1];
+               _data->nextTileToWrite.lx=lx_table[i+1];
+               _data->nextTileToWrite.ly=ly_table[i+1];
+            }
+        }else{
+            _data->nextTileToWrite=_data->nextTileCoord(_data->nextTileToWrite);
+        }
     }
 }
 
 
-void
+void   
 TiledOutputFile::copyPixels (InputFile &in)
 {
     copyPixels (*in.tFile());
 }
 
 
+void    
+TiledOutputFile::copyPixels (InputPart &in)
+{
+    copyPixels (*in.file);
+}
+
+void    
+TiledOutputFile::copyPixels (TiledInputPart &in)
+{
+    copyPixels (*in.file);
+}
+
+
+
 unsigned int
 TiledOutputFile::tileXSize () const
 {
@@ -1454,9 +1604,9 @@ int
 TiledOutputFile::numLevels () const
 {
     if (levelMode() == RIPMAP_LEVELS)
-    THROW (Iex::LogicExc, "Error calling numLevels() on image "
-                  "file \"" << fileName() << "\" "
-                  "(numLevels() is not defined for RIPMAPs).");
+       THROW (IEX_NAMESPACE::LogicExc, "Error calling numLevels() on image "
+                             "file \"" << fileName() << "\" "
+                             "(numLevels() is not defined for RIPMAPs).");
     return _data->numXLevels;
 }
 
@@ -1475,17 +1625,17 @@ TiledOutputFile::numYLevels () const
 }
 
 
-bool
+bool   
 TiledOutputFile::isValidLevel (int lx, int ly) const
 {
     if (lx < 0 || ly < 0)
-    return false;
+       return false;
 
     if (levelMode() == MIPMAP_LEVELS && lx != ly)
-    return false;
+       return false;
 
     if (lx >= numXLevels() || ly >= numYLevels())
-    return false;
+       return false;
 
     return true;
 }
@@ -1496,16 +1646,16 @@ TiledOutputFile::levelWidth (int lx) const
 {
     try
     {
-    int retVal = levelSize (_data->minX, _data->maxX, lx,
-                    _data->tileDesc.roundingMode);
-
+       int retVal = levelSize (_data->minX, _data->maxX, lx,
+                               _data->tileDesc.roundingMode);
+        
         return retVal;
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling levelWidth() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling levelWidth() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1515,14 +1665,14 @@ TiledOutputFile::levelHeight (int ly) const
 {
     try
     {
-    return levelSize (_data->minY, _data->maxY, ly,
-              _data->tileDesc.roundingMode);
+       return levelSize (_data->minY, _data->maxY, ly,
+                         _data->tileDesc.roundingMode);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling levelHeight() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling levelHeight() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1531,9 +1681,9 @@ int
 TiledOutputFile::numXTiles (int lx) const
 {
     if (lx < 0 || lx >= _data->numXLevels)
-    THROW (Iex::LogicExc, "Error calling numXTiles() on image "
-                  "file \"" << _data->os->fileName() << "\" "
-                  "(Argument is not in valid range).");
+       THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+                             "file \"" << _streamData->os->fileName() << "\" "
+                             "(Argument is not in valid range).");
 
     return _data->numXTiles[lx];
 }
@@ -1543,9 +1693,9 @@ int
 TiledOutputFile::numYTiles (int ly) const
 {
    if (ly < 0 || ly >= _data->numYLevels)
-    THROW (Iex::LogicExc, "Error calling numXTiles() on image "
-                  "file \"" << _data->os->fileName() << "\" "
-                  "(Argument is not in valid range).");
+       THROW (IEX_NAMESPACE::LogicExc, "Error calling numXTiles() on image "
+                             "file \"" << _streamData->os->fileName() << "\" "
+                             "(Argument is not in valid range).");
 
     return _data->numYTiles[ly];
 }
@@ -1563,16 +1713,17 @@ TiledOutputFile::dataWindowForLevel (int lx, int ly) const
 {
     try
     {
-    return Imf::dataWindowForLevel (_data->tileDesc,
-                        _data->minX, _data->maxX,
-                        _data->minY, _data->maxY,
-                    lx, ly);
+       return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForLevel (
+               _data->tileDesc,
+               _data->minX, _data->maxX,
+               _data->minY, _data->maxY,
+               lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling dataWindowForLevel() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1589,20 +1740,21 @@ TiledOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 {
     try
     {
-    if (!isValidTile (dx, dy, lx, ly))
-        throw Iex::ArgExc ("Arguments not in valid range.");
-
-    return Imf::dataWindowForTile (_data->tileDesc,
-                           _data->minX, _data->maxX,
-                           _data->minY, _data->maxY,
-                           dx, dy,
-                           lx, ly);
+       if (!isValidTile (dx, dy, lx, ly))
+           throw IEX_NAMESPACE::ArgExc ("Arguments not in valid range.");
+
+       return OPENEXR_IMF_INTERNAL_NAMESPACE::dataWindowForTile (
+               _data->tileDesc,
+               _data->minX, _data->maxX,
+               _data->minY, _data->maxY,
+               dx, dy,
+               lx, ly);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Error calling dataWindowForTile() on image "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
@@ -1611,35 +1763,35 @@ bool
 TiledOutputFile::isValidTile (int dx, int dy, int lx, int ly) const
 {
     return ((lx < _data->numXLevels && lx >= 0) &&
-        (ly < _data->numYLevels && ly >= 0) &&
-        (dx < _data->numXTiles[lx] && dx >= 0) &&
-        (dy < _data->numYTiles[ly] && dy >= 0));
+           (ly < _data->numYLevels && ly >= 0) &&
+           (dx < _data->numXTiles[lx] && dx >= 0) &&
+           (dy < _data->numYTiles[ly] && dy >= 0));
 }
 
 
 void
 TiledOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     if (_data->previewPosition <= 0)
-    THROW (Iex::LogicExc, "Cannot update preview image pixels. "
-                  "File \"" << fileName() << "\" does not "
-                  "contain a preview image.");
+       THROW (IEX_NAMESPACE::LogicExc, "Cannot update preview image pixels. "
+                             "File \"" << fileName() << "\" does not "
+                             "contain a preview image.");
 
     //
     // Store the new pixels in the header's preview image attribute.
     //
 
     PreviewImageAttribute &pia =
-    _data->header.typedAttribute <PreviewImageAttribute> ("preview");
+       _data->header.typedAttribute <PreviewImageAttribute> ("preview");
 
     PreviewImage &pi = pia.value();
     PreviewRgba *pixels = pi.pixels();
     int numPixels = pi.width() * pi.height();
 
     for (int i = 0; i < numPixels; ++i)
-    pixels[i] = newPixels[i];
+       pixels[i] = newPixels[i];
 
     //
     // Save the current file position, jump to the position in
@@ -1647,47 +1799,47 @@ TiledOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
     // preview image, and jump back to the saved file position.
     //
 
-    Int64 savedPosition = _data->os->tellp();
+    Int64 savedPosition = _streamData->os->tellp();
 
     try
     {
-    _data->os->seekp (_data->previewPosition);
-    pia.writeValueTo (*_data->os, _data->version);
-    _data->os->seekp (savedPosition);
+        _streamData->os->seekp (_data->previewPosition);
+       pia.writeValueTo (*_streamData->os, _data->version);
+       _streamData->os->seekp (savedPosition);
     }
-    catch (Iex::BaseExc &e)
+    catch (IEX_NAMESPACE::BaseExc &e)
     {
-    REPLACE_EXC (e, "Cannot update preview image pixels for "
-            "file \"" << fileName() << "\". " << e);
-    throw;
+       REPLACE_EXC (e, "Cannot update preview image pixels for "
+                 "file \"" << fileName() << "\". " << e.what());
+       throw;
     }
 }
 
 
 void
-TiledOutputFile::breakTile
+TiledOutputFile::breakTile 
     (int dx, int dy,
      int lx, int ly,
      int offset,
      int length,
      char c)
 {
-    Lock lock (*_data);
+    Lock lock (*_streamData);
 
     Int64 position = _data->tileOffsets (dx, dy, lx, ly);
 
     if (!position)
-    THROW (Iex::ArgExc,
-           "Cannot overwrite tile "
-           "(" << dx << ", " << dy << ", " << lx << "," << ly << "). "
-           "The tile has not yet been stored in "
-           "file \"" << fileName() << "\".");
+       THROW (IEX_NAMESPACE::ArgExc,
+              "Cannot overwrite tile "
+              "(" << dx << ", " << dy << ", " << lx << "," << ly << "). "
+              "The tile has not yet been stored in "
+              "file \"" << fileName() << "\".");
 
-    _data->currentPosition = 0;
-    _data->os->seekp (position + offset);
+    _streamData->currentPosition = 0;
+    _streamData->os->seekp (position + offset);
 
     for (int i = 0; i < length; ++i)
-    _data->os->write (&c, 1);
+        _streamData->os->write (&c, 1);
 }
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 951c8a3..bb75605 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
 #include "ImathBox.h"
-#include <ImfTileDescription.h>
-#include <ImfThreading.h>
+#include "ImfTileDescription.h"
+#include "ImfThreading.h"
+#include "ImfGenericOutputFile.h"
+#include "ImfForward.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
 
-class TiledInputFile;
-class InputFile;
 struct PreviewRgba;
 
 
-class TiledOutputFile
+class TiledOutputFile : public GenericOutputFile
 {
   public:
 
@@ -80,9 +84,10 @@ class TiledOutputFile
     // faster than reading the tiles in random order (see writeTile,
     // below).
     //-------------------------------------------------------------------
-
+    
+    IMF_EXPORT
     TiledOutputFile (const char fileName[],
-             const Header &header,
+                    const Header &header,
                      int numThreads = globalThreadCount ());
 
 
@@ -93,8 +98,9 @@ class TiledOutputFile
     // close the corresponding files.
     // ----------------------------------------------------------------
 
-    TiledOutputFile (OStream &os,
-             const Header &header,
+    IMF_EXPORT
+    TiledOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                    const Header &header,
                      int numThreads = globalThreadCount ());
 
 
@@ -104,21 +110,24 @@ class TiledOutputFile
     // Destroying a TiledOutputFile object before all tiles
     // have been written results in an incomplete file.
     //-----------------------------------------------------
-
+    
+    IMF_EXPORT
     virtual ~TiledOutputFile ();
 
 
     //------------------------
     // Access to the file name
     //------------------------
-
+    
+    IMF_EXPORT
     const char *       fileName () const;
 
 
     //--------------------------
     // Access to the file header
     //--------------------------
-
+    
+    IMF_EXPORT
     const Header &     header () const;
 
 
@@ -132,14 +141,16 @@ class TiledOutputFile
     // called.  The current frame buffer can be changed
     // after each call to writeTile().
     //-------------------------------------------------------
-
+    
+    IMF_EXPORT
     void               setFrameBuffer (const FrameBuffer &frameBuffer);
 
 
     //-----------------------------------
     // Access to the current frame buffer
     //-----------------------------------
-
+    
+    IMF_EXPORT
     const FrameBuffer &        frameBuffer () const;
 
 
@@ -153,9 +164,13 @@ class TiledOutputFile
     // fields of the file header's TileDescriptionAttribute.
     //---------------------------------------------------------
 
+    IMF_EXPORT
     unsigned int       tileXSize () const;
+    IMF_EXPORT
     unsigned int       tileYSize () const;
+    IMF_EXPORT
     LevelMode          levelMode () const;
+    IMF_EXPORT
     LevelRoundingMode  levelRoundingMode () const;
 
 
@@ -195,16 +210,20 @@ class TiledOutputFile
     //      return value is the same as for numXLevels()
     //
     // if levelMode() == RIPMAP_LEVELS:
-    //      an Iex::LogicExc exception is thrown
+    //      an IEX_NAMESPACE::LogicExc exception is thrown
     //
-    // isValidLevel(lx, ly) returns true if the file contains
+    // isValidLevel(lx, ly) returns true if the file contains 
     // a level with level number (lx, ly), false if not.
     //
     //--------------------------------------------------------------------
 
+    IMF_EXPORT
     int                        numLevels () const;
+    IMF_EXPORT
     int                        numXLevels () const;
+    IMF_EXPORT
     int                        numYLevels () const;
+    IMF_EXPORT
     bool               isValidLevel (int lx, int ly) const;
 
 
@@ -226,7 +245,9 @@ class TiledOutputFile
     //
     //---------------------------------------------------------
 
+    IMF_EXPORT
     int                        levelWidth  (int lx) const;
+    IMF_EXPORT
     int                        levelHeight (int ly) const;
 
 
@@ -250,7 +271,9 @@ class TiledOutputFile
     //
     //----------------------------------------------------------
 
+    IMF_EXPORT
     int                        numXTiles (int lx = 0) const;
+    IMF_EXPORT
     int                        numYTiles (int ly = 0) const;
 
 
@@ -274,8 +297,10 @@ class TiledOutputFile
     //
     //---------------------------------------------------------
 
-    Imath::Box2i       dataWindowForLevel (int l = 0) const;
-    Imath::Box2i       dataWindowForLevel (int lx, int ly) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int lx, int ly) const;
 
 
     //-------------------------------------------------------------------
@@ -299,11 +324,13 @@ class TiledOutputFile
     //
     //-------------------------------------------------------------------
 
-    Imath::Box2i       dataWindowForTile (int dx, int dy,
-                       int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy,
+                                          int l = 0) const;
 
-    Imath::Box2i       dataWindowForTile (int dx, int dy,
-                       int lx, int ly) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy,
+                                          int lx, int ly) const;
 
     //------------------------------------------------------------------
     // Write pixel data:
@@ -343,10 +370,10 @@ class TiledOutputFile
     //                 in a contiguous block.  The levels are ordered
     //                 like this:
     //
-    //                     (0, 0)   (1, 0)   ... (nx-1, 0)
-    //                     (0, 1)   (1, 1)   ... (nx-1, 1)
+    //                     (0, 0)   (1, 0)   ... (nx-1, 0) 
+    //                     (0, 1)   (1, 1)   ... (nx-1, 1) 
     //                      ...
-    //                     (0,ny-1) (1,ny-1) ... (nx-1,ny-1)
+    //                     (0,ny-1) (1,ny-1) ... (nx-1,ny-1) 
     //
     //                 where nx = numXLevels(), and ny = numYLevels().
     //                 In an individual level, (lx, ly), the tiles
@@ -377,12 +404,16 @@ class TiledOutputFile
     //
     //------------------------------------------------------------------
 
+    IMF_EXPORT
     void               writeTile  (int dx, int dy, int l = 0);
+    IMF_EXPORT
     void               writeTile  (int dx, int dy, int lx, int ly);
 
+    IMF_EXPORT
     void               writeTiles (int dx1, int dx2, int dy1, int dy2,
                                     int lx, int ly);
 
+    IMF_EXPORT
     void               writeTiles (int dx1, int dx2, int dy1, int dy2,
                                     int l = 0);
 
@@ -394,10 +425,13 @@ class TiledOutputFile
     // header:  The two header's "dataWindow", "compression",
     // "lineOrder", "channels", and "tiles" attributes must be the same.
     //------------------------------------------------------------------
-
+    
+    IMF_EXPORT
     void               copyPixels (TiledInputFile &in);
-
-
+    IMF_EXPORT
+    void        copyPixels (TiledInputPart &in);
+    
+    
     //------------------------------------------------------------------
     // Shortcut to copy all pixels from an InputFile into this file,
     // without uncompressing and then recompressing the pixel data.
@@ -407,9 +441,13 @@ class TiledOutputFile
     //
     // To use this function, the InputFile must be tiled.
     //------------------------------------------------------------------
-
+    
+    IMF_EXPORT
     void               copyPixels (InputFile &in);
+    IMF_EXPORT
+    void        copyPixels (InputPart &in);
 
+    
 
     //--------------------------------------------------------------
     // Updating the preview image:
@@ -417,7 +455,7 @@ class TiledOutputFile
     // updatePreviewImage() supplies a new set of pixels for the
     // preview image attribute in the file's header.  If the header
     // does not contain a preview image, updatePreviewImage() throws
-    // an Iex::LogicExc.
+    // an IEX_NAMESPACE::LogicExc.
     //
     // Note: updatePreviewImage() is necessary because images are
     // often stored in a file incrementally, a few tiles at a time,
@@ -429,12 +467,13 @@ class TiledOutputFile
     //
     //--------------------------------------------------------------
 
+    IMF_EXPORT
     void               updatePreviewImage (const PreviewRgba newPixels[]);
 
 
     //-------------------------------------------------------------
     // Break a tile -- for testing and debugging only:
-    //
+    // 
     // breakTile(dx,dy,lx,ly,p,n,c) introduces an error into the
     // output file by writing n copies of character c, starting
     // p bytes from the beginning of the tile with tile coordinates
@@ -446,30 +485,44 @@ class TiledOutputFile
     //
     //-------------------------------------------------------------
 
+    IMF_EXPORT
     void               breakTile  (int dx, int dy,
-                    int lx, int ly,
-                    int offset,
-                    int length,
-                    char c);
+                                   int lx, int ly,
+                                   int offset,
+                                   int length,
+                                   char c);
     struct Data;
 
   private:
 
+    // ----------------------------------------------------------------
+    // A constructor attaches the OutputStreamMutex to the
+    // given one from MultiPartOutputFile. Set the previewPosition
+    // and lineOffsetsPosition which have been acquired from
+    // the constructor of MultiPartOutputFile as well.
+    // ----------------------------------------------------------------
+    TiledOutputFile (const OutputPartData* part);
+
     TiledOutputFile (const TiledOutputFile &);             // not implemented
     TiledOutputFile & operator = (const TiledOutputFile &); // not implemented
 
     void               initialize (const Header &header);
 
     bool               isValidTile (int dx, int dy,
-                     int lx, int ly) const;
+                                    int lx, int ly) const;
 
     size_t             bytesPerLineForTile (int dx, int dy,
-                         int lx, int ly) const;
+                                            int lx, int ly) const;
 
     Data *             _data;
+
+    OutputStreamMutex*  _streamData;
+    bool                _deleteStream;
+
+    friend class MultiPartOutputFile;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfTiledOutputPart.cpp b/3rdparty/openexr/IlmImf/ImfTiledOutputPart.cpp
new file mode 100644 (file)
index 0000000..cfa0e78
--- /dev/null
@@ -0,0 +1,228 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfTiledOutputPart.h"
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+TiledOutputPart::TiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber)
+{
+    file = multiPartFile.getOutputPart<TiledOutputFile>(partNumber);
+}
+
+const char *
+TiledOutputPart::fileName () const
+{
+    return file->fileName();
+}
+
+const Header &
+TiledOutputPart::header () const
+{
+    return file->header();
+}
+
+void
+TiledOutputPart::setFrameBuffer (const FrameBuffer &frameBuffer)
+{
+    file->setFrameBuffer(frameBuffer);
+}
+
+const FrameBuffer &
+TiledOutputPart::frameBuffer () const
+{
+    return file->frameBuffer();
+}
+
+unsigned int
+TiledOutputPart::tileXSize () const
+{
+    return file->tileXSize();
+}
+
+unsigned int
+TiledOutputPart::tileYSize () const
+{
+    return file->tileYSize();
+}
+
+LevelMode
+TiledOutputPart::levelMode () const
+{
+    return file->levelMode();
+}
+
+LevelRoundingMode
+TiledOutputPart::levelRoundingMode () const
+{
+    return file->levelRoundingMode();
+}
+
+int
+TiledOutputPart::numLevels () const
+{
+    return file->numLevels();
+}
+
+int
+TiledOutputPart::numXLevels () const
+{
+    return file->numXLevels();
+}
+
+int
+TiledOutputPart::numYLevels () const
+{
+    return file->numYLevels();
+}
+
+bool
+TiledOutputPart::isValidLevel (int lx, int ly) const
+{
+    return file->isValidLevel(lx, ly);
+}
+
+int
+TiledOutputPart::levelWidth  (int lx) const
+{
+    return file->levelWidth(lx);
+}
+
+int
+TiledOutputPart::levelHeight (int ly) const
+{
+    return file->levelHeight(ly);
+}
+
+int
+TiledOutputPart::numXTiles (int lx) const
+{
+    return file->numXTiles(lx);
+}
+
+int
+TiledOutputPart::numYTiles (int ly) const
+{
+    return file->numYTiles(ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForLevel (int l) const
+{
+    return file->dataWindowForLevel(l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForLevel (int lx, int ly) const
+{
+    return file->dataWindowForLevel(lx, ly);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForTile (int dx, int dy, int l) const
+{
+    return file->dataWindowForTile(dx, dy, l);
+}
+
+IMATH_NAMESPACE::Box2i
+TiledOutputPart::dataWindowForTile (int dx, int dy, int lx, int ly) const
+{
+    return file->dataWindowForTile(dx, dy, lx, ly);
+}
+
+void
+TiledOutputPart::writeTile  (int dx, int dy, int l)
+{
+    file->writeTile(dx, dy, l);
+}
+
+void
+TiledOutputPart::writeTile  (int dx, int dy, int lx, int ly)
+{
+    file->writeTile(dx, dy, lx, ly);
+}
+
+void
+TiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2, int lx, int ly)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, lx, ly);
+}
+
+void
+TiledOutputPart::writeTiles (int dx1, int dx2, int dy1, int dy2, int l)
+{
+    file->writeTiles(dx1, dx2, dy1, dy2, l);
+}
+
+void
+TiledOutputPart::copyPixels (TiledInputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+TiledOutputPart::copyPixels (InputFile &in)
+{
+    file->copyPixels(in);
+}
+
+void
+TiledOutputPart::copyPixels (TiledInputPart &in)
+{
+    file->copyPixels(in);
+}
+
+void
+TiledOutputPart::copyPixels (InputPart &in)
+{
+    file->copyPixels(in);
+}
+
+
+
+void
+TiledOutputPart::updatePreviewImage (const PreviewRgba newPixels[])
+{
+    file->updatePreviewImage(newPixels);
+}
+
+void
+TiledOutputPart::breakTile  (int dx, int dy, int lx, int ly, int offset, int length, char c)
+{
+    file->breakTile(dx, dy, lx, ly, offset, length, c);
+}
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
diff --git a/3rdparty/openexr/IlmImf/ImfTiledOutputPart.h b/3rdparty/openexr/IlmImf/ImfTiledOutputPart.h
new file mode 100644 (file)
index 0000000..e7b3e2d
--- /dev/null
@@ -0,0 +1,136 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef IMFTILEDOUTPUTPART_H_
+#define IMFTILEDOUTPUTPART_H_
+
+#include "ImfMultiPartOutputFile.h"
+#include "ImfTiledOutputFile.h"
+#include "ImfForward.h"
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//-------------------------------------------------------------------------------
+// class TiledOutputPart:
+//
+// Same interface as TiledOutputFile. Please have a reference to TiledOutputFile.
+//-------------------------------------------------------------------------------
+
+class TiledOutputPart
+{
+    public:
+        IMF_EXPORT
+        TiledOutputPart(MultiPartOutputFile& multiPartFile, int partNumber);
+
+        IMF_EXPORT
+        const char *        fileName () const;
+        IMF_EXPORT
+        const Header &      header () const;
+        IMF_EXPORT
+        void                setFrameBuffer (const FrameBuffer &frameBuffer);
+        IMF_EXPORT
+        const FrameBuffer & frameBuffer () const;
+        IMF_EXPORT
+        unsigned int        tileXSize () const;
+        IMF_EXPORT
+        unsigned int        tileYSize () const;
+        IMF_EXPORT
+        LevelMode           levelMode () const;
+        IMF_EXPORT
+        LevelRoundingMode   levelRoundingMode () const;
+        IMF_EXPORT
+        int                 numLevels () const;
+        IMF_EXPORT
+        int                 numXLevels () const;
+        IMF_EXPORT
+        int                 numYLevels () const;
+        IMF_EXPORT
+        bool                isValidLevel (int lx, int ly) const;
+        IMF_EXPORT
+        int                 levelWidth  (int lx) const;
+        IMF_EXPORT
+        int                 levelHeight (int ly) const;
+        IMF_EXPORT
+        int                 numXTiles (int lx = 0) const;
+        IMF_EXPORT
+        int                 numYTiles (int ly = 0) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int l = 0) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForLevel (int lx, int ly) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                               int l = 0) const;
+        IMF_EXPORT
+        IMATH_NAMESPACE::Box2i        dataWindowForTile (int dx, int dy,
+                                               int lx, int ly) const;
+        IMF_EXPORT
+        void                writeTile  (int dx, int dy, int l = 0);
+        IMF_EXPORT
+        void                writeTile  (int dx, int dy, int lx, int ly);
+        IMF_EXPORT
+        void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                        int lx, int ly);
+        IMF_EXPORT
+        void                writeTiles (int dx1, int dx2, int dy1, int dy2,
+                                        int l = 0);
+        IMF_EXPORT
+        void                copyPixels (TiledInputFile &in);
+        IMF_EXPORT
+        void                copyPixels (InputFile &in);
+        IMF_EXPORT
+        void                copyPixels (TiledInputPart &in);
+        IMF_EXPORT
+        void                copyPixels (InputPart &in);
+        
+        
+        IMF_EXPORT
+        void                updatePreviewImage (const PreviewRgba newPixels[]);
+        IMF_EXPORT
+        void                breakTile  (int dx, int dy,
+                                        int lx, int ly,
+                                        int offset,
+                                        int length,
+                                        char c);
+
+    private:
+        TiledOutputFile* file;
+};
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif /* IMFTILEDOUTPUTPART_H_ */
index 0b20a69..157aec0 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include "IlmThreadMutex.h"
 #include "Iex.h"
 
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 using namespace std;
-using namespace Imath;
+using namespace IMATH_NAMESPACE;
 using namespace RgbaYca;
-using namespace IlmThread;
+using namespace ILMTHREAD_NAMESPACE;
 
 namespace {
 
 void
 insertChannels (Header &header,
-        RgbaChannels rgbaChannels,
-        const char fileName[])
+               RgbaChannels rgbaChannels,
+               const char fileName[])
 {
     ChannelList ch;
 
     if (rgbaChannels & (WRITE_Y | WRITE_C))
     {
-    if (rgbaChannels & WRITE_Y)
-    {
-        ch.insert ("Y", Channel (HALF, 1, 1));
-    }
-
-    if (rgbaChannels & WRITE_C)
-    {
-        THROW (Iex::ArgExc, "Cannot open file \"" << fileName << "\" "
-                "for writing.  Tiled image files do not "
-                "support subsampled chroma channels.");
-    }
+       if (rgbaChannels & WRITE_Y)
+       {
+           ch.insert ("Y", Channel (HALF, 1, 1));
+       }
+
+       if (rgbaChannels & WRITE_C)
+       {
+           THROW (IEX_NAMESPACE::ArgExc, "Cannot open file \"" << fileName << "\" "
+                               "for writing.  Tiled image files do not "
+                               "support subsampled chroma channels.");
+       }
     }
     else
     {
-    if (rgbaChannels & WRITE_R)
-        ch.insert ("R", Channel (HALF, 1, 1));
+       if (rgbaChannels & WRITE_R)
+           ch.insert ("R", Channel (HALF, 1, 1));
 
-    if (rgbaChannels & WRITE_G)
-        ch.insert ("G", Channel (HALF, 1, 1));
+       if (rgbaChannels & WRITE_G)
+           ch.insert ("G", Channel (HALF, 1, 1));
 
-    if (rgbaChannels & WRITE_B)
-        ch.insert ("B", Channel (HALF, 1, 1));
+       if (rgbaChannels & WRITE_B)
+           ch.insert ("B", Channel (HALF, 1, 1));
     }
 
     if (rgbaChannels & WRITE_A)
-    ch.insert ("A", Channel (HALF, 1, 1));
+       ch.insert ("A", Channel (HALF, 1, 1));
 
     header.channels() = ch;
 }
@@ -107,19 +108,19 @@ rgbaChannels (const ChannelList &ch, const string &channelNamePrefix = "")
     int i = 0;
 
     if (ch.findChannel (channelNamePrefix + "R"))
-    i |= WRITE_R;
+       i |= WRITE_R;
 
     if (ch.findChannel (channelNamePrefix + "G"))
-    i |= WRITE_G;
-
+       i |= WRITE_G;
+    
     if (ch.findChannel (channelNamePrefix + "B"))
-    i |= WRITE_B;
+       i |= WRITE_B;
 
     if (ch.findChannel (channelNamePrefix + "A"))
-    i |= WRITE_A;
+       i |= WRITE_A;
 
     if (ch.findChannel (channelNamePrefix + "Y"))
-    i |= WRITE_Y;
+       i |= WRITE_Y;
 
     return RgbaChannels (i);
 }
@@ -129,10 +130,10 @@ string
 prefixFromLayerName (const string &layerName, const Header &header)
 {
     if (layerName.empty())
-    return "";
+       return "";
 
     if (hasMultiView (header) && multiView(header)[0] == layerName)
-    return "";
+       return "";
 
     return layerName + ".";
 }
@@ -144,7 +145,7 @@ ywFromHeader (const Header &header)
     Chromaticities cr;
 
     if (hasChromaticities (header))
-    cr = chromaticities (header);
+       cr = chromaticities (header);
 
     return computeYw (cr);
 }
@@ -159,8 +160,8 @@ class TiledRgbaOutputFile::ToYa: public Mutex
      ToYa (TiledOutputFile &outputFile, RgbaChannels rgbaChannels);
 
      void      setFrameBuffer (const Rgba *base,
-                size_t xStride,
-                size_t yStride);
+                               size_t xStride,
+                               size_t yStride);
 
      void      writeTile (int dx, int dy, int lx, int ly);
 
@@ -179,12 +180,12 @@ class TiledRgbaOutputFile::ToYa: public Mutex
 
 
 TiledRgbaOutputFile::ToYa::ToYa (TiledOutputFile &outputFile,
-                 RgbaChannels rgbaChannels)
+                                RgbaChannels rgbaChannels)
 :
     _outputFile (outputFile)
 {
     _writeA = (rgbaChannels & WRITE_A)? true: false;
-
+    
     const TileDescription &td = outputFile.header().tileDescription();
 
     _tileXSize = td.xSize;
@@ -199,8 +200,8 @@ TiledRgbaOutputFile::ToYa::ToYa (TiledOutputFile &outputFile,
 
 void
 TiledRgbaOutputFile::ToYa::setFrameBuffer (const Rgba *base,
-                       size_t xStride,
-                       size_t yStride)
+                                          size_t xStride,
+                                          size_t yStride)
 {
     _fbBase = base;
     _fbXStride = xStride;
@@ -213,9 +214,9 @@ TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly)
 {
     if (_fbBase == 0)
     {
-    THROW (Iex::ArgExc, "No frame buffer was specified as the "
-                "pixel data source for image file "
-                "\"" << _outputFile.fileName() << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
+                           "pixel data source for image file "
+                           "\"" << _outputFile.fileName() << "\".");
     }
 
     //
@@ -228,10 +229,10 @@ TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly)
 
     for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1)
     {
-    for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
-        _buf[y1][x1] = _fbBase[x * _fbXStride + y * _fbYStride];
+       for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
+           _buf[y1][x1] = _fbBase[x * _fbXStride + y * _fbYStride];
 
-    RGBAtoYCA (_yw, width, _writeA, _buf[y1], _buf[y1]);
+       RGBAtoYCA (_yw, width, _writeA, _buf[y1], _buf[y1]);
     }
 
     //
@@ -241,14 +242,14 @@ TiledRgbaOutputFile::ToYa::writeTile (int dx, int dy, int lx, int ly)
     FrameBuffer fb;
 
     fb.insert ("Y", Slice (HALF,                                  // type
-               (char *) &_buf[-dw.min.y][-dw.min.x].g, // base
-               sizeof (Rgba),                     // xStride
-               sizeof (Rgba) * _tileXSize));      // yStride
+                          (char *) &_buf[-dw.min.y][-dw.min.x].g, // base
+                          sizeof (Rgba),                          // xStride
+                          sizeof (Rgba) * _tileXSize));           // yStride
 
     fb.insert ("A", Slice (HALF,                                  // type
-               (char *) &_buf[-dw.min.y][-dw.min.x].a, // base
-               sizeof (Rgba),                     // xStride
-               sizeof (Rgba) * _tileXSize));      // yStride
+                          (char *) &_buf[-dw.min.y][-dw.min.x].a, // base
+                          sizeof (Rgba),                          // xStride
+                          sizeof (Rgba) * _tileXSize));           // yStride
 
     _outputFile.setFrameBuffer (fb);
     _outputFile.writeTile (dx, dy, lx, ly);
@@ -274,13 +275,13 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
     _outputFile = new TiledOutputFile (name, hd, numThreads);
 
     if (rgbaChannels & WRITE_Y)
-    _toYa = new ToYa (*_outputFile, rgbaChannels);
+       _toYa = new ToYa (*_outputFile, rgbaChannels);
 }
 
 
 
 TiledRgbaOutputFile::TiledRgbaOutputFile
-    (OStream &os,
+    (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
      const Header &header,
      RgbaChannels rgbaChannels,
      int tileXSize,
@@ -298,7 +299,7 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
     _outputFile = new TiledOutputFile (os, hd, numThreads);
 
     if (rgbaChannels & WRITE_Y)
-    _toYa = new ToYa (*_outputFile, rgbaChannels);
+       _toYa = new ToYa (*_outputFile, rgbaChannels);
 }
 
 
@@ -309,11 +310,11 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
      int tileYSize,
      LevelMode mode,
      LevelRoundingMode rmode,
-     const Imath::Box2i &displayWindow,
-     const Imath::Box2i &dataWindow,
+     const IMATH_NAMESPACE::Box2i &displayWindow,
+     const IMATH_NAMESPACE::Box2i &dataWindow,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -323,19 +324,19 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
     _toYa (0)
 {
     Header hd (displayWindow,
-           dataWindow.isEmpty()? displayWindow: dataWindow,
-           pixelAspectRatio,
-           screenWindowCenter,
-           screenWindowWidth,
-           lineOrder,
-           compression);
+              dataWindow.isEmpty()? displayWindow: dataWindow,
+              pixelAspectRatio,
+              screenWindowCenter,
+              screenWindowWidth,
+              lineOrder,
+              compression);
 
     insertChannels (hd, rgbaChannels, name);
     hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
     _outputFile = new TiledOutputFile (name, hd, numThreads);
 
     if (rgbaChannels & WRITE_Y)
-    _toYa = new ToYa (*_outputFile, rgbaChannels);
+       _toYa = new ToYa (*_outputFile, rgbaChannels);
 }
 
 
@@ -349,7 +350,7 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
      LevelRoundingMode rmode,
      RgbaChannels rgbaChannels,
      float pixelAspectRatio,
-     const Imath::V2f screenWindowCenter,
+     const IMATH_NAMESPACE::V2f screenWindowCenter,
      float screenWindowWidth,
      LineOrder lineOrder,
      Compression compression,
@@ -359,19 +360,19 @@ TiledRgbaOutputFile::TiledRgbaOutputFile
     _toYa (0)
 {
     Header hd (width,
-           height,
-           pixelAspectRatio,
-           screenWindowCenter,
-           screenWindowWidth,
-           lineOrder,
-           compression);
+              height,
+              pixelAspectRatio,
+              screenWindowCenter,
+              screenWindowWidth,
+              lineOrder,
+              compression);
 
     insertChannels (hd, rgbaChannels, name);
     hd.setTileDescription (TileDescription (tileXSize, tileYSize, mode, rmode));
     _outputFile = new TiledOutputFile (name, hd, numThreads);
 
     if (rgbaChannels & WRITE_Y)
-    _toYa = new ToYa (*_outputFile, rgbaChannels);
+       _toYa = new ToYa (*_outputFile, rgbaChannels);
 }
 
 
@@ -384,27 +385,27 @@ TiledRgbaOutputFile::~TiledRgbaOutputFile ()
 
 void
 TiledRgbaOutputFile::setFrameBuffer (const Rgba *base,
-                     size_t xStride,
-                     size_t yStride)
+                                    size_t xStride,
+                                    size_t yStride)
 {
     if (_toYa)
     {
-    Lock lock (*_toYa);
-    _toYa->setFrameBuffer (base, xStride, yStride);
+       Lock lock (*_toYa);
+       _toYa->setFrameBuffer (base, xStride, yStride);
     }
     else
     {
-    size_t xs = xStride * sizeof (Rgba);
-    size_t ys = yStride * sizeof (Rgba);
+       size_t xs = xStride * sizeof (Rgba);
+       size_t ys = yStride * sizeof (Rgba);
 
-    FrameBuffer fb;
+       FrameBuffer fb;
 
-    fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys));
-    fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys));
-    fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys));
-    fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys));
+       fb.insert ("R", Slice (HALF, (char *) &base[0].r, xs, ys));
+       fb.insert ("G", Slice (HALF, (char *) &base[0].g, xs, ys));
+       fb.insert ("B", Slice (HALF, (char *) &base[0].b, xs, ys));
+       fb.insert ("A", Slice (HALF, (char *) &base[0].a, xs, ys));
 
-    _outputFile->setFrameBuffer (fb);
+       _outputFile->setFrameBuffer (fb);
     }
 }
 
@@ -423,35 +424,35 @@ TiledRgbaOutputFile::frameBuffer () const
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaOutputFile::displayWindow () const
 {
     return _outputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaOutputFile::dataWindow () const
 {
     return _outputFile->header().dataWindow();
 }
 
 
-float
+float  
 TiledRgbaOutputFile::pixelAspectRatio () const
 {
     return _outputFile->header().pixelAspectRatio();
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f
 TiledRgbaOutputFile::screenWindowCenter () const
 {
     return _outputFile->header().screenWindowCenter();
 }
 
 
-float
+float  
 TiledRgbaOutputFile::screenWindowWidth () const
 {
     return _outputFile->header().screenWindowWidth();
@@ -563,28 +564,28 @@ TiledRgbaOutputFile::numYTiles (int ly) const
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForLevel (int l) const
 {
      return _outputFile->dataWindowForLevel (l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForLevel (int lx, int ly) const
 {
      return _outputFile->dataWindowForLevel (lx, ly);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int l) const
 {
      return _outputFile->dataWindowForTile (dx, dy, l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaOutputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 {
      return _outputFile->dataWindowForTile (dx, dy, lx, ly);
@@ -596,12 +597,12 @@ TiledRgbaOutputFile::writeTile (int dx, int dy, int l)
 {
     if (_toYa)
     {
-    Lock lock (*_toYa);
-    _toYa->writeTile (dx, dy, l, l);
+       Lock lock (*_toYa);
+       _toYa->writeTile (dx, dy, l, l);
     }
     else
     {
-     _outputFile->writeTile (dx, dy, l);
+        _outputFile->writeTile (dx, dy, l);
     }
 }
 
@@ -611,27 +612,27 @@ TiledRgbaOutputFile::writeTile (int dx, int dy, int lx, int ly)
 {
     if (_toYa)
     {
-    Lock lock (*_toYa);
-    _toYa->writeTile (dx, dy, lx, ly);
+       Lock lock (*_toYa);
+       _toYa->writeTile (dx, dy, lx, ly);
     }
     else
     {
-     _outputFile->writeTile (dx, dy, lx, ly);
+        _outputFile->writeTile (dx, dy, lx, ly);
     }
 }
 
 
-void
+void   
 TiledRgbaOutputFile::writeTiles
     (int dxMin, int dxMax, int dyMin, int dyMax, int lx, int ly)
 {
     if (_toYa)
     {
-    Lock lock (*_toYa);
+       Lock lock (*_toYa);
 
         for (int dy = dyMin; dy <= dyMax; dy++)
             for (int dx = dxMin; dx <= dxMax; dx++)
-            _toYa->writeTile (dx, dy, lx, ly);
+               _toYa->writeTile (dx, dy, lx, ly);
     }
     else
     {
@@ -639,7 +640,7 @@ TiledRgbaOutputFile::writeTiles
     }
 }
 
-void
+void   
 TiledRgbaOutputFile::writeTiles
     (int dxMin, int dxMax, int dyMin, int dyMax, int l)
 {
@@ -654,9 +655,9 @@ class TiledRgbaInputFile::FromYa: public Mutex
      FromYa (TiledInputFile &inputFile);
 
      void      setFrameBuffer (Rgba *base,
-                size_t xStride,
-                size_t yStride,
-                const string &channelNamePrefix);
+                               size_t xStride,
+                               size_t yStride,
+                               const string &channelNamePrefix);
 
      void      readTile (int dx, int dy, int lx, int ly);
 
@@ -691,33 +692,33 @@ TiledRgbaInputFile::FromYa::FromYa (TiledInputFile &inputFile)
 
 void
 TiledRgbaInputFile::FromYa::setFrameBuffer (Rgba *base,
-                        size_t xStride,
-                        size_t yStride,
-                        const string &channelNamePrefix)
+                                           size_t xStride,
+                                           size_t yStride,
+                                           const string &channelNamePrefix)
 {
     if (_fbBase == 0)
 {
-    FrameBuffer fb;
-
-    fb.insert (channelNamePrefix + "Y",
-           Slice (HALF,                                // type
-              (char *) &_buf[0][0].g,  // base
-              sizeof (Rgba),           // xStride
-              sizeof (Rgba) * _tileXSize,      // yStride
-              1, 1,                            // sampling
-              0.0,                             // fillValue
-              true, true));                    // tileCoordinates
-
-    fb.insert (channelNamePrefix + "A",
-           Slice (HALF,                                // type
-              (char *) &_buf[0][0].a,  // base
-              sizeof (Rgba),           // xStride
-              sizeof (Rgba) * _tileXSize,      // yStride
-              1, 1,                            // sampling
-              1.0,                             // fillValue
-              true, true));                    // tileCoordinates
-
-    _inputFile.setFrameBuffer (fb);
+       FrameBuffer fb;
+
+       fb.insert (channelNamePrefix + "Y",
+                  Slice (HALF,                         // type
+                         (char *) &_buf[0][0].g,       // base
+                         sizeof (Rgba),                // xStride
+                         sizeof (Rgba) * _tileXSize,   // yStride
+                         1, 1,                         // sampling
+                         0.0,                          // fillValue
+                         true, true));                 // tileCoordinates
+
+       fb.insert (channelNamePrefix + "A",
+                  Slice (HALF,                         // type
+                         (char *) &_buf[0][0].a,       // base
+                         sizeof (Rgba),                // xStride
+                         sizeof (Rgba) * _tileXSize,   // yStride
+                         1, 1,                         // sampling
+                         1.0,                          // fillValue
+                         true, true));                 // tileCoordinates
+
+       _inputFile.setFrameBuffer (fb);
     }
 
     _fbBase = base;
@@ -731,15 +732,15 @@ TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly)
 {
     if (_fbBase == 0)
     {
-    THROW (Iex::ArgExc, "No frame buffer was specified as the "
-                "pixel data destination for image file "
-                "\"" << _inputFile.fileName() << "\".");
+       THROW (IEX_NAMESPACE::ArgExc, "No frame buffer was specified as the "
+                           "pixel data destination for image file "
+                           "\"" << _inputFile.fileName() << "\".");
     }
 
     //
     // Read the tile requested by the caller into _buf.
     //
-
+    
     _inputFile.readTile (dx, dy, lx, ly);
 
     //
@@ -752,18 +753,18 @@ TiledRgbaInputFile::FromYa::readTile (int dx, int dy, int lx, int ly)
 
     for (int y = dw.min.y, y1 = 0; y <= dw.max.y; ++y, ++y1)
     {
-    for (int x1 = 0; x1 < width; ++x1)
-    {
-        _buf[y1][x1].r = 0;
-        _buf[y1][x1].b = 0;
-    }
-
-    YCAtoRGBA (_yw, width, _buf[y1], _buf[y1]);
-
-    for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
-    {
-        _fbBase[x * _fbXStride + y * _fbYStride] = _buf[y1][x1];
-    }
+       for (int x1 = 0; x1 < width; ++x1)
+       {
+           _buf[y1][x1].r = 0;
+           _buf[y1][x1].b = 0;
+       }
+
+       YCAtoRGBA (_yw, width, _buf[y1], _buf[y1]);
+
+       for (int x = dw.min.x, x1 = 0; x <= dw.max.x; ++x, ++x1)
+       {
+           _fbBase[x * _fbXStride + y * _fbYStride] = _buf[y1][x1];
+       }
     }
 }
 
@@ -774,43 +775,43 @@ TiledRgbaInputFile::TiledRgbaInputFile (const char name[], int numThreads):
     _channelNamePrefix ("")
 {
     if (channels() & WRITE_Y)
-    _fromYa = new FromYa (*_inputFile);
+       _fromYa = new FromYa (*_inputFile);
 }
 
 
-TiledRgbaInputFile::TiledRgbaInputFile (IStream &is, int numThreads):
+TiledRgbaInputFile::TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads):
     _inputFile (new TiledInputFile (is, numThreads)),
     _fromYa (0),
     _channelNamePrefix ("")
 {
     if (channels() & WRITE_Y)
-    _fromYa = new FromYa (*_inputFile);
+       _fromYa = new FromYa (*_inputFile);
 }
 
 
 TiledRgbaInputFile::TiledRgbaInputFile (const char name[],
-                    const string &layerName,
-                    int numThreads)
+                                       const string &layerName,
+                                       int numThreads)
 :
     _inputFile (new TiledInputFile (name, numThreads)),
     _fromYa (0),
     _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
 {
     if (channels() & WRITE_Y)
-    _fromYa = new FromYa (*_inputFile);
+       _fromYa = new FromYa (*_inputFile);
 }
 
 
-TiledRgbaInputFile::TiledRgbaInputFile (IStream &is,
-                    const string &layerName,
-                    int numThreads)
+TiledRgbaInputFile::TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                                       const string &layerName,
+                                       int numThreads)
 :
     _inputFile (new TiledInputFile (is, numThreads)),
     _fromYa (0),
     _channelNamePrefix (prefixFromLayerName (layerName, _inputFile->header()))
 {
     if (channels() & WRITE_Y)
-    _fromYa = new FromYa (*_inputFile);
+       _fromYa = new FromYa (*_inputFile);
 }
 
 
@@ -821,64 +822,64 @@ TiledRgbaInputFile::~TiledRgbaInputFile ()
 }
 
 
-void
+void   
 TiledRgbaInputFile::setFrameBuffer (Rgba *base, size_t xStride, size_t yStride)
 {
     if (_fromYa)
     {
-    Lock lock (*_fromYa);
-    _fromYa->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
+       Lock lock (*_fromYa);
+       _fromYa->setFrameBuffer (base, xStride, yStride, _channelNamePrefix);
     }
     else
     {
-    size_t xs = xStride * sizeof (Rgba);
-    size_t ys = yStride * sizeof (Rgba);
-
-    FrameBuffer fb;
-
-    fb.insert (_channelNamePrefix + "R",
-           Slice (HALF,
-                   (char *) &base[0].r,
-                   xs, ys,
-                   1, 1,       // xSampling, ySampling
-                   0.0));      // fillValue
-
-    fb.insert (_channelNamePrefix + "G",
-           Slice (HALF,
-                   (char *) &base[0].g,
-                   xs, ys,
-                   1, 1,       // xSampling, ySampling
-                   0.0));      // fillValue
-
-    fb.insert (_channelNamePrefix + "B",
-           Slice (HALF,
-                   (char *) &base[0].b,
-                   xs, ys,
-                   1, 1,       // xSampling, ySampling
-                   0.0));      // fillValue
-
-    fb.insert (_channelNamePrefix + "A",
-           Slice (HALF,
-                   (char *) &base[0].a,
-                   xs, ys,
-                   1, 1,       // xSampling, ySampling
-                   1.0));      // fillValue
-
-    _inputFile->setFrameBuffer (fb);
+       size_t xs = xStride * sizeof (Rgba);
+       size_t ys = yStride * sizeof (Rgba);
+
+       FrameBuffer fb;
+
+       fb.insert (_channelNamePrefix + "R",
+                  Slice (HALF,
+                              (char *) &base[0].r,
+                              xs, ys,
+                              1, 1,    // xSampling, ySampling
+                              0.0));   // fillValue
+
+       fb.insert (_channelNamePrefix + "G",
+                  Slice (HALF,
+                              (char *) &base[0].g,
+                              xs, ys,
+                              1, 1,    // xSampling, ySampling
+                              0.0));   // fillValue
+
+       fb.insert (_channelNamePrefix + "B",
+                  Slice (HALF,
+                              (char *) &base[0].b,
+                              xs, ys,
+                              1, 1,    // xSampling, ySampling
+                              0.0));   // fillValue
+
+       fb.insert (_channelNamePrefix + "A",
+                  Slice (HALF,
+                              (char *) &base[0].a,
+                              xs, ys,
+                              1, 1,    // xSampling, ySampling
+                              1.0));   // fillValue
+
+       _inputFile->setFrameBuffer (fb);
     }
 }
 
 
-void
+void           
 TiledRgbaInputFile::setLayerName (const std::string &layerName)
 {
     delete _fromYa;
     _fromYa = 0;
-
+    
     _channelNamePrefix = prefixFromLayerName (layerName, _inputFile->header());
 
     if (channels() & WRITE_Y)
-    _fromYa = new FromYa (*_inputFile);
+       _fromYa = new FromYa (*_inputFile);
 
     FrameBuffer fb;
     _inputFile->setFrameBuffer (fb);
@@ -899,42 +900,42 @@ TiledRgbaInputFile::fileName () const
 }
 
 
-const FrameBuffer &
+const FrameBuffer &    
 TiledRgbaInputFile::frameBuffer () const
 {
     return _inputFile->frameBuffer();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaInputFile::displayWindow () const
 {
     return _inputFile->header().displayWindow();
 }
 
 
-const Imath::Box2i &
+const IMATH_NAMESPACE::Box2i &
 TiledRgbaInputFile::dataWindow () const
 {
     return _inputFile->header().dataWindow();
 }
 
 
-float
+float  
 TiledRgbaInputFile::pixelAspectRatio () const
 {
     return _inputFile->header().pixelAspectRatio();
 }
 
 
-const Imath::V2f
+const IMATH_NAMESPACE::V2f     
 TiledRgbaInputFile::screenWindowCenter () const
 {
     return _inputFile->header().screenWindowCenter();
 }
 
 
-float
+float  
 TiledRgbaInputFile::screenWindowWidth () const
 {
     return _inputFile->header().screenWindowWidth();
@@ -955,7 +956,7 @@ TiledRgbaInputFile::compression () const
 }
 
 
-RgbaChannels
+RgbaChannels   
 TiledRgbaInputFile::channels () const
 {
     return rgbaChannels (_inputFile->header().channels(), _channelNamePrefix);
@@ -1060,28 +1061,28 @@ TiledRgbaInputFile::numYTiles (int ly) const
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForLevel (int l) const
 {
      return _inputFile->dataWindowForLevel (l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForLevel (int lx, int ly) const
 {
      return _inputFile->dataWindowForLevel (lx, ly);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int l) const
 {
      return _inputFile->dataWindowForTile (dx, dy, l);
 }
 
 
-Imath::Box2i
+IMATH_NAMESPACE::Box2i
 TiledRgbaInputFile::dataWindowForTile (int dx, int dy, int lx, int ly) const
 {
      return _inputFile->dataWindowForTile (dx, dy, lx, ly);
@@ -1093,12 +1094,12 @@ TiledRgbaInputFile::readTile (int dx, int dy, int l)
 {
     if (_fromYa)
     {
-    Lock lock (*_fromYa);
-    _fromYa->readTile (dx, dy, l, l);
+       Lock lock (*_fromYa);
+       _fromYa->readTile (dx, dy, l, l);
     }
     else
     {
-     _inputFile->readTile (dx, dy, l);
+        _inputFile->readTile (dx, dy, l);
     }
 }
 
@@ -1108,27 +1109,27 @@ TiledRgbaInputFile::readTile (int dx, int dy, int lx, int ly)
 {
     if (_fromYa)
     {
-    Lock lock (*_fromYa);
-    _fromYa->readTile (dx, dy, lx, ly);
+       Lock lock (*_fromYa);
+       _fromYa->readTile (dx, dy, lx, ly);
     }
     else
     {
-     _inputFile->readTile (dx, dy, lx, ly);
+        _inputFile->readTile (dx, dy, lx, ly);
     }
 }
 
 
-void
+void   
 TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
                                int lx, int ly)
 {
     if (_fromYa)
     {
-    Lock lock (*_fromYa);
+       Lock lock (*_fromYa);
 
         for (int dy = dyMin; dy <= dyMax; dy++)
             for (int dx = dxMin; dx <= dxMax; dx++)
-            _fromYa->readTile (dx, dy, lx, ly);
+               _fromYa->readTile (dx, dy, lx, ly);
     }
     else
     {
@@ -1136,7 +1137,7 @@ TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
     }
 }
 
-void
+void   
 TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
                                int l)
 {
@@ -1144,19 +1145,19 @@ TiledRgbaInputFile::readTiles (int dxMin, int dxMax, int dyMin, int dyMax,
 }
 
 
-void
+void           
 TiledRgbaOutputFile::updatePreviewImage (const PreviewRgba newPixels[])
 {
     _outputFile->updatePreviewImage (newPixels);
 }
 
 
-void
+void   
 TiledRgbaOutputFile::breakTile  (int dx, int dy, int lx, int ly,
-                 int offset, int length, char c)
+                                int offset, int length, char c)
 {
     _outputFile->breakTile (dx, dy, lx, ly, offset, length, c);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index a23d159..e12faab 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfHeader.h>
-#include <ImfFrameBuffer.h>
+#include "ImfHeader.h"
+#include "ImfFrameBuffer.h"
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "half.h"
-#include <ImfTileDescription.h>
-#include <ImfRgba.h>
-#include <ImfThreading.h>
+#include "ImfTileDescription.h"
+#include "ImfRgba.h"
+#include "ImfThreading.h"
 #include <string>
+#include "ImfNamespace.h"
+#include "ImfForward.h"
 
-namespace Imf {
 
-class TiledOutputFile;
-class TiledInputFile;
-struct PreviewRgba;
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //
@@ -78,13 +77,14 @@ class TiledRgbaOutputFile
     // constructor.
     //---------------------------------------------------
 
+    IMF_EXPORT
     TiledRgbaOutputFile (const char name[],
-             const Header &header,
-             RgbaChannels rgbaChannels,
-             int tileXSize,
-             int tileYSize,
-             LevelMode mode,
-             LevelRoundingMode rmode = ROUND_DOWN,
+                        const Header &header,
+                        RgbaChannels rgbaChannels,
+                        int tileXSize,
+                        int tileYSize,
+                        LevelMode mode,
+                        LevelRoundingMode rmode = ROUND_DOWN,
                          int numThreads = globalThreadCount ());
 
 
@@ -97,13 +97,14 @@ class TiledRgbaOutputFile
     // corresponding files.
     //---------------------------------------------------
 
-    TiledRgbaOutputFile (OStream &os,
-             const Header &header,
-             RgbaChannels rgbaChannels,
-             int tileXSize,
-             int tileYSize,
-             LevelMode mode,
-             LevelRoundingMode rmode = ROUND_DOWN,
+    IMF_EXPORT
+    TiledRgbaOutputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os,
+                        const Header &header,
+                        RgbaChannels rgbaChannels,
+                        int tileXSize,
+                        int tileYSize,
+                        LevelMode mode,
+                        LevelRoundingMode rmode = ROUND_DOWN,
                          int numThreads = globalThreadCount ());
 
 
@@ -113,20 +114,21 @@ class TiledRgbaOutputFile
     // "same as displayWindow")
     //------------------------------------------------------
 
+    IMF_EXPORT
     TiledRgbaOutputFile (const char name[],
-             int tileXSize,
-             int tileYSize,
-             LevelMode mode,
-             LevelRoundingMode rmode,
-             const Imath::Box2i &displayWindow,
-             const Imath::Box2i &dataWindow = Imath::Box2i(),
-             RgbaChannels rgbaChannels = WRITE_RGBA,
-             float pixelAspectRatio = 1,
-             const Imath::V2f screenWindowCenter =
-                            Imath::V2f (0, 0),
-             float screenWindowWidth = 1,
-             LineOrder lineOrder = INCREASING_Y,
-             Compression compression = ZIP_COMPRESSION,
+                        int tileXSize,
+                        int tileYSize,
+                        LevelMode mode,
+                        LevelRoundingMode rmode,
+                        const IMATH_NAMESPACE::Box2i &displayWindow,
+                        const IMATH_NAMESPACE::Box2i &dataWindow = IMATH_NAMESPACE::Box2i(),
+                        RgbaChannels rgbaChannels = WRITE_RGBA,
+                        float pixelAspectRatio = 1,
+                        const IMATH_NAMESPACE::V2f screenWindowCenter =
+                                                   IMATH_NAMESPACE::V2f (0, 0),
+                        float screenWindowWidth = 1,
+                        LineOrder lineOrder = INCREASING_Y,
+                        Compression compression = ZIP_COMPRESSION,
                          int numThreads = globalThreadCount ());
 
 
@@ -136,23 +138,24 @@ class TiledRgbaOutputFile
     // Box2i (V2i (0, 0), V2i (width - 1, height -1))
     //-----------------------------------------------
 
+    IMF_EXPORT
     TiledRgbaOutputFile (const char name[],
-             int width,
-             int height,
-             int tileXSize,
-             int tileYSize,
-             LevelMode mode,
-             LevelRoundingMode rmode = ROUND_DOWN,
-             RgbaChannels rgbaChannels = WRITE_RGBA,
-             float pixelAspectRatio = 1,
-             const Imath::V2f screenWindowCenter =
-                            Imath::V2f (0, 0),
-             float screenWindowWidth = 1,
-             LineOrder lineOrder = INCREASING_Y,
-             Compression compression = ZIP_COMPRESSION,
+                        int width,
+                        int height,
+                        int tileXSize,
+                        int tileYSize,
+                        LevelMode mode,
+                        LevelRoundingMode rmode = ROUND_DOWN,
+                        RgbaChannels rgbaChannels = WRITE_RGBA,
+                        float pixelAspectRatio = 1,
+                        const IMATH_NAMESPACE::V2f screenWindowCenter =
+                                                   IMATH_NAMESPACE::V2f (0, 0),
+                        float screenWindowWidth = 1,
+                        LineOrder lineOrder = INCREASING_Y,
+                        Compression compression = ZIP_COMPRESSION,
                          int numThreads = globalThreadCount ());
 
-
+    IMF_EXPORT
     virtual ~TiledRgbaOutputFile ();
 
 
@@ -164,23 +167,34 @@ class TiledRgbaOutputFile
     //
     //------------------------------------------------
 
+    IMF_EXPORT
     void               setFrameBuffer (const Rgba *base,
-                    size_t xStride,
-                    size_t yStride);
+                                       size_t xStride,
+                                       size_t yStride);
 
     //--------------------------
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &             header () const;
+    IMF_EXPORT
     const FrameBuffer &                frameBuffer () const;
-    const Imath::Box2i &       displayWindow () const;
-    const Imath::Box2i &       dataWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     displayWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     dataWindow () const;
+    IMF_EXPORT
     float                      pixelAspectRatio () const;
-    const Imath::V2f           screenWindowCenter () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::V2f         screenWindowCenter () const;
+    IMF_EXPORT
     float                      screenWindowWidth () const;
+    IMF_EXPORT
     LineOrder                  lineOrder () const;
+    IMF_EXPORT
     Compression                        compression () const;
+    IMF_EXPORT
     RgbaChannels               channels () const;
 
 
@@ -188,30 +202,46 @@ class TiledRgbaOutputFile
     // Utility functions (same as in Imf::TiledOutputFile)
     //----------------------------------------------------
 
+    IMF_EXPORT
     unsigned int       tileXSize () const;
+    IMF_EXPORT
     unsigned int       tileYSize () const;
+    IMF_EXPORT
     LevelMode          levelMode () const;
+    IMF_EXPORT
     LevelRoundingMode  levelRoundingMode () const;
 
+    IMF_EXPORT
     int                        numLevels () const;
+    IMF_EXPORT
     int                        numXLevels () const;
+    IMF_EXPORT
     int                        numYLevels () const;
+    IMF_EXPORT
     bool               isValidLevel (int lx, int ly) const;
 
+    IMF_EXPORT
     int                        levelWidth  (int lx) const;
+    IMF_EXPORT
     int                        levelHeight (int ly) const;
 
+    IMF_EXPORT
     int                        numXTiles (int lx = 0) const;
+    IMF_EXPORT
     int                        numYTiles (int ly = 0) const;
 
-    Imath::Box2i       dataWindowForLevel (int l = 0) const;
-    Imath::Box2i       dataWindowForLevel (int lx, int ly) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int lx, int ly) const;
 
-    Imath::Box2i       dataWindowForTile (int dx, int dy,
-                       int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy,
+                                          int l = 0) const;
 
-    Imath::Box2i       dataWindowForTile (int dx, int dy,
-                       int lx, int ly) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy,
+                                          int lx, int ly) const;
 
     //------------------------------------------------------------------
     // Write pixel data:
@@ -241,12 +271,16 @@ class TiledRgbaOutputFile
     //
     //------------------------------------------------------------------
 
+    IMF_EXPORT
     void               writeTile (int dx, int dy, int l = 0);
+    IMF_EXPORT
     void               writeTile (int dx, int dy, int lx, int ly);
 
+    IMF_EXPORT
     void               writeTiles (int dxMin, int dxMax, int dyMin, int dyMax,
                                     int lx, int ly);
 
+    IMF_EXPORT
     void               writeTiles (int dxMin, int dxMax, int dyMin, int dyMax,
                                     int l = 0);
 
@@ -255,6 +289,7 @@ class TiledRgbaOutputFile
     // Update the preview image (see Imf::TiledOutputFile::updatePreviewImage())
     // -------------------------------------------------------------------------
 
+    IMF_EXPORT
     void               updatePreviewImage (const PreviewRgba[]);
 
 
@@ -269,18 +304,19 @@ class TiledRgbaOutputFile
     //
     //------------------------------------------------
 
+    IMF_EXPORT
     void               breakTile  (int dx, int dy,
-                    int lx, int ly,
-                    int offset,
-                    int length,
-                    char c);
+                                   int lx, int ly,
+                                   int offset,
+                                   int length,
+                                   char c);
   private:
 
     //
     // Copy constructor and assignment are not implemented
     //
 
-    TiledRgbaOutputFile (const TiledRgbaOutputFile &);
+    TiledRgbaOutputFile (const TiledRgbaOutputFile &); 
     TiledRgbaOutputFile & operator = (const TiledRgbaOutputFile &);
 
     class ToYa;
@@ -306,6 +342,7 @@ class TiledRgbaInputFile
     // files.
     //--------------------------------------------------------
 
+    IMF_EXPORT
     TiledRgbaInputFile (const char name[],
                         int numThreads = globalThreadCount ());
 
@@ -319,7 +356,8 @@ class TiledRgbaInputFile
     // corresponding files.
     //-------------------------------------------------------
 
-    TiledRgbaInputFile (IStream &is, int numThreads = globalThreadCount ());
+    IMF_EXPORT
+    TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int numThreads = globalThreadCount ());
 
 
     //------------------------------------------------------------
@@ -328,18 +366,21 @@ class TiledRgbaInputFile
     // expected to be layerName.R, layerName.G, etc.
     //------------------------------------------------------------
 
+    IMF_EXPORT
     TiledRgbaInputFile (const char name[],
-                const std::string &layerName,
-                int numThreads = globalThreadCount());
+                       const std::string &layerName,
+                       int numThreads = globalThreadCount());
 
-    TiledRgbaInputFile (IStream &is,
-                const std::string &layerName,
-                int numThreads = globalThreadCount());
+    IMF_EXPORT
+    TiledRgbaInputFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,
+                       const std::string &layerName,
+                       int numThreads = globalThreadCount());
 
     //-----------
     // Destructor
     //-----------
 
+    IMF_EXPORT
     virtual ~TiledRgbaInputFile ();
 
 
@@ -351,9 +392,10 @@ class TiledRgbaInputFile
     //
     //-----------------------------------------------------
 
+    IMF_EXPORT
     void                       setFrameBuffer (Rgba *base,
-                        size_t xStride,
-                        size_t yStride);
+                                               size_t xStride,
+                                               size_t yStride);
 
     //-------------------------------------------------------------------
     // Switch to a different layer -- subsequent calls to readTile()
@@ -362,6 +404,7 @@ class TiledRgbaInputFile
     // at least once before the next call to readTile() or readTiles().
     //-------------------------------------------------------------------
 
+    IMF_EXPORT
     void                       setLayerName (const std::string &layerName);
 
 
@@ -369,23 +412,36 @@ class TiledRgbaInputFile
     // Access to the file header
     //--------------------------
 
+    IMF_EXPORT
     const Header &             header () const;
+    IMF_EXPORT
     const FrameBuffer &                frameBuffer () const;
-    const Imath::Box2i &       displayWindow () const;
-    const Imath::Box2i &       dataWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     displayWindow () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::Box2i &     dataWindow () const;
+    IMF_EXPORT
     float                      pixelAspectRatio () const;
-    const Imath::V2f           screenWindowCenter () const;
+    IMF_EXPORT
+    const IMATH_NAMESPACE::V2f         screenWindowCenter () const;
+    IMF_EXPORT
     float                      screenWindowWidth () const;
+    IMF_EXPORT
     LineOrder                  lineOrder () const;
+    IMF_EXPORT
     Compression                        compression () const;
+    IMF_EXPORT
     RgbaChannels               channels () const;
+    IMF_EXPORT
     const char *                fileName () const;
+    IMF_EXPORT
     bool                       isComplete () const;
 
     //----------------------------------
     // Access to the file format version
     //----------------------------------
 
+    IMF_EXPORT
     int                                version () const;
 
 
@@ -393,31 +449,47 @@ class TiledRgbaInputFile
     // Utility functions (same as in Imf::TiledInputFile)
     //---------------------------------------------------
 
+    IMF_EXPORT
     unsigned int       tileXSize () const;
+    IMF_EXPORT
     unsigned int       tileYSize () const;
+    IMF_EXPORT
     LevelMode          levelMode () const;
+    IMF_EXPORT
     LevelRoundingMode  levelRoundingMode () const;
 
+    IMF_EXPORT
     int                        numLevels () const;
+    IMF_EXPORT
     int                        numXLevels () const;
+    IMF_EXPORT
     int                        numYLevels () const;
+    IMF_EXPORT
     bool               isValidLevel (int lx, int ly) const;
 
+    IMF_EXPORT
     int                        levelWidth  (int lx) const;
+    IMF_EXPORT
     int                        levelHeight (int ly) const;
 
+    IMF_EXPORT
     int                        numXTiles (int lx = 0) const;
+    IMF_EXPORT
     int                        numYTiles (int ly = 0) const;
 
-    Imath::Box2i       dataWindowForLevel (int l = 0) const;
-    Imath::Box2i       dataWindowForLevel (int lx, int ly) const;
-
-    Imath::Box2i       dataWindowForTile (int dx, int dy,
-                       int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int l = 0) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForLevel (int lx, int ly) const;
 
-    Imath::Box2i       dataWindowForTile (int dx, int dy,
-                       int lx, int ly) const;
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy,
+                                          int l = 0) const;
 
+    IMF_EXPORT
+    IMATH_NAMESPACE::Box2i     dataWindowForTile (int dx, int dy,
+                                          int lx, int ly) const;
+                                          
 
     //----------------------------------------------------------------
     // Read pixel data:
@@ -448,12 +520,16 @@ class TiledRgbaInputFile
     //
     //----------------------------------------------------------------
 
+    IMF_EXPORT
     void               readTile (int dx, int dy, int l = 0);
+    IMF_EXPORT
     void               readTile (int dx, int dy, int lx, int ly);
 
+    IMF_EXPORT
     void               readTiles (int dxMin, int dxMax,
                                    int dyMin, int dyMax, int lx, int ly);
 
+    IMF_EXPORT
     void               readTiles (int dxMin, int dxMax,
                                    int dyMin, int dyMax, int l = 0);
 
@@ -474,6 +550,10 @@ class TiledRgbaInputFile
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index fd4a7ed..88b9d1c 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 //
 //     class TimeCode
-//
+//     
 //-----------------------------------------------------------------------------
 
 #include <ImfTimeCode.h>
 #include "Iex.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+   
 TimeCode::TimeCode ()
 {
     _time = 0;
@@ -118,6 +119,21 @@ TimeCode::operator = (const TimeCode &other)
     return *this;
 }
 
+    
+bool
+TimeCode::operator == (const TimeCode & c) const
+{
+    return (_time == c._time && _user == c._user);
+}
+
+
+bool
+TimeCode::operator != (const TimeCode & c) const
+{
+    return (_time != c._time || _user != c._user);
+}
+    
+    
 
 namespace {
 
@@ -169,8 +185,8 @@ void
 TimeCode::setHours (int value)
 {
     if (value < 0 || value > 23)
-    throw Iex::ArgExc ("Cannot set hours field in time code. "
-               "New value is out of range.");
+       throw IEX_NAMESPACE::ArgExc ("Cannot set hours field in time code. "
+                          "New value is out of range.");
 
     setBitField (_time, 24, 29, binaryToBcd (value));
 }
@@ -187,8 +203,8 @@ void
 TimeCode::setMinutes (int value)
 {
     if (value < 0 || value > 59)
-    throw Iex::ArgExc ("Cannot set minutes field in time code. "
-               "New value is out of range.");
+       throw IEX_NAMESPACE::ArgExc ("Cannot set minutes field in time code. "
+                          "New value is out of range.");
 
     setBitField (_time, 16, 22, binaryToBcd (value));
 }
@@ -205,8 +221,8 @@ void
 TimeCode::setSeconds (int value)
 {
     if (value < 0 || value > 59)
-    throw Iex::ArgExc ("Cannot set seconds field in time code. "
-               "New value is out of range.");
+       throw IEX_NAMESPACE::ArgExc ("Cannot set seconds field in time code. "
+                          "New value is out of range.");
 
     setBitField (_time, 8, 14, binaryToBcd (value));
 }
@@ -223,8 +239,8 @@ void
 TimeCode::setFrame (int value)
 {
     if (value < 0 || value > 59)
-    throw Iex::ArgExc ("Cannot set frame field in time code. "
-               "New value is out of range.");
+       throw IEX_NAMESPACE::ArgExc ("Cannot set frame field in time code. "
+                          "New value is out of range.");
 
     setBitField (_time, 0, 5, binaryToBcd (value));
 }
@@ -233,7 +249,7 @@ TimeCode::setFrame (int value)
 bool
 TimeCode::dropFrame () const
 {
-    return bool (bitField (_time, 6, 6));
+    return !!bitField (_time, 6, 6);
 }
 
 
@@ -247,7 +263,7 @@ TimeCode::setDropFrame (bool value)
 bool
 TimeCode::colorFrame () const
 {
-    return bool (bitField (_time, 7, 7));
+    return !!bitField (_time, 7, 7);
 }
 
 
@@ -261,7 +277,7 @@ TimeCode::setColorFrame (bool value)
 bool
 TimeCode::fieldPhase () const
 {
-    return bool (bitField (_time, 15, 15));
+    return !!bitField (_time, 15, 15);
 }
 
 
@@ -275,7 +291,7 @@ TimeCode::setFieldPhase (bool value)
 bool
 TimeCode::bgf0 () const
 {
-    return bool (bitField (_time, 23, 23));
+    return !!bitField (_time, 23, 23);
 }
 
 
@@ -289,7 +305,7 @@ TimeCode::setBgf0 (bool value)
 bool
 TimeCode::bgf1 () const
 {
-    return bool (bitField (_time, 30, 30));
+    return!!bitField (_time, 30, 30);
 }
 
 
@@ -303,7 +319,7 @@ TimeCode::setBgf1 (bool value)
 bool
 TimeCode::bgf2 () const
 {
-    return bool (bitField (_time, 31, 31));
+    return !!bitField (_time, 31, 31);
 }
 
 
@@ -318,8 +334,8 @@ int
 TimeCode::binaryGroup (int group) const
 {
     if (group < 1 || group > 8)
-    throw Iex::ArgExc ("Cannot extract binary group from time code "
-                   "user data.  Group number is out of range.");
+       throw IEX_NAMESPACE::ArgExc ("Cannot extract binary group from time code "
+                          "user data.  Group number is out of range.");
 
     int minBit = 4 * (group - 1);
     int maxBit = minBit + 3;
@@ -331,8 +347,8 @@ void
 TimeCode::setBinaryGroup (int group, int value)
 {
     if (group < 1 || group > 8)
-    throw Iex::ArgExc ("Cannot extract binary group from time code "
-                   "user data.  Group number is out of range.");
+       throw IEX_NAMESPACE::ArgExc ("Cannot extract binary group from time code "
+                          "user data.  Group number is out of range.");
 
     int minBit = 4 * (group - 1);
     int maxBit = minBit + 3;
@@ -345,24 +361,24 @@ TimeCode::timeAndFlags (Packing packing) const
 {
     if (packing == TV50_PACKING)
     {
-    unsigned int t = _time;
+       unsigned int t = _time;
 
-    t &= ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31));
+       t &= ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31));
 
-    t |= ((unsigned int) bgf0() << 15);
-    t |= ((unsigned int) bgf2() << 23);
-    t |= ((unsigned int) bgf1() << 30);
-    t |= ((unsigned int) fieldPhase() << 31);
+       t |= ((unsigned int) bgf0() << 15);
+       t |= ((unsigned int) bgf2() << 23);
+       t |= ((unsigned int) bgf1() << 30);
+       t |= ((unsigned int) fieldPhase() << 31);
 
-    return t;
+       return t;
     }
     if (packing == FILM24_PACKING)
     {
-    return _time & ~((1 << 6) | (1 << 7));
+       return _time & ~((1 << 6) | (1 << 7));
     }
     else // packing == TV60_PACKING
     {
-    return _time;
+       return _time;
     }
 }
 
@@ -372,28 +388,28 @@ TimeCode::setTimeAndFlags (unsigned int value, Packing packing)
 {
     if (packing == TV50_PACKING)
     {
-    _time = value &
-         ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31));
+       _time = value &
+                ~((1 << 6) | (1 << 15) | (1 << 23) | (1 << 30) | (1 << 31));
 
-    if (value & (1 << 15))
-        setBgf0 (true);
+       if (value & (1 << 15))
+           setBgf0 (true);
 
-    if (value & (1 << 23))
-        setBgf2 (true);
+       if (value & (1 << 23))
+           setBgf2 (true);
 
-    if (value & (1 << 30))
-        setBgf1 (true);
+       if (value & (1 << 30))
+           setBgf1 (true);
 
-    if (value & (1 << 31))
-        setFieldPhase (true);
+       if (value & (1 << 31))
+           setFieldPhase (true);
     }
     else if (packing == FILM24_PACKING)
     {
-    _time = value & ~((1 << 6) | (1 << 7));
+       _time = value & ~((1 << 6) | (1 << 7));
     }
     else // packing == TV60_PACKING
     {
-    _time = value;
+       _time = value;
     }
 }
 
@@ -412,4 +428,4 @@ TimeCode::setUserData (unsigned int value)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index 1f3ce8a..1e3a464 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #ifndef INCLUDED_IMF_TIME_CODE_H
 #define INCLUDED_IMF_TIME_CODE_H
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
+
 //-----------------------------------------------------------------------------
 //
 //     class TimeCode
-//
+//     
 //     A TimeCode object stores time and control codes as described
 //     in SMPTE standard 12M-1999.  A TimeCode object contains the
 //     following fields:
 //
 //-----------------------------------------------------------------------------
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
+   
 class TimeCode
 {
   public:
@@ -123,9 +126,9 @@ class TimeCode
 
     enum Packing
     {
-    TV60_PACKING,              // packing for 60-field television
-    TV50_PACKING,              // packing for 50-field television
-    FILM24_PACKING             // packing for 24-frame film
+       TV60_PACKING,           // packing for 60-field television
+       TV50_PACKING,           // packing for 50-field television
+       FILM24_PACKING          // packing for 24-frame film
     };
 
 
@@ -133,33 +136,38 @@ class TimeCode
     // Constructors and assignment operator
     //-------------------------------------
 
+    IMF_EXPORT
     TimeCode ();  // all fields set to 0 or false
 
+    IMF_EXPORT
     TimeCode (int hours,
-          int minutes,
-          int seconds,
-          int frame,
-          bool dropFrame = false,
-          bool colorFrame = false,
-          bool fieldPhase = false,
-          bool bgf0 = false,
-          bool bgf1 = false,
-          bool bgf2 = false,
-          int binaryGroup1 = 0,
-          int binaryGroup2 = 0,
-          int binaryGroup3 = 0,
-          int binaryGroup4 = 0,
-          int binaryGroup5 = 0,
-          int binaryGroup6 = 0,
-          int binaryGroup7 = 0,
-          int binaryGroup8 = 0);
-
+             int minutes,
+             int seconds,
+             int frame,
+             bool dropFrame = false,
+             bool colorFrame = false,
+             bool fieldPhase = false,
+             bool bgf0 = false,
+             bool bgf1 = false,
+             bool bgf2 = false,
+             int binaryGroup1 = 0,
+             int binaryGroup2 = 0,
+             int binaryGroup3 = 0,
+             int binaryGroup4 = 0,
+             int binaryGroup5 = 0,
+             int binaryGroup6 = 0,
+             int binaryGroup7 = 0,
+             int binaryGroup8 = 0);
+
+    IMF_EXPORT
     TimeCode (unsigned int timeAndFlags,
-          unsigned int userData = 0,
-          Packing packing = TV60_PACKING);
+             unsigned int userData = 0,
+             Packing packing = TV60_PACKING);
 
+    IMF_EXPORT
     TimeCode (const TimeCode &other);
 
+    IMF_EXPORT
     TimeCode & operator = (const TimeCode &other);
 
 
@@ -167,53 +175,89 @@ class TimeCode
     // Access to individual fields
     //----------------------------
 
+    IMF_EXPORT
     int                hours () const;
+    IMF_EXPORT
     void       setHours (int value);
 
+    IMF_EXPORT
     int                minutes () const;
+    IMF_EXPORT
     void       setMinutes (int value);
 
+    IMF_EXPORT
     int                seconds () const;
+    IMF_EXPORT
     void       setSeconds (int value);
 
+    IMF_EXPORT
     int                frame () const;
+    IMF_EXPORT
     void       setFrame (int value);
 
+    IMF_EXPORT
     bool       dropFrame () const;
+    IMF_EXPORT
     void       setDropFrame (bool value);
 
+    IMF_EXPORT
     bool       colorFrame () const;
+    IMF_EXPORT
     void       setColorFrame (bool value);
 
+    IMF_EXPORT
     bool       fieldPhase () const;
+    IMF_EXPORT
     void       setFieldPhase (bool value);
 
+    IMF_EXPORT
     bool       bgf0 () const;
+    IMF_EXPORT
     void       setBgf0 (bool value);
 
+    IMF_EXPORT
     bool       bgf1 () const;
+    IMF_EXPORT
     void       setBgf1 (bool value);
 
+    IMF_EXPORT
     bool       bgf2 () const;
+    IMF_EXPORT
     void       setBgf2 (bool value);
 
+    IMF_EXPORT
     int                binaryGroup (int group) const; // group must be between 1 and 8
+    IMF_EXPORT
     void       setBinaryGroup (int group, int value);
 
-
+    
     //---------------------------------
     // Access to packed representations
     //---------------------------------
 
+    IMF_EXPORT
     unsigned int       timeAndFlags (Packing packing = TV60_PACKING) const;
 
+    IMF_EXPORT
     void               setTimeAndFlags (unsigned int value,
-                     Packing packing = TV60_PACKING);
+                                        Packing packing = TV60_PACKING);
 
+    IMF_EXPORT
     unsigned int       userData () const;
 
+    IMF_EXPORT
     void               setUserData (unsigned int value);
-
+    
+    
+    //---------
+    // Equality
+    //---------
+    
+    IMF_EXPORT
+    bool               operator == (const TimeCode &v) const;    
+    IMF_EXPORT
+    bool               operator != (const TimeCode &v) const;
+    
   private:
 
     unsigned int       _time;
@@ -221,6 +265,11 @@ class TimeCode
 };
 
 
-} // namespace Imf
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index b65e741..5e7ea59 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -41,8 +41,9 @@
 
 #include <ImfTimeCodeAttribute.h>
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -54,7 +55,7 @@ TimeCodeAttribute::staticTypeName ()
 
 template <>
 void
-TimeCodeAttribute::writeValueTo (OStream &os, int) const
+TimeCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.timeAndFlags());
     Xdr::write <StreamIO> (os, _value.userData());
@@ -63,7 +64,7 @@ TimeCodeAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-TimeCodeAttribute::readValueFrom (IStream &is, int, int)
+TimeCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     unsigned int tmp;
 
@@ -75,4 +76,4 @@ TimeCodeAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 9cd1976..ccd893a 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
-#include <ImfTimeCode.h>
-
+#include "ImfAttribute.h"
+#include "ImfTimeCode.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-typedef TypedAttribute<TimeCode> TimeCodeAttribute;
+typedef TypedAttribute<OPENEXR_IMF_INTERNAL_NAMESPACE::TimeCode> TimeCodeAttribute;
 
 template <>
+IMF_EXPORT
 const char *TimeCodeAttribute::staticTypeName ();
 
 template <>
-void TimeCodeAttribute::writeValueTo (OStream &, int) const;
+IMF_EXPORT
+void TimeCodeAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &,
+                                      int) const;
 
 template <>
-void TimeCodeAttribute::readValueFrom (IStream &, int, int);
+IMF_EXPORT
+void TimeCodeAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &,
+                                       int, int);
+
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
-} // namespace Imf
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfTimeCodeAttribute.cpp>
-#endif
 
 #endif
index 63f0017..7d51904 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -48,8 +48,9 @@
 #include <ImfVecAttribute.h>
 
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;
 
 template <>
 const char *
@@ -61,7 +62,7 @@ V2iAttribute::staticTypeName ()
 
 template <>
 void
-V2iAttribute::writeValueTo (OStream &os, int) const
+V2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -70,7 +71,7 @@ V2iAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-V2iAttribute::readValueFrom (IStream &is, int, int)
+V2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -87,7 +88,7 @@ V2fAttribute::staticTypeName ()
 
 template <>
 void
-V2fAttribute::writeValueTo (OStream &os, int) const
+V2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -96,7 +97,7 @@ V2fAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-V2fAttribute::readValueFrom (IStream &is, int, int)
+V2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -113,7 +114,7 @@ V2dAttribute::staticTypeName ()
 
 template <>
 void
-V2dAttribute::writeValueTo (OStream &os, int) const
+V2dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -122,7 +123,7 @@ V2dAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-V2dAttribute::readValueFrom (IStream &is, int, int)
+V2dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -139,7 +140,7 @@ V3iAttribute::staticTypeName ()
 
 template <>
 void
-V3iAttribute::writeValueTo (OStream &os, int) const
+V3iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -149,7 +150,7 @@ V3iAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-V3iAttribute::readValueFrom (IStream &is, int, int)
+V3iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -167,7 +168,7 @@ V3fAttribute::staticTypeName ()
 
 template <>
 void
-V3fAttribute::writeValueTo (OStream &os, int) const
+V3fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -177,7 +178,7 @@ V3fAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-V3fAttribute::readValueFrom (IStream &is, int, int)
+V3fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -195,7 +196,7 @@ V3dAttribute::staticTypeName ()
 
 template <>
 void
-V3dAttribute::writeValueTo (OStream &os, int) const
+V3dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os, int version) const
 {
     Xdr::write <StreamIO> (os, _value.x);
     Xdr::write <StreamIO> (os, _value.y);
@@ -205,7 +206,7 @@ V3dAttribute::writeValueTo (OStream &os, int) const
 
 template <>
 void
-V3dAttribute::readValueFrom (IStream &is, int, int)
+V3dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, int size, int version)
 {
     Xdr::read <StreamIO> (is, _value.x);
     Xdr::read <StreamIO> (is, _value.y);
@@ -213,4 +214,4 @@ V3dAttribute::readValueFrom (IStream &is, int, int)
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT 
index 83e3c84..8480fe6 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfAttribute.h>
+#include "ImfAttribute.h"
 #include "ImathVec.h"
 
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-namespace Imf {
+typedef TypedAttribute<IMATH_NAMESPACE::V2i> V2iAttribute;
+template <> IMF_EXPORT const char *V2iAttribute::staticTypeName ();
+template <> IMF_EXPORT void V2iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V2iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V2i> V2iAttribute;
-template <> const char *V2iAttribute::staticTypeName ();
-template <> void V2iAttribute::writeValueTo (OStream &, int) const;
-template <> void V2iAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V2f> V2fAttribute;
+template <> IMF_EXPORT const char *V2fAttribute::staticTypeName ();
+template <> IMF_EXPORT void V2fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V2fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V2f> V2fAttribute;
-template <> const char *V2fAttribute::staticTypeName ();
-template <> void V2fAttribute::writeValueTo (OStream &, int) const;
-template <> void V2fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V2d> V2dAttribute;
+template <> IMF_EXPORT const char *V2dAttribute::staticTypeName ();
+template <> IMF_EXPORT void V2dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V2dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V2d> V2dAttribute;
-template <> const char *V2dAttribute::staticTypeName ();
-template <> void V2dAttribute::writeValueTo (OStream &, int) const;
-template <> void V2dAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V3i> V3iAttribute;
+template <> IMF_EXPORT const char *V3iAttribute::staticTypeName ();
+template <> IMF_EXPORT void V3iAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V3iAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V3i> V3iAttribute;
-template <> const char *V3iAttribute::staticTypeName ();
-template <> void V3iAttribute::writeValueTo (OStream &, int) const;
-template <> void V3iAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V3f> V3fAttribute;
+template <> IMF_EXPORT const char *V3fAttribute::staticTypeName ();
+template <> IMF_EXPORT void V3fAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V3fAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V3f> V3fAttribute;
-template <> const char *V3fAttribute::staticTypeName ();
-template <> void V3fAttribute::writeValueTo (OStream &, int) const;
-template <> void V3fAttribute::readValueFrom (IStream &, int, int);
+typedef TypedAttribute<IMATH_NAMESPACE::V3d> V3dAttribute;
+template <> IMF_EXPORT const char *V3dAttribute::staticTypeName ();
+template <> IMF_EXPORT void V3dAttribute::writeValueTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &, int) const;
+template <> IMF_EXPORT void V3dAttribute::readValueFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &, int, int);
 
 
-typedef TypedAttribute<Imath::V3d> V3dAttribute;
-template <> const char *V3dAttribute::staticTypeName ();
-template <> void V3dAttribute::writeValueTo (OStream &, int) const;
-template <> void V3dAttribute::readValueFrom (IStream &, int, int);
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
-} // namespace Imf
+#if defined (OPENEXR_IMF_INTERNAL_NAMESPACE_AUTO_EXPOSE)
+namespace Imf { using namespace OPENEXR_IMF_INTERNAL_NAMESPACE; }
 
-// Metrowerks compiler wants the .cpp file inlined, too
-#ifdef __MWERKS__
-#include <ImfVecAttribute.cpp>
 #endif
 
 #endif
index 665cfb9..4f49aa0 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 
 #include <ImfVersion.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
 isImfMagic (const char bytes[4])
 {
     return bytes[0] == ((MAGIC >>  0) & 0x00ff) &&
-       bytes[1] == ((MAGIC >>  8) & 0x00ff) &&
-       bytes[2] == ((MAGIC >> 16) & 0x00ff) &&
-       bytes[3] == ((MAGIC >> 24) & 0x00ff);
+          bytes[1] == ((MAGIC >>  8) & 0x00ff) &&
+          bytes[2] == ((MAGIC >> 16) & 0x00ff) &&
+          bytes[3] == ((MAGIC >> 24) & 0x00ff);
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
 
index 946e697..64de7f4 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
+#include "ImfExport.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
-
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // The MAGIC number is stored in the first four bytes of every
@@ -88,11 +89,19 @@ const int LONG_NAMES_FLAG       = 0x00000400;   // File contains long
                                                 // attribute or channel
                                                 // names
 
+const int NON_IMAGE_FLAG        = 0x00000800;   // File has at least one part
+                                                // which is not a regular
+                                                // scanline image or regular tiled image
+                                                // (that is, it is a deep format)
+
+const int MULTI_PART_FILE_FLAG  = 0x00001000;   // File has multiple parts
+
 //
 // Bitwise OR of all known flags.
 //
 
-const int ALL_FLAGS            = TILED_FLAG | LONG_NAMES_FLAG;
+const int ALL_FLAGS            = TILED_FLAG | LONG_NAMES_FLAG |
+                                  NON_IMAGE_FLAG | MULTI_PART_FILE_FLAG;
 
 
 //
@@ -100,6 +109,8 @@ const int ALL_FLAGS         = TILED_FLAG | LONG_NAMES_FLAG;
 //
 
 inline bool  isTiled (int version)     {return !!(version & TILED_FLAG);}
+inline bool  isMultiPart (int version)  {return !!(version & MULTI_PART_FILE_FLAG); }
+inline bool  isNonImage(int version)    {return !!(version & NON_IMAGE_FLAG); }
 inline int   makeTiled (int version)   {return version | TILED_FLAG;}
 inline int   makeNotTiled (int version) {return version & ~TILED_FLAG;}
 inline int   getVersion (int version)  {return version & VERSION_NUMBER_FIELD;}
@@ -112,9 +123,14 @@ inline bool  supportsFlags (int flags)     {return !(flags & ~ALL_FLAGS);}
 // file is probably an OpenEXR image file, false if not.
 //
 
+IMF_EXPORT 
 bool        isImfMagic (const char bytes[4]);
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index 361ba66..5d71d56 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -46,8 +46,9 @@
 
 
 #include <ImfWav.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 namespace {
 
 
@@ -112,7 +113,7 @@ wenc16 (unsigned short  a, unsigned short  b,
     int d  =   ao - b;
 
     if (d < 0)
-    m = (m + M_OFFSET) & MOD_MASK;
+       m = (m + M_OFFSET) & MOD_MASK;
 
     d &= MOD_MASK;
 
@@ -160,98 +161,98 @@ wav2Encode
 
     while (p2 <= n)
     {
-    unsigned short *py = in;
-    unsigned short *ey = in + oy * (ny - p2);
-    int oy1 = oy * p;
-    int oy2 = oy * p2;
-    int ox1 = ox * p;
-    int ox2 = ox * p2;
-    unsigned short i00,i01,i10,i11;
-
-    //
-    // Y loop
-    //
-
-    for (; py <= ey; py += oy2)
-    {
-        unsigned short *px = py;
-        unsigned short *ex = py + ox * (nx - p2);
-
-        //
-        // X loop
-        //
-
-        for (; px <= ex; px += ox2)
-        {
-        unsigned short *p01 = px  + ox1;
-        unsigned short *p10 = px  + oy1;
-        unsigned short *p11 = p10 + ox1;
-
-        //
-        // 2D wavelet encoding
-        //
-
-        if (w14)
-        {
-            wenc14 (*px,  *p01, i00, i01);
-            wenc14 (*p10, *p11, i10, i11);
-            wenc14 (i00, i10, *px,  *p10);
-            wenc14 (i01, i11, *p01, *p11);
-        }
-        else
-        {
-            wenc16 (*px,  *p01, i00, i01);
-            wenc16 (*p10, *p11, i10, i11);
-            wenc16 (i00, i10, *px,  *p10);
-            wenc16 (i01, i11, *p01, *p11);
-        }
-        }
-
-        //
-        // Encode (1D) odd column (still in Y loop)
-        //
-
-        if (nx & p)
-        {
-        unsigned short *p10 = px + oy1;
-
-        if (w14)
-            wenc14 (*px, *p10, i00, *p10);
-        else
-            wenc16 (*px, *p10, i00, *p10);
-
-        *px= i00;
-        }
-    }
-
-    //
-    // Encode (1D) odd line (must loop in X)
-    //
-
-    if (ny & p)
-    {
-        unsigned short *px = py;
-        unsigned short *ex = py + ox * (nx - p2);
-
-        for (; px <= ex; px += ox2)
-        {
-        unsigned short *p01 = px + ox1;
-
-        if (w14)
-            wenc14 (*px, *p01, i00, *p01);
-        else
-            wenc16 (*px, *p01, i00, *p01);
-
-        *px= i00;
-        }
-    }
-
-    //
-    // Next level
-    //
-
-    p = p2;
-    p2 <<= 1;
+       unsigned short *py = in;
+       unsigned short *ey = in + oy * (ny - p2);
+       int oy1 = oy * p;
+       int oy2 = oy * p2;
+       int ox1 = ox * p;
+       int ox2 = ox * p2;
+       unsigned short i00,i01,i10,i11;
+
+       //
+       // Y loop
+       //
+
+       for (; py <= ey; py += oy2)
+       {
+           unsigned short *px = py;
+           unsigned short *ex = py + ox * (nx - p2);
+
+           //
+           // X loop
+           //
+
+           for (; px <= ex; px += ox2)
+           {
+               unsigned short *p01 = px  + ox1;
+               unsigned short *p10 = px  + oy1;
+               unsigned short *p11 = p10 + ox1;
+
+               //
+               // 2D wavelet encoding
+               //
+
+               if (w14)
+               {
+                   wenc14 (*px,  *p01, i00, i01);
+                   wenc14 (*p10, *p11, i10, i11);
+                   wenc14 (i00, i10, *px,  *p10);
+                   wenc14 (i01, i11, *p01, *p11);
+               }
+               else
+               {
+                   wenc16 (*px,  *p01, i00, i01);
+                   wenc16 (*p10, *p11, i10, i11);
+                   wenc16 (i00, i10, *px,  *p10);
+                   wenc16 (i01, i11, *p01, *p11);
+               }
+           }
+
+           //
+           // Encode (1D) odd column (still in Y loop)
+           //
+
+           if (nx & p)
+           {
+               unsigned short *p10 = px + oy1;
+
+               if (w14)
+                   wenc14 (*px, *p10, i00, *p10);
+               else
+                   wenc16 (*px, *p10, i00, *p10);
+
+               *px= i00;
+           }
+       }
+
+       //
+       // Encode (1D) odd line (must loop in X)
+       //
+
+       if (ny & p)
+       {
+           unsigned short *px = py;
+           unsigned short *ex = py + ox * (nx - p2);
+
+           for (; px <= ex; px += ox2)
+           {
+               unsigned short *p01 = px + ox1;
+
+               if (w14)
+                   wenc14 (*px, *p01, i00, *p01);
+               else
+                   wenc16 (*px, *p01, i00, *p01);
+
+               *px= i00;
+           }
+       }
+
+       //
+       // Next level
+       //
+
+       p = p2;
+       p2 <<= 1;
     }
 }
 
@@ -279,7 +280,7 @@ wav2Decode
     //
 
     while (p <= n)
-    p <<= 1;
+       p <<= 1;
 
     p >>= 1;
     p2 = p;
@@ -291,100 +292,100 @@ wav2Decode
 
     while (p >= 1)
     {
-    unsigned short *py = in;
-    unsigned short *ey = in + oy * (ny - p2);
-    int oy1 = oy * p;
-    int oy2 = oy * p2;
-    int ox1 = ox * p;
-    int ox2 = ox * p2;
-    unsigned short i00,i01,i10,i11;
-
-    //
-    // Y loop
-    //
-
-    for (; py <= ey; py += oy2)
-    {
-        unsigned short *px = py;
-        unsigned short *ex = py + ox * (nx - p2);
-
-        //
-        // X loop
-        //
-
-        for (; px <= ex; px += ox2)
-        {
-        unsigned short *p01 = px  + ox1;
-        unsigned short *p10 = px  + oy1;
-        unsigned short *p11 = p10 + ox1;
-
-        //
-        // 2D wavelet decoding
-        //
-
-        if (w14)
-        {
-            wdec14 (*px,  *p10, i00, i10);
-            wdec14 (*p01, *p11, i01, i11);
-            wdec14 (i00, i01, *px,  *p01);
-            wdec14 (i10, i11, *p10, *p11);
-        }
-        else
-        {
-            wdec16 (*px,  *p10, i00, i10);
-            wdec16 (*p01, *p11, i01, i11);
-            wdec16 (i00, i01, *px,  *p01);
-            wdec16 (i10, i11, *p10, *p11);
-        }
-        }
-
-        //
-        // Decode (1D) odd column (still in Y loop)
-        //
-
-        if (nx & p)
-        {
-        unsigned short *p10 = px + oy1;
-
-        if (w14)
-            wdec14 (*px, *p10, i00, *p10);
-        else
-            wdec16 (*px, *p10, i00, *p10);
-
-        *px= i00;
-        }
-    }
-
-    //
-    // Decode (1D) odd line (must loop in X)
-    //
-
-    if (ny & p)
-    {
-        unsigned short *px = py;
-        unsigned short *ex = py + ox * (nx - p2);
-
-        for (; px <= ex; px += ox2)
-        {
-        unsigned short *p01 = px + ox1;
-
-        if (w14)
-            wdec14 (*px, *p01, i00, *p01);
-        else
-            wdec16 (*px, *p01, i00, *p01);
-
-        *px= i00;
-        }
-    }
-
-    //
-    // Next level
-    //
-
-    p2 = p;
-    p >>= 1;
+       unsigned short *py = in;
+       unsigned short *ey = in + oy * (ny - p2);
+       int oy1 = oy * p;
+       int oy2 = oy * p2;
+       int ox1 = ox * p;
+       int ox2 = ox * p2;
+       unsigned short i00,i01,i10,i11;
+
+       //
+       // Y loop
+       //
+
+       for (; py <= ey; py += oy2)
+       {
+           unsigned short *px = py;
+           unsigned short *ex = py + ox * (nx - p2);
+
+           //
+           // X loop
+           //
+
+           for (; px <= ex; px += ox2)
+           {
+               unsigned short *p01 = px  + ox1;
+               unsigned short *p10 = px  + oy1;
+               unsigned short *p11 = p10 + ox1;
+
+               //
+               // 2D wavelet decoding
+               //
+
+               if (w14)
+               {
+                   wdec14 (*px,  *p10, i00, i10);
+                   wdec14 (*p01, *p11, i01, i11);
+                   wdec14 (i00, i01, *px,  *p01);
+                   wdec14 (i10, i11, *p10, *p11);
+               }
+               else
+               {
+                   wdec16 (*px,  *p10, i00, i10);
+                   wdec16 (*p01, *p11, i01, i11);
+                   wdec16 (i00, i01, *px,  *p01);
+                   wdec16 (i10, i11, *p10, *p11);
+               }
+           }
+
+           //
+           // Decode (1D) odd column (still in Y loop)
+           //
+
+           if (nx & p)
+           {
+               unsigned short *p10 = px + oy1;
+
+               if (w14)
+                   wdec14 (*px, *p10, i00, *p10);
+               else
+                   wdec16 (*px, *p10, i00, *p10);
+
+               *px= i00;
+           }
+       }
+
+       //
+       // Decode (1D) odd line (must loop in X)
+       //
+
+       if (ny & p)
+       {
+           unsigned short *px = py;
+           unsigned short *ex = py + ox * (nx - p2);
+
+           for (; px <= ex; px += ox2)
+           {
+               unsigned short *p01 = px + ox1;
+
+               if (w14)
+                   wdec14 (*px, *p01, i00, *p01);
+               else
+                   wdec16 (*px, *p01, i00, *p01);
+
+               *px= i00;
+           }
+       }
+
+       //
+       // Next level
+       //
+
+       p2 = p;
+       p >>= 1;
     }
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
index b84bc50..9751433 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //     16-bit Haar Wavelet encoding and decoding
 //
 //-----------------------------------------------------------------------------
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
+IMF_EXPORT 
 void
 wav2Encode
     (unsigned short *in, // io: values in[y][x] are transformed in place
@@ -55,6 +58,7 @@ wav2Encode
      int     oy,        // i : y offset
      unsigned short mx); // i : maximum in[x][y] value
 
+IMF_EXPORT
 void
 wav2Decode
     (unsigned short *in, // io: values in[y][x] are transformed in place
@@ -65,6 +69,10 @@ wav2Decode
      unsigned short mx); // i : maximum in[x][y] value
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
index 7970ca3..0af6f67 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -36,6 +36,7 @@
 #ifndef INCLUDED_IMF_XDR_H
 #define INCLUDED_IMF_XDR_H
 
+
 //----------------------------------------------------------------------------
 //
 //     Xdr -- routines to convert data between the machine's native
@@ -56,7 +57,7 @@
 //         size<S>();                  returns the size, in bytes, of the
 //                                     machine-independent representation
 //                                     of an object of type S.
-//
+//                                     
 //     The write() and read() routines are templates; data can be written
 //     to and read from any output or input buffer type T for which a helper
 //     class, R, exits.  Class R must define a method to store a char array
 //
 //----------------------------------------------------------------------------
 
-#include <ImfInt64.h>
+#include "ImfInt64.h"
 #include "IexMathExc.h"
 #include "half.h"
 #include <limits.h>
 
-namespace Imf {
+#include "ImfNamespace.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
 namespace Xdr {
 
 
@@ -425,31 +429,31 @@ write (T &out, signed long v)
 
     #if LONG_MAX == 2147483647
 
-    if (v >= 0)
-    {
-        b[4] = 0;
-        b[5] = 0;
-        b[6] = 0;
-        b[7] = 0;
-    }
-    else
-    {
-        b[4] = ~0;
-        b[5] = ~0;
-        b[6] = ~0;
-        b[7] = ~0;
-    }
+       if (v >= 0)
+       {
+           b[4] = 0;
+           b[5] = 0;
+           b[6] = 0;
+           b[7] = 0;
+       }
+       else
+       {
+           b[4] = ~0;
+           b[5] = ~0;
+           b[6] = ~0;
+           b[7] = ~0;
+       }
 
     #elif LONG_MAX == 9223372036854775807L
 
-    b[4] = (signed char) (v >> 32);
-    b[5] = (signed char) (v >> 40);
-    b[6] = (signed char) (v >> 48);
-    b[7] = (signed char) (v >> 56);
+       b[4] = (signed char) (v >> 32);
+       b[5] = (signed char) (v >> 40);
+       b[6] = (signed char) (v >> 48);
+       b[7] = (signed char) (v >> 56);
 
     #else
-
-    #error write<T> (T &out, signed long v) not implemented
+       
+       #error write<T> (T &out, signed long v) not implemented
 
     #endif
 
@@ -470,21 +474,21 @@ write (T &out, unsigned long v)
 
     #if ULONG_MAX == 4294967295U
 
-    b[4] = 0;
-    b[5] = 0;
-    b[6] = 0;
-    b[7] = 0;
+       b[4] = 0;
+       b[5] = 0;
+       b[6] = 0;
+       b[7] = 0;
 
     #elif ULONG_MAX == 18446744073709551615LU
 
-    b[4] = (unsigned char) (v >> 32);
-    b[5] = (unsigned char) (v >> 40);
-    b[6] = (unsigned char) (v >> 48);
-    b[7] = (unsigned char) (v >> 56);
+       b[4] = (unsigned char) (v >> 32);
+       b[5] = (unsigned char) (v >> 40);
+       b[6] = (unsigned char) (v >> 48);
+       b[7] = (unsigned char) (v >> 56);
 
     #else
-
-    #error write<T> (T &out, unsigned long v) not implemented
+       
+       #error write<T> (T &out, unsigned long v) not implemented
 
     #endif
 
@@ -582,8 +586,8 @@ write (T &out, const char v[])              // zero-terminated string
 {
     while (*v)
     {
-    S::writeChars (out, v, 1);
-    ++v;
+       S::writeChars (out, v, 1);
+       ++v;
     }
 
     S::writeChars (out, v, 1);
@@ -596,8 +600,8 @@ pad (T &out, int n)                 // add n padding bytes
 {
     for (int i = 0; i < n; i++)
     {
-    const char c = 0;
-    S::writeChars (out, &c, 1);
+       const char c = 0;
+       S::writeChars (out, &c, 1);
     }
 }
 
@@ -646,7 +650,7 @@ read (T &in, signed short &v)
     readSignedChars<S> (in, b, 2);
 
     v = (b[0] & 0x00ff) |
-    (b[1] << 8);
+       (b[1] << 8);
 }
 
 
@@ -659,7 +663,7 @@ read (T &in, unsigned short &v)
     readUnsignedChars<S> (in, b, 2);
 
     v = (b[0] & 0x00ff) |
-    (b[1] << 8);
+       (b[1] << 8);
 }
 
 
@@ -672,9 +676,9 @@ read (T &in, signed int &v)
     readSignedChars<S> (in, b, 4);
 
     v =  (b[0]        & 0x000000ff) |
-    ((b[1] << 8)  & 0x0000ff00) |
-    ((b[2] << 16) & 0x00ff0000) |
-     (b[3] << 24);
+       ((b[1] << 8)  & 0x0000ff00) |
+       ((b[2] << 16) & 0x00ff0000) |
+        (b[3] << 24);
 }
 
 
@@ -687,9 +691,9 @@ read (T &in, unsigned int &v)
     readUnsignedChars<S> (in, b, 4);
 
     v =  (b[0]        & 0x000000ff) |
-    ((b[1] << 8)  & 0x0000ff00) |
-    ((b[2] << 16) & 0x00ff0000) |
-     (b[3] << 24);
+       ((b[1] << 8)  & 0x0000ff00) |
+       ((b[2] << 16) & 0x00ff0000) |
+        (b[3] << 24);
 }
 
 
@@ -703,32 +707,32 @@ read (T &in, signed long &v)
 
     #if LONG_MAX == 2147483647
 
-    v =  (b[0]        & 0x000000ff) |
-        ((b[1] << 8)  & 0x0000ff00) |
-        ((b[2] << 16) & 0x00ff0000) |
-         (b[3] << 24);
+       v =  (b[0]        & 0x000000ff) |
+           ((b[1] << 8)  & 0x0000ff00) |
+           ((b[2] << 16) & 0x00ff0000) |
+            (b[3] << 24);
 
-    if (( b[4] ||  b[5] ||  b[6] ||  b[7]) &&
-        (~b[4] || ~b[5] || ~b[6] || ~b[7]))
-    {
-        throw Iex::OverflowExc ("Long int overflow - read a large "
-                    "64-bit integer in a 32-bit process.");
-    }
+       if (( b[4] ||  b[5] ||  b[6] ||  b[7]) &&
+           (~b[4] || ~b[5] || ~b[6] || ~b[7]))
+       {
+           throw IEX_NAMESPACE::OverflowExc ("Long int overflow - read a large "
+                                   "64-bit integer in a 32-bit process.");
+       }
 
     #elif LONG_MAX == 9223372036854775807L
 
-    v =  ((long) b[0]        & 0x00000000000000ff) |
-        (((long) b[1] << 8)  & 0x000000000000ff00) |
-        (((long) b[2] << 16) & 0x0000000000ff0000) |
-        (((long) b[3] << 24) & 0x00000000ff000000) |
-        (((long) b[4] << 32) & 0x000000ff00000000) |
-        (((long) b[5] << 40) & 0x0000ff0000000000) |
-        (((long) b[6] << 48) & 0x00ff000000000000) |
-         ((long) b[7] << 56);
+       v =  ((long) b[0]        & 0x00000000000000ff) |
+           (((long) b[1] << 8)  & 0x000000000000ff00) |
+           (((long) b[2] << 16) & 0x0000000000ff0000) |
+           (((long) b[3] << 24) & 0x00000000ff000000) |
+           (((long) b[4] << 32) & 0x000000ff00000000) |
+           (((long) b[5] << 40) & 0x0000ff0000000000) |
+           (((long) b[6] << 48) & 0x00ff000000000000) |
+            ((long) b[7] << 56);
 
     #else
 
-    #error read<T> (T &in, signed long &v) not implemented
+       #error read<T> (T &in, signed long &v) not implemented
 
     #endif
 }
@@ -744,31 +748,31 @@ read (T &in, unsigned long &v)
 
     #if ULONG_MAX == 4294967295U
 
-    v =  (b[0]        & 0x000000ff) |
-        ((b[1] << 8)  & 0x0000ff00) |
-        ((b[2] << 16) & 0x00ff0000) |
-         (b[3] << 24);
+       v =  (b[0]        & 0x000000ff) |
+           ((b[1] << 8)  & 0x0000ff00) |
+           ((b[2] << 16) & 0x00ff0000) |
+            (b[3] << 24);
 
-    if (b[4] || b[5] || b[6] || b[7])
-    {
-        throw Iex::OverflowExc ("Long int overflow - read a large "
-                    "64-bit integer in a 32-bit process.");
-    }
+       if (b[4] || b[5] || b[6] || b[7])
+       {
+           throw IEX_NAMESPACE::OverflowExc ("Long int overflow - read a large "
+                                   "64-bit integer in a 32-bit process.");
+       }
 
     #elif ULONG_MAX == 18446744073709551615LU
 
-    v =  ((unsigned long) b[0]        & 0x00000000000000ff) |
-        (((unsigned long) b[1] << 8)  & 0x000000000000ff00) |
-        (((unsigned long) b[2] << 16) & 0x0000000000ff0000) |
-        (((unsigned long) b[3] << 24) & 0x00000000ff000000) |
-        (((unsigned long) b[4] << 32) & 0x000000ff00000000) |
-        (((unsigned long) b[5] << 40) & 0x0000ff0000000000) |
-        (((unsigned long) b[6] << 48) & 0x00ff000000000000) |
-         ((unsigned long) b[7] << 56);
+       v =  ((unsigned long) b[0]        & 0x00000000000000ff) |
+           (((unsigned long) b[1] << 8)  & 0x000000000000ff00) |
+           (((unsigned long) b[2] << 16) & 0x0000000000ff0000) |
+           (((unsigned long) b[3] << 24) & 0x00000000ff000000) |
+           (((unsigned long) b[4] << 32) & 0x000000ff00000000) |
+           (((unsigned long) b[5] << 40) & 0x0000ff0000000000) |
+           (((unsigned long) b[6] << 48) & 0x00ff000000000000) |
+            ((unsigned long) b[7] << 56);
 
     #else
 
-    #error read<T> (T &in, unsigned long &v) not implemented
+       #error read<T> (T &in, unsigned long &v) not implemented
 
     #endif
 }
@@ -785,13 +789,13 @@ read (T &in, unsigned long &v)
         readUnsignedChars<S> (in, b, 8);
 
         v =  ((Int64) b[0]        & 0x00000000000000ffLL) |
-        (((Int64) b[1] << 8)  & 0x000000000000ff00LL) |
-        (((Int64) b[2] << 16) & 0x0000000000ff0000LL) |
-        (((Int64) b[3] << 24) & 0x00000000ff000000LL) |
-        (((Int64) b[4] << 32) & 0x000000ff00000000LL) |
-        (((Int64) b[5] << 40) & 0x0000ff0000000000LL) |
-        (((Int64) b[6] << 48) & 0x00ff000000000000LL) |
-        ((Int64) b[7] << 56);
+           (((Int64) b[1] << 8)  & 0x000000000000ff00LL) |
+           (((Int64) b[2] << 16) & 0x0000000000ff0000LL) |
+           (((Int64) b[3] << 24) & 0x00000000ff000000LL) |
+           (((Int64) b[4] << 32) & 0x000000ff00000000LL) |
+           (((Int64) b[5] << 40) & 0x0000ff0000000000LL) |
+           (((Int64) b[6] << 48) & 0x00ff000000000000LL) |
+           ((Int64) b[7] << 56);
     }
 
 #endif
@@ -808,9 +812,9 @@ read (T &in, float &v)
     union {unsigned int i; float f;} u;
 
     u.i = (b[0]        & 0x000000ff) |
-     ((b[1] << 8)  & 0x0000ff00) |
-     ((b[2] << 16) & 0x00ff0000) |
-      (b[3] << 24);
+        ((b[1] << 8)  & 0x0000ff00) |
+        ((b[2] << 16) & 0x00ff0000) |
+         (b[3] << 24);
 
     v = u.f;
 }
@@ -827,13 +831,13 @@ read (T &in, double &v)
     union {Int64 i; double d;} u;
 
     u.i = ((Int64) b[0]        & 0x00000000000000ffULL) |
-     (((Int64) b[1] << 8)  & 0x000000000000ff00ULL) |
-     (((Int64) b[2] << 16) & 0x0000000000ff0000ULL) |
-     (((Int64) b[3] << 24) & 0x00000000ff000000ULL) |
-     (((Int64) b[4] << 32) & 0x000000ff00000000ULL) |
-     (((Int64) b[5] << 40) & 0x0000ff0000000000ULL) |
-     (((Int64) b[6] << 48) & 0x00ff000000000000ULL) |
-      ((Int64) b[7] << 56);
+        (((Int64) b[1] << 8)  & 0x000000000000ff00ULL) |
+        (((Int64) b[2] << 16) & 0x0000000000ff0000ULL) |
+        (((Int64) b[3] << 24) & 0x00000000ff000000ULL) |
+        (((Int64) b[4] << 32) & 0x000000ff00000000ULL) |
+        (((Int64) b[5] << 40) & 0x0000ff0000000000ULL) |
+        (((Int64) b[6] << 48) & 0x00ff000000000000ULL) |
+         ((Int64) b[7] << 56);
 
     v = u.d;
 }
@@ -865,13 +869,13 @@ read (T &in, int n, char v[])             // zero-terminated string
 {
     while (n >= 0)
     {
-    S::readChars (in, v, 1);
+       S::readChars (in, v, 1);
 
-    if (*v == 0)
-        break;
+       if (*v == 0)
+           break;
 
-    --n;
-    ++v;
+       --n;
+       ++v;
     }
 }
 
@@ -884,14 +888,14 @@ skip (T &in, int n)                       // skip n padding bytes
 
     while (n >= (int) sizeof (c))
     {
-    if (!S::readChars (in, c, sizeof (c)))
-        return;
+       if (!S::readChars (in, c, sizeof (c)))
+           return;
 
-    n -= sizeof (c);
+       n -= sizeof (c);
     }
 
     if (n >= 1)
-    S::readChars (in, c, n);
+       S::readChars (in, c, n);
 }
 
 
@@ -905,12 +909,19 @@ template <> inline int size <signed int> ()               {return 4;}
 template <> inline int size <unsigned int> ()          {return 4;}
 template <> inline int size <signed long> ()           {return 8;}
 template <> inline int size <unsigned long> ()         {return 8;}
+template <> inline int size <unsigned long long> ()     {return 8;}
 template <> inline int size <float> ()                 {return 4;}
 template <> inline int size <double> ()                        {return 8;}
 template <> inline int size <half> ()                  {return 2;}
 
 
 } // namespace Xdr
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+#if defined (OPENEXR_IMF_INTERNAL_NAMESPACE_AUTO_EXPOSE)
+namespace Imf{using namespace OPENEXR_IMF_INTERNAL_NAMESPACE;}
+#endif
+
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/ImfZip.cpp b/3rdparty/openexr/IlmImf/ImfZip.cpp
new file mode 100644 (file)
index 0000000..4e6a62f
--- /dev/null
@@ -0,0 +1,305 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImfZip.h"
+#include "ImfCheckedArithmetic.h"
+#include "ImfNamespace.h"
+#include "ImfSimd.h"
+#include "Iex.h"
+
+#include <math.h>
+#include <zlib.h>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+Zip::Zip(size_t maxRawSize):
+    _maxRawSize(maxRawSize),
+    _tmpBuffer(0)
+{
+    _tmpBuffer = new char[_maxRawSize];
+}
+
+Zip::Zip(size_t maxScanLineSize, size_t numScanLines):
+    _maxRawSize(0),
+    _tmpBuffer(0)
+{
+    _maxRawSize = uiMult (maxScanLineSize, numScanLines);
+    _tmpBuffer  = new char[_maxRawSize];
+}
+
+Zip::~Zip()
+{
+    if (_tmpBuffer) delete[] _tmpBuffer;
+}
+
+size_t
+Zip::maxRawSize()
+{
+    return _maxRawSize;
+}
+
+size_t
+Zip::maxCompressedSize()
+{
+    return uiAdd (uiAdd (_maxRawSize,
+               size_t (ceil (_maxRawSize * 0.01))),
+                  size_t (100));
+}
+
+int
+Zip::compress(const char *raw, int rawSize, char *compressed)
+{
+    //
+    // Reorder the pixel data.
+    //
+
+    {
+        char *t1 = _tmpBuffer;
+        char *t2 = _tmpBuffer + (rawSize + 1) / 2;
+        const char *stop = raw + rawSize;
+
+        while (true)
+        {
+            if (raw < stop)
+            *(t1++) = *(raw++);
+            else
+            break;
+
+            if (raw < stop)
+            *(t2++) = *(raw++);
+            else
+            break;
+        }
+    }
+
+    //
+    // Predictor.
+    //
+
+    {
+        unsigned char *t    = (unsigned char *) _tmpBuffer + 1;
+        unsigned char *stop = (unsigned char *) _tmpBuffer + rawSize;
+        int p = t[-1];
+
+        while (t < stop)
+        {
+            int d = int (t[0]) - p + (128 + 256);
+            p = t[0];
+            t[0] = d;
+            ++t;
+        }
+    }
+
+    //
+    // Compress the data using zlib
+    //
+
+    uLongf outSize = int(ceil(rawSize * 1.01)) + 100;
+
+    if (Z_OK != ::compress ((Bytef *)compressed, &outSize,
+                (const Bytef *) _tmpBuffer, rawSize))
+    {
+        throw IEX_NAMESPACE::BaseExc ("Data compression (zlib) failed.");
+    }
+
+    return outSize;
+}
+
+#ifdef IMF_HAVE_SSE4_1
+
+static void
+reconstruct_sse41(char *buf, size_t outSize)
+{
+    static const size_t bytesPerChunk = sizeof(__m128i);
+    const size_t vOutSize = outSize / bytesPerChunk;
+
+    const __m128i c = _mm_set1_epi8(-128);
+    const __m128i shuffleMask = _mm_set1_epi8(15);
+
+    // The first element doesn't have its high bit flipped during compression,
+    // so it must not be flipped here.  To make the SIMD loop nice and
+    // uniform, we pre-flip the bit so that the loop will unflip it again.
+    buf[0] += -128;
+
+    __m128i *vBuf = reinterpret_cast<__m128i *>(buf);
+    __m128i vPrev = _mm_setzero_si128();
+    for (size_t i=0; i<vOutSize; ++i)
+    {
+        __m128i d = _mm_add_epi8(_mm_loadu_si128(vBuf), c);
+
+        // Compute the prefix sum of elements.
+        d = _mm_add_epi8(d, _mm_slli_si128(d, 1));
+        d = _mm_add_epi8(d, _mm_slli_si128(d, 2));
+        d = _mm_add_epi8(d, _mm_slli_si128(d, 4));
+        d = _mm_add_epi8(d, _mm_slli_si128(d, 8));
+        d = _mm_add_epi8(d, vPrev);
+
+        _mm_storeu_si128(vBuf++, d);
+
+        // Broadcast the high byte in our result to all lanes of the prev
+        // value for the next iteration.
+        vPrev = _mm_shuffle_epi8(d, shuffleMask);
+    }
+
+    unsigned char prev = _mm_extract_epi8(vPrev, 15);
+    for (size_t i=vOutSize*bytesPerChunk; i<outSize; ++i)
+    {
+        unsigned char d = prev + buf[i] - 128;
+        buf[i] = d;
+        prev = d;
+    }
+}
+
+#else
+
+static void
+reconstruct_scalar(char *buf, size_t outSize)
+{
+    unsigned char *t    = (unsigned char *) buf + 1;
+    unsigned char *stop = (unsigned char *) buf + outSize;
+
+    while (t < stop)
+    {
+        int d = int (t[-1]) + int (t[0]) - 128;
+        t[0] = d;
+        ++t;
+    }
+}
+
+#endif
+
+
+#ifdef IMF_HAVE_SSE2
+
+static void
+interleave_sse2(const char *source, size_t outSize, char *out)
+{
+    static const size_t bytesPerChunk = 2*sizeof(__m128i);
+
+    const size_t vOutSize = outSize / bytesPerChunk;
+
+    const __m128i *v1 = reinterpret_cast<const __m128i *>(source);
+    const __m128i *v2 = reinterpret_cast<const __m128i *>(source + (outSize + 1) / 2);
+    __m128i *vOut = reinterpret_cast<__m128i *>(out);
+
+    for (size_t i=0; i<vOutSize; ++i) {
+        __m128i a = _mm_loadu_si128(v1++);
+        __m128i b = _mm_loadu_si128(v2++);
+
+        __m128i lo = _mm_unpacklo_epi8(a, b);
+        __m128i hi = _mm_unpackhi_epi8(a, b);
+
+        _mm_storeu_si128(vOut++, lo);
+        _mm_storeu_si128(vOut++, hi);
+    }
+
+    const char *t1 = reinterpret_cast<const char *>(v1);
+    const char *t2 = reinterpret_cast<const char *>(v2);
+    char *sOut = reinterpret_cast<char *>(vOut);
+
+    for (size_t i=vOutSize*bytesPerChunk; i<outSize; ++i)
+    {
+        *(sOut++) = (i%2==0) ? *(t1++) : *(t2++);
+    }
+}
+
+#else
+
+static void
+interleave_scalar(const char *source, size_t outSize, char *out)
+{
+    const char *t1 = source;
+    const char *t2 = source + (outSize + 1) / 2;
+    char *s = out;
+    char *const stop = s + outSize;
+
+    while (true)
+    {
+        if (s < stop)
+            *(s++) = *(t1++);
+        else
+            break;
+
+        if (s < stop)
+            *(s++) = *(t2++);
+        else
+            break;
+    }
+}
+
+#endif
+
+int
+Zip::uncompress(const char *compressed, int compressedSize,
+                char *raw)
+{
+    //
+    // Decompress the data using zlib
+    //
+
+    uLongf outSize = _maxRawSize;
+
+    if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer, &outSize,
+                     (const Bytef *) compressed, compressedSize))
+    {
+        throw IEX_NAMESPACE::InputExc ("Data decompression (zlib) failed.");
+    }
+
+    if (outSize == 0)
+    {
+        return outSize;
+    }
+
+    //
+    // Predictor.
+    //
+#ifdef IMF_HAVE_SSE4_1
+    reconstruct_sse41(_tmpBuffer, outSize);
+#else
+    reconstruct_scalar(_tmpBuffer, outSize);
+#endif
+
+    //
+    // Reorder the pixel data.
+    //
+#ifdef IMF_HAVE_SSE2
+    interleave_sse2(_tmpBuffer, outSize, raw);
+#else
+    interleave_scalar(_tmpBuffer, outSize, raw);
+#endif
+
+    return outSize;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
similarity index 53%
rename from 3rdparty/openexr/Half/eLut.cpp
rename to 3rdparty/openexr/IlmImf/ImfZip.h
index b231389..e63b8b5 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 ///////////////////////////////////////////////////////////////////////////
 
 
+#ifndef INCLUDED_IMF_ZIP_H
+#define INCLUDED_IMF_ZIP_H
 
-#include <iostream>
-#include <iomanip>
+#include "ImfNamespace.h"
+#include "ImfExport.h"
 
-using namespace std;
+#include <cstddef>
 
-//-----------------------------------------------------
-// Compute a lookup table for float-to-half conversion.
-//
-// When indexed with the combined sign and exponent of
-// a float, the table either returns the combined sign
-// and exponent of the corresponding half, or zero if
-// the corresponding half may not be normalized (zero,
-// denormalized, overflow).
-//-----------------------------------------------------
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
-void
-initELut (unsigned short eLut[])
+class Zip
 {
-    for (int i = 0; i < 0x100; i++)
-    {
-    int e = (i & 0x0ff) - (127 - 15);
+    public:
+        IMF_EXPORT
+        explicit Zip(size_t rawMaxSize);
+        IMF_EXPORT
+        Zip(size_t maxScanlineSize, size_t numScanLines);
+        IMF_EXPORT
+        ~Zip();
+
+        IMF_EXPORT
+        size_t maxRawSize();
+        IMF_EXPORT
+        size_t maxCompressedSize();
 
-    if (e <= 0 || e >= 30)
-    {
         //
-        // Special case
+        // Compress the raw data into the provided buffer.
+        // Returns the amount of compressed data.
         //
+        IMF_EXPORT
+        int compress(const char *raw, int rawSize, char *compressed);
 
-        eLut[i]         = 0;
-        eLut[i | 0x100] = 0;
-    }
-    else
-    {
-        //
-        // Common case - normalized half, no exponent overflow possible
+        // 
+        // Uncompress the compressed data into the provided
+        // buffer. Returns the amount of raw data actually decoded.
         //
+        IMF_EXPORT
+        int uncompress(const char *compressed, int compressedSize,
+                                                 char *raw);
 
-        eLut[i]         =  (e << 10);
-        eLut[i | 0x100] = ((e << 10) | 0x8000);
-    }
-    }
-}
-
-
-//------------------------------------------------------------
-// Main - prints the sign-and-exponent conversion lookup table
-//------------------------------------------------------------
-
-int
-main ()
-{
-    const int tableSize = 1 << 9;
-    unsigned short eLut[tableSize];
-    initELut (eLut);
-
-    cout << "//\n"
-        "// This is an automatically generated file.\n"
-        "// Do not edit.\n"
-        "//\n\n";
-
-    cout << "{\n    ";
-
-    for (int i = 0; i < tableSize; i++)
-    {
-    cout << setw (5) << eLut[i] << ", ";
+    private:
+        size_t _maxRawSize;
+        char  *_tmpBuffer;
 
-    if (i % 8 == 7)
-    {
-        cout << "\n";
+        Zip();
+        Zip(const Zip&);
+};
 
-        if (i < tableSize - 1)
-        cout << "    ";
-    }
-    }
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
 
-    cout << "};\n";
-    return 0;
-}
+#endif
index 9296a5f..b0d6989 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //     class ZipCompressor
 //
 //-----------------------------------------------------------------------------
-//#define ZLIB_WINAPI
 
-#include <ImfZipCompressor.h>
-#include <ImfCheckedArithmetic.h>
+#include "ImfZipCompressor.h"
+#include "ImfCheckedArithmetic.h"
 #include "Iex.h"
 #include <zlib.h>
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 ZipCompressor::ZipCompressor
@@ -57,28 +57,15 @@ ZipCompressor::ZipCompressor
     Compressor (hdr),
     _maxScanLineSize (maxScanLineSize),
     _numScanLines (numScanLines),
-    _tmpBuffer (0),
-    _outBuffer (0)
+    _outBuffer (0),
+    _zip(maxScanLineSize, numScanLines)
 {
-    size_t maxInBytes =
-        uiMult (maxScanLineSize, numScanLines);
-
-    size_t maxOutBytes =
-        uiAdd (uiAdd (maxInBytes,
-                      size_t (ceil (maxInBytes * 0.01))),
-               size_t (100));
-
-    _tmpBuffer =
-    new char [maxInBytes];
-
-    _outBuffer =
-    new char [maxOutBytes];
+    _outBuffer = new char[_zip.maxCompressedSize()];
 }
 
 
 ZipCompressor::~ZipCompressor ()
 {
-    delete [] _tmpBuffer;
     delete [] _outBuffer;
 }
 
@@ -92,72 +79,21 @@ ZipCompressor::numScanLines () const
 
 int
 ZipCompressor::compress (const char *inPtr,
-             int inSize,
-             int /*minY*/,
-             const char *&outPtr)
+                        int inSize,
+                        int minY,
+                        const char *&outPtr)
 {
     //
-    // Special case Â­- empty input buffer
+    // Special case ï¿½- empty input buffer
     //
 
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
+       outPtr = _outBuffer;
+       return 0;
     }
 
-    //
-    // Reorder the pixel data.
-    //
-
-    {
-    char *t1 = _tmpBuffer;
-    char *t2 = _tmpBuffer + (inSize + 1) / 2;
-    const char *stop = inPtr + inSize;
-
-    while (true)
-    {
-        if (inPtr < stop)
-        *(t1++) = *(inPtr++);
-        else
-        break;
-
-        if (inPtr < stop)
-        *(t2++) = *(inPtr++);
-        else
-        break;
-    }
-    }
-
-    //
-    // Predictor.
-    //
-
-    {
-    unsigned char *t = (unsigned char *) _tmpBuffer + 1;
-    unsigned char *stop = (unsigned char *) _tmpBuffer + inSize;
-    int p = t[-1];
-
-    while (t < stop)
-    {
-        int d = int (t[0]) - p + (128 + 256);
-        p = t[0];
-        t[0] = d;
-        ++t;
-    }
-    }
-
-    //
-    // Compress the data using zlib
-    //
-
-    uLongf outSize = int(ceil(inSize * 1.01)) + 100;
-
-    if (Z_OK != ::compress ((Bytef *)_outBuffer, &outSize,
-                (const Bytef *) _tmpBuffer, inSize))
-    {
-    throw Iex::BaseExc ("Data compression (zlib) failed.");
-    }
+    int outSize = _zip.compress(inPtr, inSize, _outBuffer);
 
     outPtr = _outBuffer;
     return outSize;
@@ -166,75 +102,26 @@ ZipCompressor::compress (const char *inPtr,
 
 int
 ZipCompressor::uncompress (const char *inPtr,
-               int inSize,
-               int /*minY*/,
-               const char *&outPtr)
+                          int inSize,
+                          int minY,
+                          const char *&outPtr)
 {
     //
-    // Special case Â­- empty input buffer
+    // Special case ï¿½- empty input buffer
     //
 
     if (inSize == 0)
     {
-    outPtr = _outBuffer;
-    return 0;
-    }
-
-    //
-    // Decompress the data using zlib
-    //
-
-    uLongf outSize = _maxScanLineSize * _numScanLines;
-
-    if (Z_OK != ::uncompress ((Bytef *)_tmpBuffer, &outSize,
-                  (const Bytef *) inPtr, inSize))
-    {
-    throw Iex::InputExc ("Data decompression (zlib) failed.");
-    }
-
-    //
-    // Predictor.
-    //
-
-    {
-    unsigned char *t = (unsigned char *) _tmpBuffer + 1;
-    unsigned char *stop = (unsigned char *) _tmpBuffer + outSize;
-
-    while (t < stop)
-    {
-        int d = int (t[-1]) + int (t[0]) - 128;
-        t[0] = d;
-        ++t;
+       outPtr = _outBuffer;
+       return 0;
     }
-    }
-
-    //
-    // Reorder the pixel data.
-    //
 
-    {
-    const char *t1 = _tmpBuffer;
-    const char *t2 = _tmpBuffer + (outSize + 1) / 2;
-    char *s = _outBuffer;
-    char *stop = s + outSize;
-
-    while (true)
-    {
-        if (s < stop)
-        *(s++) = *(t1++);
-        else
-        break;
-
-        if (s < stop)
-        *(s++) = *(t2++);
-        else
-        break;
-    }
-    }
+    int outSize = _zip.uncompress(inPtr, inSize, _outBuffer);
 
     outPtr = _outBuffer;
     return outSize;
 }
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
index ae1f988..6744b63 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include <ImfCompressor.h>
+#include "ImfCompressor.h"
+#include "ImfZip.h"
+#include "ImfNamespace.h"
 
-namespace Imf {
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 class ZipCompressor: public Compressor
 {
   public:
 
-    ZipCompressor (const Header &hdr,
+    IMF_EXPORT
+    ZipCompressor (const Header &hdr, 
                    size_t maxScanLineSize,
                    size_t numScanLines);
 
+    IMF_EXPORT
     virtual ~ZipCompressor ();
 
+    IMF_EXPORT
     virtual int numScanLines () const;
 
+    IMF_EXPORT
     virtual int        compress (const char *inPtr,
-              int inSize,
-              int minY,
-              const char *&outPtr);
+                         int inSize,
+                         int minY,
+                         const char *&outPtr);
 
+    IMF_EXPORT
     virtual int        uncompress (const char *inPtr,
-                int inSize,
-                int minY,
-                const char *&outPtr);
+                           int inSize,
+                           int minY,
+                           const char *&outPtr);
   private:
 
     int                _maxScanLineSize;
     int                _numScanLines;
-    char *     _tmpBuffer;
     char *     _outBuffer;
+    Zip     _zip;
 };
 
 
-} // namespace Imf
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
+
+
+
+
 
 #endif
diff --git a/3rdparty/openexr/IlmImf/dwaLookups.cpp b/3rdparty/openexr/IlmImf/dwaLookups.cpp
new file mode 100644 (file)
index 0000000..ac5ac09
--- /dev/null
@@ -0,0 +1,650 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2009-2014 DreamWorks Animation LLC. 
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of DreamWorks Animation 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#define OPENEXR_BUILTIN_TABLES
+
+//
+// A program to generate various acceleration lookup tables 
+// for Imf::DwaCompressor
+//
+
+#include <cstddef>
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <vector>
+
+#include <OpenEXRConfig.h>
+
+#ifndef OPENEXR_BUILTIN_TABLES
+#ifdef OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN
+#include <unistd.h>
+#endif
+#endif // OPENEXR_BUILTIN_TABLES
+
+#include <half.h>
+#include <IlmThread.h>
+#include <IlmThreadSemaphore.h>
+#include <ImfIO.h>
+#include <ImfXdr.h>
+#include "ImfNamespace.h"
+
+using namespace OPENEXR_IMF_NAMESPACE;
+
+namespace {
+
+#ifdef OPENEXR_BUILTIN_TABLES
+static unsigned short dwaCompressorNoOp[0x10000] = {};
+static unsigned short dwaCompressorToLinear[0x10000] = {};
+static unsigned short dwaCompressorToNonlinear[0x10000] = {};
+
+//static unsigned int closestDataOffset[0x10000] = {};
+//static unsigned short closestData[0x80000] = {};
+#else
+
+    class LutHeaderWorker
+    {
+        public:
+            class Runner : public ILMTHREAD_NAMESPACE::Thread
+            {
+                public:
+                    Runner(LutHeaderWorker &worker, bool output):
+                        ILMTHREAD_NAMESPACE::Thread(),
+                        _worker(worker),
+                        _output(output)
+                    {
+                        start();
+                    }
+
+                    virtual ~Runner()
+                    {
+                        _semaphore.wait();
+                    }
+
+                    virtual void run()
+                    {
+                        _semaphore.post();
+                        _worker.run(_output);
+                    }
+
+                private:
+                    LutHeaderWorker     &_worker;
+                    bool                 _output;
+                    ILMTHREAD_NAMESPACE::Semaphore _semaphore;
+
+            }; // class LutHeaderWorker::Runner
+
+
+            LutHeaderWorker(size_t startValue,
+                            size_t endValue):
+                _lastCandidateCount(0),
+                _startValue(startValue),
+                _endValue(endValue),
+                _numElements(0),
+                _offset(new size_t[numValues()]),
+                _elements(new unsigned short[1024*1024*2])
+            {
+            }
+
+            ~LutHeaderWorker()
+            {
+                delete[] _offset;
+                delete[] _elements;
+            }
+
+            size_t lastCandidateCount() const
+            {
+                return _lastCandidateCount;
+            }
+
+            size_t numValues() const 
+            {
+                return _endValue - _startValue;
+            }
+
+            size_t numElements() const
+            {
+                return _numElements;
+            }
+
+            const size_t* offset() const
+            {
+                return _offset;
+            }
+
+            const unsigned short* elements() const
+            {
+                return _elements;
+            }
+
+            void run(bool outputProgress)
+            {
+                half candidate[16];
+                int  candidateCount = 0;
+
+                for (size_t input=_startValue; input<_endValue; ++input) {
+
+                    if (outputProgress) {
+#ifdef __GNUC__
+                        if (input % 100 == 0) {
+                            fprintf(stderr, 
+                            " Building acceleration for DwaCompressor, %.2f %%      %c",
+                                          100.*(float)input/(float)numValues(), 13);
+                        }
+#else
+                        if (input % 1000 == 0) {
+                            fprintf(stderr, 
+                            " Building acceleration for DwaCompressor, %.2f %%\n",
+                                          100.*(float)input/(float)numValues());
+                        }
+#endif
+                    } 
+
+                    
+                    int  numSetBits = countSetBits(input);
+                    half inputHalf, closestHalf;
+
+                    inputHalf.setBits(input);
+
+                    _offset[input - _startValue] = _numElements;
+
+                    // Gather candidates
+                    candidateCount = 0;
+                    for (int targetNumSetBits=numSetBits-1; targetNumSetBits>=0;
+                                                           --targetNumSetBits) {
+                        bool valueFound = false;
+
+                        for (int i=0; i<65536; ++i) {
+                            if (countSetBits(i) != targetNumSetBits) continue;
+
+                            if (!valueFound) {
+                                closestHalf.setBits(i);
+                                valueFound = true;
+                            } else {
+                                half tmpHalf;
+
+                                tmpHalf.setBits(i);
+
+                                if (fabs((float)inputHalf - (float)tmpHalf) < 
+                                    fabs((float)inputHalf - (float)closestHalf)) {
+                                    closestHalf = tmpHalf;
+                                }
+                            }
+                        }
+
+                        if (valueFound == false) {
+                            fprintf(stderr, "bork bork bork!\n");
+                        }       
+
+                        candidate[candidateCount] = closestHalf;
+                        candidateCount++;
+                    }
+
+                    // Sort candidates by increasing number of bits set
+                    for (int i=0; i<candidateCount; ++i) {
+                        for (int j=i+1; j<candidateCount; ++j) {
+
+                            int   iCnt = countSetBits(candidate[i].bits());
+                            int   jCnt = countSetBits(candidate[j].bits());
+
+                            if (jCnt < iCnt) {
+                                half tmp     = candidate[i];
+                                candidate[i] = candidate[j];
+                                candidate[j] = tmp;
+                            }
+                        }
+                    }
+
+                    // Copy candidates to the data buffer;
+                    for (int i=0; i<candidateCount; ++i) {
+                        _elements[_numElements] = candidate[i].bits();
+                        _numElements++;
+                    }
+
+                    if (input == _endValue-1) {
+                        _lastCandidateCount = candidateCount;
+                    }
+                }
+            }
+            
+
+        private:
+            size_t          _lastCandidateCount;
+            size_t          _startValue;
+            size_t          _endValue;
+            size_t          _numElements;
+            size_t         *_offset;
+            unsigned short *_elements;
+
+            //
+            // Precomputing the bit count runs faster than using
+            // the builtin instruction, at least in one case..
+            //
+            // Precomputing 8-bits is no slower than 16-bits,
+            // and saves a fair bit of overhead..
+            //
+            int countSetBits(unsigned short src)
+            {
+                static const unsigned short numBitsSet[256] =
+                {
+                    0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
+                    4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
+                };
+
+                return numBitsSet[src & 0xff] + numBitsSet[src >> 8];
+            }
+
+    }; // class LutHeaderWorker
+
+#endif // OPENEXR_BUILTIN_TABLES
+
+} // namespace
+
+
+//
+// Generate a no-op LUT, to cut down in conditional branches
+//
+static void
+generateNoop()
+{
+#ifndef OPENEXR_BUILTIN_TABLES
+    printf("const unsigned short dwaCompressorNoOp[] = \n");
+    printf("{");
+#endif // OPENEXR_BUILTIN_TABLES
+    for (int i=0; i<65536; ++i) {
+#ifndef OPENEXR_BUILTIN_TABLES
+        if (i % 8 == 0) {
+            printf("\n    ");
+        }
+#endif  // OPENEXR_BUILTIN_TABLES
+        unsigned short dst;
+        char *tmp = (char *)(&dst);
+
+        unsigned short src = (unsigned short)i;
+        Xdr::write <CharPtrIO> (tmp,  src);
+#ifndef OPENEXR_BUILTIN_TABLES
+        printf("0x%04x, ", dst);
+#else
+        dwaCompressorNoOp[i] = dst;
+#endif // OPENEXR_BUILTIN_TABLES
+    }
+#ifndef OPENEXR_BUILTIN_TABLES
+    printf("\n};\n");
+#endif // OPENEXR_BUILTIN_TABLES
+}
+
+//
+// Nonlinearly encode luminance. For values below 1.0, we want
+// to use a gamma 2.2 function to match what is fairly common
+// for storing output referred. However, > 1, gamma functions blow up,
+// and log functions are much better behaved. We could use a log 
+// function everywhere, but it tends to over-sample dark 
+// regions and undersample the brighter regions, when 
+// compared to the way real devices reproduce values.
+//
+// So, above 1, use a log function which is a smooth blend
+// into the gamma function. 
+//
+//  Nonlinear(linear) = 
+//
+//    linear^(1./2.2)             / linear <= 1.0
+//                               |
+//    ln(linear)/ln(e^2.2) + 1    \ otherwise
+//
+//
+// toNonlinear[] needs to take in XDR format half float values,
+// and output NATIVE format float. 
+//
+// toLinear[] does the opposite - takes in NATIVE half and 
+// outputs XDR half values.
+//
+
+static void
+generateToLinear()
+{
+#ifndef OPENEXR_BUILTIN_TABLES
+    unsigned short toLinear[65536];
+#else
+    unsigned short* toLinear = dwaCompressorToLinear;
+#endif // OPENEXR_BUILTIN_TABLES
+
+    toLinear[0] = 0;
+
+    for (int i=1; i<65536; ++i) {
+        half  h;
+        float sign    = 1;
+        float logBase = pow(2.7182818, 2.2);
+
+        // map  NaN and inf to 0
+        if ((i & 0x7c00) == 0x7c00) {
+            toLinear[i]    = 0;
+            continue;
+        }
+
+        //
+        // _toLinear - assume i is NATIVE, but our output needs
+        //             to get flipped to XDR
+        //
+        h.setBits(i);
+        sign = 1;
+        if ((float)h < 0) {
+            sign = -1;
+        } 
+
+        if ( fabs( (float)h) <= 1.0 ) {
+            h  = (half)(sign * pow((float)fabs((float)h), 2.2f));
+        } else {
+            h  = (half)(sign * pow(logBase, (float)(fabs((float)h) - 1.0)));
+        }
+
+        {
+            char *tmp = (char *)(&toLinear[i]);
+
+            Xdr::write <CharPtrIO> ( tmp,  h.bits());
+        }
+    }
+#ifndef OPENEXR_BUILTIN_TABLES
+    printf("const unsigned short dwaCompressorToLinear[] = \n");
+    printf("{");
+    for (int i=0; i<65536; ++i) {
+        if (i % 8 == 0) {
+            printf("\n    ");
+        }
+        printf("0x%04x, ", toLinear[i]);
+    }
+    printf("\n};\n");
+#endif // OPENEXR_BUILTIN_TABLES
+}
+
+
+static void
+generateToNonlinear()
+{
+#ifndef OPENEXR_BUILTIN_TABLES
+    unsigned short toNonlinear[65536];
+#else
+    unsigned short* toNonlinear = dwaCompressorToNonlinear;
+#endif // OPENEXR_BUILTIN_TABLES
+
+    toNonlinear[0] = 0;
+
+    for (int i=1; i<65536; ++i) {
+        unsigned short usNative, usXdr;
+        half  h;
+        float sign    = 1;
+        float logBase = pow(2.7182818, 2.2);
+
+        usXdr           = i;
+
+        {
+            const char *tmp = (char *)(&usXdr);
+
+            Xdr::read<CharPtrIO>(tmp, usNative);
+        }
+
+        // map  NaN and inf to 0
+        if ((usNative & 0x7c00) == 0x7c00) {
+            toNonlinear[i] = 0;
+            continue;
+        }
+
+        //
+        // toNonlinear - assume i is XDR
+        //
+        h.setBits(usNative);
+        sign = 1;
+        if ((float)h < 0) {
+            sign = -1;
+        } 
+
+        if ( fabs( (float)h ) <= 1.0) {
+            h = (half)(sign * pow(fabs((float)h), 1.f/2.2f));
+        } else {
+            h = (half)(sign * ( log(fabs((float)h)) / log(logBase) + 1.0) );
+        }
+        toNonlinear[i] = h.bits();
+    }
+#ifndef OPENEXR_BUILTIN_TABLES
+    printf("const unsigned short dwaCompressorToNonlinear[] = \n");
+    printf("{");
+    for (int i=0; i<65536; ++i) {
+        if (i % 8 == 0) {
+            printf("\n    ");
+        }
+        printf("0x%04x, ", toNonlinear[i]);
+    }
+    printf("\n};\n");
+#endif // OPENEXR_BUILTIN_TABLES
+}
+
+
+#ifndef OPENEXR_BUILTIN_TABLES
+//
+// Attempt to get available CPUs in a somewhat portable way. 
+//
+
+int
+cpuCount()
+{
+    if (!ILMTHREAD_NAMESPACE::supportsThreads()) return 1;
+
+    int cpuCount = 1;
+
+#if defined (OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN)
+
+    cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
+
+#elif defined (_WIN32)
+
+    SYSTEM_INFO sysinfo;
+    GetSystemInfo( &sysinfo );
+    cpuCount = sysinfo.dwNumberOfProcessors;
+
+#endif
+
+    if (cpuCount < 1) cpuCount = 1;
+    return cpuCount;
+}
+
+//
+// Generate acceleration luts for the quantization.
+//
+// For each possible input value, we want to find the closest numbers
+// which have one fewer bits set than before. 
+//
+// This gives us num_bits(input)-1 values per input. If we alloc
+// space for everything, that's like a 2MB table. We can do better
+// by compressing all the values to be contigious and using offset
+// pointers.
+//
+// After we've found the candidates with fewer bits set, sort them
+// based on increasing numbers of bits set. This way, on quantize(),
+// we can scan through the list and halt once we find the first
+// candidate within the error range. For small values that can 
+// be quantized to 0, 0 is the first value tested and the search
+// can exit fairly quickly.
+//
+
+void
+generateLutHeader()
+{
+    std::vector<LutHeaderWorker*> workers;
+
+    size_t numWorkers     = cpuCount();
+    size_t workerInterval = 65536 / numWorkers;
+
+    for (size_t i=0; i<numWorkers; ++i) {
+        if (i != numWorkers-1) {
+            workers.push_back( new LutHeaderWorker( i   *workerInterval, 
+                                                   (i+1)*workerInterval) );
+        } else {
+            workers.push_back( new LutHeaderWorker(i*workerInterval, 65536) );
+        }
+    }
+
+    if (ILMTHREAD_NAMESPACE::supportsThreads()) {
+        std::vector<LutHeaderWorker::Runner*> runners;
+        for (size_t i=0; i<workers.size(); ++i) {
+            runners.push_back( new LutHeaderWorker::Runner(*workers[i], (i==0)) );
+        }
+
+        for (size_t i=0; i<workers.size(); ++i) {
+            delete runners[i];
+        }
+    } else {
+        for (size_t i=0; i<workers.size(); ++i) {
+            workers[i]->run(i == 0);
+        }
+    }
+
+    printf("static unsigned int closestDataOffset[] = {\n");
+    int offsetIdx  = 0;
+    int offsetPrev = 0;
+    for (size_t i=0; i<workers.size(); ++i) {
+        for (size_t value=0; value<workers[i]->numValues(); ++value) {
+            if (offsetIdx % 8 == 0) {
+                printf("    ");
+            }
+            printf("%6lu, ", workers[i]->offset()[value] + offsetPrev);
+            if (offsetIdx % 8 == 7) {
+                printf("\n");
+            }
+            offsetIdx++;
+        }
+        offsetPrev += workers[i]->offset()[workers[i]->numValues()-1] + 
+                      workers[i]->lastCandidateCount();
+    }
+    printf("};\n\n\n");
+
+
+    printf("static unsigned short closestData[] = {\n");
+    int elementIdx = 0;
+    for (size_t i=0; i<workers.size(); ++i) {
+        for (size_t element=0; element<workers[i]->numElements(); ++element) {
+            if (elementIdx % 8 == 0) {
+                printf("    ");
+            }
+            printf("%5d, ", workers[i]->elements()[element]);
+            if (elementIdx % 8 == 7) {
+                printf("\n");
+            }
+            elementIdx++;
+        }    
+    }
+    printf("};\n\n\n");
+
+    for (size_t i=0; i<workers.size(); ++i) {
+        delete workers[i];
+    }
+}
+
+
+int
+main(int argc, char **argv)
+{
+    printf("#include <cstddef>\n");
+    printf("\n\n\n");
+
+    generateNoop();
+
+    printf("\n\n\n");
+
+    generateToLinear();
+
+    printf("\n\n\n");
+
+    generateToNonlinear();
+
+    printf("\n\n\n");
+
+    generateLutHeader();
+
+    return 0;
+}
+#else // OPENEXR_BUILTIN_TABLES
+
+#include "dwaLookups.h"
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+static void init_dwa_()
+{
+    generateNoop();
+    generateToLinear();
+    generateToNonlinear();
+    // N/A: generateLutHeader();
+}
+
+static inline void init_dwa()
+{
+    static bool initialized = false;
+    if (!initialized)
+    {
+        init_dwa_();
+        initialized = true;
+    }
+}
+
+const unsigned short* get_dwaCompressorNoOp()
+{
+    init_dwa();
+    return dwaCompressorNoOp;
+}
+const unsigned short* get_dwaCompressorToLinear()
+{
+    init_dwa();
+    return dwaCompressorToLinear;
+}
+const unsigned short* get_dwaCompressorToNonlinear()
+{
+    init_dwa();
+    return dwaCompressorToNonlinear;
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+#endif // OPENEXR_BUILTIN_TABLES
diff --git a/3rdparty/openexr/IlmImf/dwaLookups.h b/3rdparty/openexr/IlmImf/dwaLookups.h
new file mode 100644 (file)
index 0000000..8f0da83
--- /dev/null
@@ -0,0 +1,22 @@
+#include "ImfHeader.h"
+#include "ImfNamespace.h"
+#include "ImfExport.h"
+
+#include <cstddef>
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
+
+
+const unsigned short* get_dwaCompressorNoOp();
+const unsigned short* get_dwaCompressorToLinear();
+const unsigned short* get_dwaCompressorToNonlinear();
+
+//const unsigned int* get_closestDataOffset();
+//const unsigned short* get_closestData();
+static inline
+const unsigned short* get_dwaClosest(int idx)
+{
+    throw std::runtime_error("OpenEXR: DW* compression tables are not available");
+}
+
+OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
index ef1ace1..45c958c 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 //-----------------------------------------------------------------------------
 //
-//     class Thread -- dummy implementation for
-//     platforms that do not support threading
+//     class Thread -- this file contains two implementations of thread:
+//     - dummy implementation for platforms that do not support threading
+//       when OPENEXR_FORCE_CXX03 is on
+//     - c++11 and newer version
 //
 //-----------------------------------------------------------------------------
 
 #include "IlmBaseConfig.h"
-
-#if !defined (_WIN32) && !defined(_WIN64) && !(HAVE_PTHREAD)
-
 #include "IlmThread.h"
 #include "Iex.h"
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+#ifndef ILMBASE_FORCE_CXX03
+//-----------------------------------------------------------------------------
+// C++11 and newer implementation
+//-----------------------------------------------------------------------------
+bool
+supportsThreads ()
+{
+    return true;
+}
+
+Thread::Thread ()
+{
+    // empty
+}
+
+
+Thread::~Thread ()
+{
+    // hopefully the thread has basically exited and we are just
+    // cleaning up, because run is a virtual function, so the v-table
+    // has already been partly destroyed...
+    if ( _thread.joinable () )
+        _thread.join ();
+}
 
 
+void
+Thread::start ()
+{
+    _thread = std::thread (&Thread::run, this);
+}
+
+#else
+#   if !defined (_WIN32) &&!(_WIN64) && !(HAVE_PTHREAD)
+//-----------------------------------------------------------------------------
+// OPENEXR_FORCE_CXX03 with no windows / pthread support
+//-----------------------------------------------------------------------------
 bool
 supportsThreads ()
 {
@@ -58,23 +93,24 @@ supportsThreads ()
 
 Thread::Thread ()
 {
-    throw Iex::NoImplExc ("Threads not supported on this platform.");
+    throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
 }
 
 
 Thread::~Thread ()
 {
-    throw Iex::NoImplExc ("Threads not supported on this platform.");
+    throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
 }
 
 
 void
 Thread::start ()
 {
-    throw Iex::NoImplExc ("Threads not supported on this platform.");
+    throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
 }
+#   endif
+#endif
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
-#endif
index dabe61a..26925aa 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include "IlmBaseConfig.h"
-
-#if defined _WIN32 || defined _WIN64
-    #ifdef NOMINMAX
-        #undef NOMINMAX
-    #endif
-    #define NOMINMAX
-    #include <windows.h>
-    #include <process.h>
-#elif HAVE_PTHREAD
-    #include <pthread.h>
-#endif
-
-#if defined(OPENEXR_DLL) && !defined(ZENO_STATIC)
-    #ifdef ILMTHREAD_EXPORTS
-    #define ILMTHREAD_EXPORT __declspec(dllexport)
-    #else
-    #define ILMTHREAD_EXPORT __declspec(dllimport)
-    #endif
+#include "IlmThreadExport.h"
+#include "IlmThreadNamespace.h"
+
+#ifdef ILMBASE_FORCE_CXX03
+#   if defined _WIN32 || defined _WIN64
+#       ifdef NOMINMAX
+#          undef NOMINMAX
+#       endif
+#       define NOMINMAX
+#       include <windows.h>
+#       include <process.h>
+#   elif HAVE_PTHREAD
+#      include <pthread.h>
+#   endif
 #else
-    #define ILMTHREAD_EXPORT
+#   include <thread>
 #endif
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
 // Query function to determine if the current platform supports
@@ -123,29 +119,35 @@ namespace IlmThread {
 ILMTHREAD_EXPORT bool supportsThreads ();
 
 
-class ILMTHREAD_EXPORT Thread
+class Thread
 {
   public:
 
-    Thread ();
-    virtual ~Thread ();
+    ILMTHREAD_EXPORT Thread ();
+    ILMTHREAD_EXPORT virtual ~Thread ();
 
-    void               start ();
-    virtual void       run () = 0;
+    ILMTHREAD_EXPORT void         start ();
+    ILMTHREAD_EXPORT virtual void run () = 0;
 
   private:
 
-    #if defined _WIN32 || defined _WIN64
-    HANDLE _thread;
-    #elif HAVE_PTHREAD
-    pthread_t _thread;
-    #endif
-
+#ifdef ILMBASE_FORCE_CXX03
+#   if defined _WIN32 || defined _WIN64
+       HANDLE _thread;
+#   elif HAVE_PTHREAD
+       pthread_t _thread;
+#   endif
     void operator = (const Thread& t); // not implemented
     Thread (const Thread& t);          // not implemented
+#else
+    std::thread _thread;
+
+    Thread &operator= (const Thread& t) = delete;
+    Thread (const Thread& t) = delete;
+#endif
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_H
diff --git a/3rdparty/openexr/IlmThread/IlmThreadExport.h b/3rdparty/openexr/IlmThread/IlmThreadExport.h
new file mode 100644 (file)
index 0000000..96d2200
--- /dev/null
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(ILMTHREAD_EXPORTS)
+           #define ILMTHREAD_EXPORT __declspec(dllexport)
+        #define ILMTHREAD_EXPORT_CONST extern __declspec(dllexport)
+    #else
+           #define ILMTHREAD_EXPORT __declspec(dllimport)
+           #define ILMTHREAD_EXPORT_CONST extern __declspec(dllimport)
+    #endif
+#else
+    #define ILMTHREAD_EXPORT
+    #define ILMTHREAD_EXPORT_CONST extern const
+#endif
diff --git a/3rdparty/openexr/IlmThread/IlmThreadForward.h b/3rdparty/openexr/IlmThread/IlmThreadForward.h
new file mode 100644 (file)
index 0000000..e57d596
--- /dev/null
@@ -0,0 +1,60 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_ILMTHREADFORWARD_H
+#define INCLUDED_ILMTHREADFORWARD_H
+
+#include "IlmThreadNamespace.h"
+
+#ifndef ILMBASE_FORCE_CXX03
+namespace std { class mutex; }
+#endif
+
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
+
+class Thread;
+#ifdef ILMBASE_FORCE_CXX03
+class Mutex;
+#else
+using Mutex = std::mutex;
+#endif
+class Lock;
+class ThreadPool;
+class Task;
+class TaskGroup;
+class Semaphore;
+
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_ILMTHREADFORWARD_H
index 331de07..f056f73 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "IlmBaseConfig.h"
 
-#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
-
-#include "IlmThreadMutex.h"
+#ifdef ILMBASE_FORCE_CXX03
+#   if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
+#      include "IlmThreadMutex.h"
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Mutex::Mutex () {}
@@ -54,6 +54,7 @@ void Mutex::lock () const {}
 void Mutex::unlock () const {}
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
+#   endif
 #endif
index df5729e..97c43bc 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -51,7 +51,7 @@
 //     share a Lock object among multiple threads.
 //
 //     Typical usage:
-//
+//    
 //         Mutex mtx;  // Create a Mutex object that is visible
 //                     //to multiple threads
 //
 //
 //-----------------------------------------------------------------------------
 
+#include "IlmThreadExport.h"
 #include "IlmBaseConfig.h"
-
-#if defined _WIN32 || defined _WIN64
-    #ifdef NOMINMAX
-        #undef NOMINMAX
-    #endif
-    #define NOMINMAX
-    #include <windows.h>
-#elif HAVE_PTHREAD
-    #include <pthread.h>
+#include "IlmThreadNamespace.h"
+
+#ifdef ILMBASE_FORCE_CXX03
+#   if defined _WIN32 || defined _WIN64
+#      ifdef NOMINMAX
+#         undef NOMINMAX
+#      endif
+#      define NOMINMAX
+#      include <windows.h>
+#   elif HAVE_PTHREAD
+#      include <pthread.h>
+#   endif
+#else
+#   include <mutex>
 #endif
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
-class Lock;
 
+// in c++11, this can just be
+//
+// using Mutex = std::mutex;
+// unfortunately we can't use std::unique_lock as a replacement for Lock since
+// they have different API.
+//
+// if we decide to break the API, we can just
+//
+// using Lock = std::lock_guard<std::mutex>;
+// or
+// using Lock = std::unique_lock<std::mutex>;
+//
+// (or eliminate the type completely and have people use the std library) 
+#ifdef ILMBASE_FORCE_CXX03
 
-class Mutex
+class Lock;
+
+class ILMTHREAD_EXPORT Mutex
 {
   public:
 
@@ -96,25 +117,26 @@ class Mutex
     void       unlock () const;
 
     #if defined _WIN32 || defined _WIN64
-    mutable CRITICAL_SECTION _mutex;
+       mutable CRITICAL_SECTION _mutex;
     #elif HAVE_PTHREAD
-    mutable pthread_mutex_t _mutex;
+       mutable pthread_mutex_t _mutex;
     #endif
 
     void operator = (const Mutex& M);  // not implemented
     Mutex (const Mutex& M);            // not implemented
-
+    
     friend class Lock;
 };
+#else
+using Mutex = std::mutex;
+#endif
 
-
-class Lock
+class ILMTHREAD_EXPORT Lock
 {
   public:
 
     Lock (const Mutex& m, bool autoLock = true):
-    _mutex (m),
-    _locked (false)
+        _mutex (const_cast<Mutex &>(m)), _locked (false)
     {
         if (autoLock)
         {
@@ -122,25 +144,25 @@ class Lock
             _locked = true;
         }
     }
-
+    
     ~Lock ()
     {
         if (_locked)
             _mutex.unlock();
     }
-
+    
     void acquire ()
     {
         _mutex.lock();
         _locked = true;
     }
-
+    
     void release ()
     {
         _mutex.unlock();
         _locked = false;
     }
-
+    
     bool locked ()
     {
         return _locked;
@@ -148,11 +170,11 @@ class Lock
 
   private:
 
-    const Mutex &      _mutex;
-    bool               _locked;
+    Mutex & _mutex;
+    bool    _locked;
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_MUTEX_H
index b2880cf..29a265a 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "IlmBaseConfig.h"
 
-#if HAVE_PTHREAD
+#ifdef ILMBASE_FORCE_CXX03
+#   if HAVE_PTHREAD
 
-#include "IlmThreadMutex.h"
-#include "Iex.h"
-#include <assert.h>
+#      include "IlmThreadMutex.h"
+#      include "Iex.h"
+#      include <assert.h>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Mutex::Mutex ()
 {
     if (int error = ::pthread_mutex_init (&_mutex, 0))
-        Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error);
+        IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot initialize mutex (%T).", error);
 }
 
 
@@ -68,7 +69,7 @@ void
 Mutex::lock () const
 {
     if (int error = ::pthread_mutex_lock (&_mutex))
-        Iex::throwErrnoExc ("Cannot lock mutex (%T).", error);
+        IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot lock mutex (%T).", error);
 }
 
 
@@ -76,10 +77,11 @@ void
 Mutex::unlock () const
 {
     if (int error = ::pthread_mutex_unlock (&_mutex))
-        Iex::throwErrnoExc ("Cannot unlock mutex (%T).", error);
+        IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot unlock mutex (%T).", error);
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
+#   endif
 #endif
index 0e30abf..2f7bc30 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
-#include "IlmThreadMutex.h"
-#include "Iex.h"
+#include "IlmBaseConfig.h"
 
-namespace IlmThread {
+#ifdef ILMBASE_FORCE_CXX03
+#   include "IlmThreadMutex.h"
+#   include "Iex.h"
+
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Mutex::Mutex ()
@@ -70,4 +73,6 @@ Mutex::unlock () const
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+#endif
diff --git a/3rdparty/openexr/IlmThread/IlmThreadNamespace.h b/3rdparty/openexr/IlmThread/IlmThreadNamespace.h
new file mode 100644 (file)
index 0000000..a412997
--- /dev/null
@@ -0,0 +1,114 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_ILMTHREADNAMESPACE_H
+#define INCLUDED_ILMTHREADNAMESPACE_H
+
+//
+// The purpose of this file is to make it possible to specify an
+// ILMTHREAD_INTERNAL_NAMESPACE as a preprocessor definition and have all of
+// the IlmThread symbols defined within that namespace rather than the
+// standard IlmThread namespace.  Those symbols are made available to client
+// code through the ILMTHREAD_NAMESPACE in addition to the
+// ILMTHREAD_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the ILMTHREAD_NAMESPACE defaults to
+// IlmThread and then "using namespace ILMTHREAD_INTERNAL_NAMESPACE;" brings
+// all of the declarations from the ILMTHREAD_INTERNAL_NAMESPACE into the
+// ILMTHREAD_NAMESPACE.  This means that client code can continue to use
+// syntax like IlmThread::Thread, but at link time it will resolve to a
+// mangled symbol based on the ILMTHREAD_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of IlmThread
+// and have it run alongside an older version in the same application, it is
+// now possible to use an internal namespace to prevent collisions between
+// the older versions of IlmThread symbols and the newer ones.  To do this,
+// the following could be defined at build time:
+//
+// ILMTHREAD_INTERNAL_NAMESPACE = IlmThread_v2
+//
+// This means that declarations inside IlmThread headers look like this
+// (after the preprocessor has done its work):
+//
+// namespace IlmThread_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace IlmThread {
+//     using namespace IlmThread_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the IlmBaseConfig.h file
+// for the configure time options.
+//
+#include "IlmBaseConfig.h"
+
+#ifndef ILMTHREAD_NAMESPACE
+#define ILMTHREAD_NAMESPACE IlmThread
+#endif
+
+#ifndef ILMTHREAD_INTERNAL_NAMESPACE
+#define ILMTHREAD_INTERNAL_NAMESPACE ILMTHREAD_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// ILMTHREAD_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// ILMTHREAD_NAMESPACE and pulls the internal symbols into the public
+// namespace.
+//
+
+namespace ILMTHREAD_INTERNAL_NAMESPACE {}
+namespace ILMTHREAD_NAMESPACE {
+     using namespace ILMTHREAD_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER namespace ILMTHREAD_INTERNAL_NAMESPACE {
+#define ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER namespace ILMTHREAD_INTERNAL_NAMESPACE {
+#define ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+#endif // INCLUDED_ILMTHREADNAMESPACE_H
index 3eb47d5..174ab98 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -34,7 +34,7 @@
 
 //-----------------------------------------------------------------------------
 //
-//     class Task, class ThreadPool, class TaskGroup
+//  class Task, class ThreadPool, class TaskGroup
 //
 //-----------------------------------------------------------------------------
 
 #include "IlmThreadSemaphore.h"
 #include "IlmThreadPool.h"
 #include "Iex.h"
-#include <list>
+#include <vector>
+#ifndef ILMBASE_FORCE_CXX03
+# include <memory>
+# include <atomic>
+# include <thread>
+#endif
 
 using namespace std;
 
-namespace IlmThread {
-namespace {
-
-class WorkerThread: public Thread
-{
-  public:
-
-    WorkerThread (ThreadPool::Data* data);
-
-    virtual void       run ();
-
-  private:
-
-    ThreadPool::Data * _data;
-};
-
-} //namespace
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+#if defined(__GNU_LIBRARY__) && ( __GLIBC__ < 2 || ( __GLIBC__ == 2 && __GLIBC_MINOR__ < 21 ) )
+# define ENABLE_SEM_DTOR_WORKAROUND
+#endif
 
 struct TaskGroup::Data
 {
      Data ();
     ~Data ();
-
-    void       addTask () ;
-    void       removeTask ();
-
-    Semaphore  isEmpty;        // used to signal that the taskgroup is empty
-    int                numPending;     // number of pending tasks to still execute
+    
+    void    addTask () ;
+    void    removeTask ();
+#ifndef ILMBASE_FORCE_CXX03
+    std::atomic<int> numPending;
+#else
+    int              numPending;     // number of pending tasks to still execute
+#endif
+    Semaphore        isEmpty;        // used to signal that the taskgroup is empty
+#if defined(ENABLE_SEM_DTOR_WORKAROUND) || defined(ILMBASE_FORCE_CXX03)
+    // this mutex is also used to lock numPending in the legacy c++ mode...
+    Mutex            dtorMutex;      // used to work around the glibc bug:
+                                     // http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
+#endif
 };
 
 
 struct ThreadPool::Data
 {
+    typedef ThreadPoolProvider *TPPointer;
+
      Data ();
     ~Data();
 
-    void       finish ();
-    bool       stopped () const;
-    void       stop ();
+    struct SafeProvider
+    {
+        SafeProvider (Data *d, ThreadPoolProvider *p) : _data( d ), _ptr( p )
+        {
+        }
+
+        ~SafeProvider()
+        {
+            if ( _data )
+                _data->coalesceProviderUse();
+        }
+        SafeProvider (const SafeProvider &o)
+            : _data( o._data ), _ptr( o._ptr )
+        {
+            if ( _data )
+                _data->bumpProviderUse();
+        }
+        SafeProvider &operator= (const SafeProvider &o)
+        {
+            if ( this != &o )
+            {
+                if ( o._data )
+                    o._data->bumpProviderUse();
+                if ( _data )
+                    _data->coalesceProviderUse();
+                _data = o._data;
+                _ptr = o._ptr;
+            }
+            return *this;
+        }
+#ifndef ILMBASE_FORCE_CXX03
+        SafeProvider( SafeProvider &&o )
+            : _data( o._data ), _ptr( o._ptr )
+        {
+            o._data = nullptr;
+        }
+        SafeProvider &operator=( SafeProvider &&o )
+        {
+            std::swap( _data, o._data );
+            std::swap( _ptr, o._ptr );
+            return *this;
+        }
+#endif
+        inline ThreadPoolProvider *get () const
+        {
+            return _ptr;
+        }
+        ThreadPoolProvider *operator-> () const
+        {
+            return get();
+        }
 
+        Data *_data;
+        ThreadPoolProvider *_ptr;
+    };
+
+    // NB: In C++20, there is full support for atomic shared_ptr, but that is not
+    // yet in use or finalized. Once stabilized, add appropriate usage here
+    inline SafeProvider getProvider ();
+    inline void coalesceProviderUse ();
+    inline void bumpProviderUse ();
+    inline void setProvider (ThreadPoolProvider *p);
+
+#ifdef ILMBASE_FORCE_CXX03
+    Semaphore provSem;
+    Mutex provMutex;
+    int provUsers;
+    ThreadPoolProvider *provider;
+    ThreadPoolProvider *oldprovider;
+#else
+    std::atomic<ThreadPoolProvider *> provider;
+    std::atomic<int> provUsers;
+#endif
+};
+
+
+
+namespace {
+
+class DefaultWorkerThread;
+
+struct DefaultWorkData
+{
     Semaphore taskSemaphore;        // threads wait on this for ready tasks
-    Mutex taskMutex;                // mutual exclusion for the tasks list
-    list<Task*> tasks;              // the list of tasks to execute
-    size_t numTasks;                // fast access to list size
-                                    //   (list::size() can be O(n))
+    mutable Mutex taskMutex;        // mutual exclusion for the tasks list
+    vector<Task*> tasks;            // the list of tasks to execute
 
     Semaphore threadSemaphore;      // signaled when a thread starts executing
-    Mutex threadMutex;              // mutual exclusion for threads list
-    list<WorkerThread*> threads;    // the list of all threads
-    size_t numThreads;              // fast access to list size
-
+    mutable Mutex threadMutex;      // mutual exclusion for threads list
+    vector<DefaultWorkerThread*> threads;  // the list of all threads
+    
+#ifdef ILMBASE_FORCE_CXX03
     bool stopping;                  // flag indicating whether to stop threads
-    Mutex stopMutex;                // mutual exclusion for stopping flag
-};
+    mutable Mutex stopMutex;        // mutual exclusion for stopping flag
+#else
+    std::atomic<bool> hasThreads;
+    std::atomic<bool> stopping;
+#endif
 
+    inline bool stopped () const
+    {
+#ifdef ILMBASE_FORCE_CXX03
+        Lock lock (stopMutex);
+        return stopping;
+#else
+        return stopping.load( std::memory_order_relaxed );
+#endif
+    }
 
+    inline void stop ()
+    {
+#ifdef ILMBASE_FORCE_CXX03
+        Lock lock (stopMutex);
+#endif
+        stopping = true;
+    }
+};
 
 //
 // class WorkerThread
 //
+class DefaultWorkerThread: public Thread
+{
+  public:
 
-WorkerThread::WorkerThread (ThreadPool::Data* data):
+    DefaultWorkerThread (DefaultWorkData* data);
+
+    virtual void    run ();
+    
+  private:
+
+    DefaultWorkData *  _data;
+};
+
+
+DefaultWorkerThread::DefaultWorkerThread (DefaultWorkData* data):
     _data (data)
 {
     start();
@@ -117,7 +229,7 @@ WorkerThread::WorkerThread (ThreadPool::Data* data):
 
 
 void
-WorkerThread::run ()
+DefaultWorkerThread::run ()
 {
     //
     // Signal that the thread has started executing
@@ -127,41 +239,221 @@ WorkerThread::run ()
 
     while (true)
     {
-    //
+        //
         // Wait for a task to become available
-    //
+        //
 
         _data->taskSemaphore.wait();
 
         {
             Lock taskLock (_data->taskMutex);
-
-        //
+    
+            //
             // If there is a task pending, pop off the next task in the FIFO
-        //
+            //
 
-            if (_data->numTasks > 0)
+            if (!_data->tasks.empty())
             {
-                Task* task = _data->tasks.front();
-        TaskGroup* taskGroup = task->group();
-                _data->tasks.pop_front();
-                _data->numTasks--;
-
+                Task* task = _data->tasks.back();
+                _data->tasks.pop_back();
                 taskLock.release();
+
+                TaskGroup* taskGroup = task->group();
                 task->execute();
-                taskLock.acquire();
 
                 delete task;
-                taskGroup->_data->removeTask();
+
+                taskGroup->_data->removeTask ();
             }
             else if (_data->stopped())
-        {
+            {
                 break;
+            }
         }
+    }
+}
+
+
+//
+// class DefaultThreadPoolProvider
+//
+class DefaultThreadPoolProvider : public ThreadPoolProvider
+{
+  public:
+    DefaultThreadPoolProvider(int count);
+    virtual ~DefaultThreadPoolProvider();
+
+    virtual int numThreads() const;
+    virtual void setNumThreads(int count);
+    virtual void addTask(Task *task);
+
+    virtual void finish();
+
+  private:
+    DefaultWorkData _data;
+};
+
+DefaultThreadPoolProvider::DefaultThreadPoolProvider (int count)
+{
+    setNumThreads(count);
+}
+
+DefaultThreadPoolProvider::~DefaultThreadPoolProvider ()
+{
+    finish();
+}
+
+int
+DefaultThreadPoolProvider::numThreads () const
+{
+    Lock lock (_data.threadMutex);
+    return static_cast<int> (_data.threads.size());
+}
+
+void
+DefaultThreadPoolProvider::setNumThreads (int count)
+{
+    //
+    // Lock access to thread list and size
+    //
+
+    Lock lock (_data.threadMutex);
+
+    size_t desired = static_cast<size_t>(count);
+    if (desired > _data.threads.size())
+    {
+        //
+        // Add more threads
+        //
+
+        while (_data.threads.size() < desired)
+            _data.threads.push_back (new DefaultWorkerThread (&_data));
+    }
+    else if ((size_t)count < _data.threads.size())
+    {
+        //
+        // Wait until all existing threads are finished processing,
+        // then delete all threads.
+        //
+        finish ();
+
+        //
+        // Add in new threads
+        //
+
+        while (_data.threads.size() < desired)
+            _data.threads.push_back (new DefaultWorkerThread (&_data));
+    }
+#ifndef ILMBASE_FORCE_CXX03
+    _data.hasThreads = !(_data.threads.empty());
+#endif
+}
+
+void
+DefaultThreadPoolProvider::addTask (Task *task)
+{
+    //
+    // Lock the threads, needed to access numThreads
+    //
+#ifdef ILMBASE_FORCE_CXX03
+    bool doPush;
+    {
+        Lock lock (_data.threadMutex);
+        doPush = !_data.threads.empty();
+    }
+#else
+    bool doPush = _data.hasThreads.load( std::memory_order_relaxed );
+#endif
+
+    if ( doPush )
+    {
+        //
+        // Get exclusive access to the tasks queue
+        //
+
+        {
+            Lock taskLock (_data.taskMutex);
+
+            //
+            // Push the new task into the FIFO
+            //
+            _data.tasks.push_back (task);
         }
+        
+        //
+        // Signal that we have a new task to process
+        //
+        _data.taskSemaphore.post ();
+    }
+    else
+    {
+        // this path shouldn't normally happen since we have the
+        // NullThreadPoolProvider, but just in case...
+        task->execute ();
+        task->group()->_data->removeTask ();
+        delete task;
     }
 }
 
+void
+DefaultThreadPoolProvider::finish ()
+{
+    _data.stop();
+
+    //
+    // Signal enough times to allow all threads to stop.
+    //
+    // Wait until all threads have started their run functions.
+    // If we do not wait before we destroy the threads then it's
+    // possible that the threads have not yet called their run
+    // functions.
+    // If this happens then the run function will be called off
+    // of an invalid object and we will crash, most likely with
+    // an error like: "pure virtual method called"
+    //
+
+    size_t curT = _data.threads.size();
+    for (size_t i = 0; i != curT; ++i)
+    {
+        _data.taskSemaphore.post();
+        _data.threadSemaphore.wait();
+    }
+
+    //
+    // Join all the threads
+    //
+    for (size_t i = 0; i != curT; ++i)
+        delete _data.threads[i];
+
+    Lock lock1 (_data.taskMutex);
+#ifdef ILMBASE_FORCE_CXX03
+    Lock lock2 (_data.stopMutex);
+#endif
+    _data.threads.clear();
+    _data.tasks.clear();
+
+    _data.stopping = false;
+}
+
+
+class NullThreadPoolProvider : public ThreadPoolProvider
+{
+    virtual ~NullThreadPoolProvider() {}
+    virtual int numThreads () const { return 0; }
+    virtual void setNumThreads (int count)
+    {
+    }
+    virtual void addTask (Task *t)
+    {
+        t->execute ();
+        t->group()->_data->removeTask ();
+        delete t;
+    }
+    virtual void finish () {}
+}; 
+
+} //namespace
+
 
 //
 // struct TaskGroup::Data
@@ -182,36 +474,89 @@ TaskGroup::Data::~Data ()
     //
 
     isEmpty.wait ();
+
+#ifdef ENABLE_SEM_DTOR_WORKAROUND
+    // Update: this was fixed in v. 2.2.21, so this ifdef checks for that
+    //
+    // Alas, given the current bug in glibc we need a secondary
+    // syncronisation primitive here to account for the fact that
+    // destructing the isEmpty Semaphore in this thread can cause
+    // an error for a separate thread that is issuing the post() call.
+    // We are entitled to destruct the semaphore at this point, however,
+    // that post() call attempts to access data out of the associated
+    // memory *after* it has woken the waiting threads, including this one,
+    // potentially leading to invalid memory reads.
+    // http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
+
+    Lock lock (dtorMutex);
+#endif
 }
 
 
 void
-TaskGroup::Data::addTask ()
+TaskGroup::Data::addTask () 
 {
     //
-    // Any access to the taskgroup is protected by a mutex that is
-    // held by the threadpool.  Therefore it is safe to access
-    // numPending before we wait on the semaphore.
+    // in c++11, we use an atomic to protect numPending to avoid the
+    // extra lock but for c++98, to add the ability for custom thread
+    // pool we add the lock here
     //
-
+#if ILMBASE_FORCE_CXX03
+    Lock lock (dtorMutex);
+#endif
     if (numPending++ == 0)
-    isEmpty.wait ();
+        isEmpty.wait ();
 }
 
 
 void
 TaskGroup::Data::removeTask ()
 {
+    // Alas, given the current bug in glibc we need a secondary
+    // syncronisation primitive here to account for the fact that
+    // destructing the isEmpty Semaphore in a separate thread can
+    // cause an error. Issuing the post call here the current libc
+    // implementation attempts to access memory *after* it has woken
+    // waiting threads.
+    // Since other threads are entitled to delete the semaphore the
+    // access to the memory location can be invalid.
+    // http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
+    // Update: this bug has been fixed, but how do we know which
+    // glibc version we're in?
+
+    // Further update:
+    //
+    // we could remove this if it is a new enough glibc, however 
+    // we've changed the API to enable a custom override of a
+    // thread pool. In order to provide safe access to the numPending,
+    // we need the lock anyway, except for c++11 or newer
+#ifdef ILMBASE_FORCE_CXX03
+    Lock lock (dtorMutex);
+
     if (--numPending == 0)
-    isEmpty.post ();
+        isEmpty.post ();
+#else
+    if (--numPending == 0)
+    {
+#ifdef ENABLE_SEM_DTOR_WORKAROUND
+        Lock lock (dtorMutex);
+#endif
+        isEmpty.post ();
+    }
+#endif
 }
-
+    
 
 //
 // struct ThreadPool::Data
 //
 
-ThreadPool::Data::Data (): numTasks (0), numThreads (0), stopping (false)
+ThreadPool::Data::Data ():
+    provUsers (0), provider (NULL)
+#ifdef ILMBASE_FORCE_CXX03
+    , oldprovider (NULL)
+#else
+#endif
 {
     // empty
 }
@@ -219,70 +564,130 @@ ThreadPool::Data::Data (): numTasks (0), numThreads (0), stopping (false)
 
 ThreadPool::Data::~Data()
 {
-    Lock lock (threadMutex);
-    finish ();
+#ifdef ILMBASE_FORCE_CXX03
+    provider->finish();
+#else
+    ThreadPoolProvider *p = provider.load( std::memory_order_relaxed );
+    p->finish();
+#endif
 }
 
-
-void
-ThreadPool::Data::finish ()
+inline ThreadPool::Data::SafeProvider
+ThreadPool::Data::getProvider ()
 {
-    stop();
+#ifdef ILMBASE_FORCE_CXX03
+    Lock provLock( provMutex );
+    ++provUsers;
+    return SafeProvider( this, provider );
+#else
+    provUsers.fetch_add( 1, std::memory_order_relaxed );
+    return SafeProvider( this, provider.load( std::memory_order_relaxed ) );
+#endif
+}
 
-    //
-    // Signal enough times to allow all threads to stop.
-    //
-    // Wait until all threads have started their run functions.
-    // If we do not wait before we destroy the threads then it's
-    // possible that the threads have not yet called their run
-    // functions.
-    // If this happens then the run function will be called off
-    // of an invalid object and we will crash, most likely with
-    // an error like: "pure virtual method called"
-    //
 
-    for (size_t i = 0; i < numThreads; i++)
+inline void
+ThreadPool::Data::coalesceProviderUse ()
+{
+#ifdef ILMBASE_FORCE_CXX03
+    Lock provLock( provMutex );
+    --provUsers;
+    if ( provUsers == 0 )
     {
-    taskSemaphore.post();
-    threadSemaphore.wait();
+        if ( oldprovider )
+            provSem.post();
     }
-
-    //
-    // Join all the threads
-    //
-
-    for (list<WorkerThread*>::iterator i = threads.begin();
-     i != threads.end();
-     ++i)
+#else
+    int ov = provUsers.fetch_sub( 1, std::memory_order_relaxed );
+    // ov is the previous value, so one means that now it might be 0
+    if ( ov == 1 )
     {
-    delete (*i);
+        
     }
-
-    Lock lock1 (taskMutex);
-    Lock lock2 (stopMutex);
-    threads.clear();
-    tasks.clear();
-    numThreads = 0;
-    numTasks = 0;
-    stopping = false;
+#endif
 }
 
 
-bool
-ThreadPool::Data::stopped () const
+inline void
+ThreadPool::Data::bumpProviderUse ()
 {
-    Lock lock (stopMutex);
-    return stopping;
+#ifdef ILMBASE_FORCE_CXX03
+    Lock lock (provMutex);
+    ++provUsers;
+#else
+    provUsers.fetch_add( 1, std::memory_order_relaxed );
+#endif
 }
 
 
-void
-ThreadPool::Data::stop ()
+inline void
+ThreadPool::Data::setProvider (ThreadPoolProvider *p)
 {
-    Lock lock (stopMutex);
-    stopping = true;
-}
+#ifdef ILMBASE_FORCE_CXX03
+    Lock provLock( provMutex );
+
+    if ( oldprovider )
+        throw IEX_INTERNAL_NAMESPACE::ArgExc ("Attempt to set the thread pool provider while"
+                                              " another thread is currently setting the provider.");
+
+    oldprovider = provider;
+    provider = p;
+
+    while ( provUsers > 0 )
+    {
+        provLock.release();
+        provSem.wait();
+        provLock.acquire();
+    }
+    if ( oldprovider )
+    {
+        oldprovider->finish();
+        delete oldprovider;
+        oldprovider = NULL;
+    }
+#else
+    ThreadPoolProvider *old = provider.load( std::memory_order_relaxed );
+    do
+    {
+        if ( ! provider.compare_exchange_weak( old, p, std::memory_order_release, std::memory_order_relaxed ) )
+            continue;
+    } while ( false );
 
+    // wait for any other users to finish prior to deleting, given
+    // that these are just mostly to query the thread count or push a
+    // task to the queue (so fast), just spin...
+    //
+    // (well, and normally, people don't do this mid stream anyway, so
+    // this will be 0 99.999% of the time, but just to be safe)
+    // 
+    while ( provUsers.load( std::memory_order_relaxed ) > 0 )
+        std::this_thread::yield();
+
+    if ( old )
+    {
+        old->finish();
+        delete old;
+    }
+
+    // NB: the shared_ptr mechanism is safer and means we don't have
+    // to have the provUsers counter since the shared_ptr keeps that
+    // for us. However, gcc 4.8/9 compilers which many people are
+    // still using even though it is 2018 forgot to add the shared_ptr
+    // functions... once that compiler is fully deprecated, switch to
+    // using the below, change provider to a std::shared_ptr and remove
+    // provUsers...
+    //
+//    std::shared_ptr<ThreadPoolProvider> newp( p );
+//    std::shared_ptr<ThreadPoolProvider> curp = std::atomic_load_explicit( &provider, std::memory_order_relaxed );
+//    do
+//    {
+//        if ( ! std::atomic_compare_exchange_weak_explicit( &provider, &curp, newp, std::memory_order_release, std::memory_order_relaxed ) )
+//            continue;
+//    } while ( false );
+//    if ( curp )
+//        curp->finish();
+#endif
+}
 
 //
 // class Task
@@ -290,7 +695,8 @@ ThreadPool::Data::stop ()
 
 Task::Task (TaskGroup* g): _group(g)
 {
-    // empty
+    if ( g )
+        g->_data->addTask ();
 }
 
 
@@ -320,14 +726,38 @@ TaskGroup::~TaskGroup ()
 }
 
 
+void
+TaskGroup::finishOneTask ()
+{
+    _data->removeTask ();
+}
+
+//
+// class ThreadPoolProvider
+//
+
+
+ThreadPoolProvider::ThreadPoolProvider()
+{
+}
+
+
+ThreadPoolProvider::~ThreadPoolProvider()
+{
+}
+
+
 //
 // class ThreadPool
 //
 
 ThreadPool::ThreadPool (unsigned nthreads):
-    _data (new Data())
+    _data (new Data)
 {
-    setNumThreads (nthreads);
+    if ( nthreads == 0 )
+        _data->setProvider( new NullThreadPoolProvider );
+    else
+        _data->setProvider( new DefaultThreadPoolProvider( int(nthreads) ) );
 }
 
 
@@ -340,8 +770,7 @@ ThreadPool::~ThreadPool ()
 int
 ThreadPool::numThreads () const
 {
-    Lock lock (_data->threadMutex);
-    return _data->numThreads;
+    return _data->getProvider ()->numThreads ();
 }
 
 
@@ -349,87 +778,53 @@ void
 ThreadPool::setNumThreads (int count)
 {
     if (count < 0)
-        throw Iex::ArgExc ("Attempt to set the number of threads "
+        throw IEX_INTERNAL_NAMESPACE::ArgExc ("Attempt to set the number of threads "
                "in a thread pool to a negative value.");
 
-    //
-    // Lock access to thread list and size
-    //
-
-    Lock lock (_data->threadMutex);
-
-    if ((size_t)count > _data->numThreads)
+    bool doReset = false;
     {
-    //
-        // Add more threads
-    //
+        Data::SafeProvider sp = _data->getProvider ();
+        int curT = sp->numThreads ();
+        if ( curT == count )
+            return;
 
-        while (_data->numThreads < (size_t)count)
+        if ( curT == 0 )
         {
-            _data->threads.push_back (new WorkerThread (_data));
-            _data->numThreads++;
+            NullThreadPoolProvider *npp = dynamic_cast<NullThreadPoolProvider *>( sp.get() );
+            if ( npp )
+                doReset = true;
         }
-    }
-    else if ((size_t)count < _data->numThreads)
-    {
-    //
-    // Wait until all existing threads are finished processing,
-    // then delete all threads.
-    //
-
-        _data->finish ();
-
-    //
-        // Add in new threads
-    //
-
-        while (_data->numThreads < (size_t)count)
+        else if ( count == 0 )
         {
-            _data->threads.push_back (new WorkerThread (_data));
-            _data->numThreads++;
+            DefaultThreadPoolProvider *dpp = dynamic_cast<DefaultThreadPoolProvider *>( sp.get() );
+            if ( dpp )
+                doReset = true;
         }
+        if ( ! doReset )
+            sp->setNumThreads( count );
     }
-}
-
 
-void
-ThreadPool::addTask (Task* task)
-{
-    //
-    // Lock the threads, needed to access numThreads
-    //
-
-    Lock lock (_data->threadMutex);
-
-    if (_data->numThreads == 0)
+    if ( doReset )
     {
-        task->execute ();
-        delete task;
+        if ( count == 0 )
+            _data->setProvider( new NullThreadPoolProvider );
+        else
+            _data->setProvider( new DefaultThreadPoolProvider( count ) );
     }
-    else
-    {
-    //
-        // Get exclusive access to the tasks queue
-    //
+}
 
-        {
-            Lock taskLock (_data->taskMutex);
 
-        //
-            // Push the new task into the FIFO
-        //
-
-            _data->tasks.push_back (task);
-            _data->numTasks++;
-            task->group()->_data->addTask();
-        }
+void
+ThreadPool::setThreadProvider (ThreadPoolProvider *provider)
+{
+    _data->setProvider (provider);
+}
 
-    //
-        // Signal that we have a new task to process
-    //
 
-        _data->taskSemaphore.post ();
-    }
+void
+ThreadPool::addTask (Task* task) 
+{
+    _data->getProvider ()->addTask (task);
 }
 
 
@@ -439,7 +834,7 @@ ThreadPool::globalThreadPool ()
     //
     // The global thread pool
     //
-
+    
     static ThreadPool gThreadPool (0);
 
     return gThreadPool;
@@ -453,4 +848,4 @@ ThreadPool::addGlobalTask (Task* task)
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
index e806db9..85b3de2 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #ifndef INCLUDED_ILM_THREAD_POOL_H
 #define INCLUDED_ILM_THREAD_POOL_H
 
+
 //-----------------------------------------------------------------------------
 //
 //     class Task, class ThreadPool, class TaskGroup
 //
 //     Class ThreadPool manages a set of worker threads and accepts
 //     tasks for processing.  Tasks added to the thread pool are
-//     executed concurrently by the worker threads.
-//
-//     Class Thread provides an abstract interface for a task which
+//     executed concurrently by the worker threads.  
+//     
+//     Class Task provides an abstract interface for a task which
 //     a ThreadPool works on.  Derived classes need to implement the
 //     execute() function which performs the actual task.
 //
-//     Class TaskTroup allows synchronization on the completion of a set
+//     Class TaskGroup allows synchronization on the completion of a set
 //     of tasks.  Every task that is added to a ThreadPool belongs to a
 //     single TaskGroup.  The destructor of the TaskGroup waits for all
 //     tasks in the group to finish.
 //
 //-----------------------------------------------------------------------------
 
-namespace IlmThread {
+#include "IlmThreadNamespace.h"
+#include "IlmThreadExport.h"
+
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
 class TaskGroup;
 class Task;
 
+//-------------------------------------------------------
+// ThreadPoolProvider -- this is a pure virtual interface
+// enabling custom overloading of the threads used and how
+// the implementation of the processing of tasks
+// is implemented
+//-------------------------------------------------------
+class ILMTHREAD_EXPORT ThreadPoolProvider
+{
+  public:
+    ThreadPoolProvider();
+    virtual ~ThreadPoolProvider();
+
+    // as in ThreadPool below
+    virtual int numThreads () const = 0;
+    // as in ThreadPool below
+    virtual void setNumThreads (int count) = 0;
+    // as in ThreadPool below
+    virtual void addTask (Task* task) = 0;
+
+    // Ensure that all tasks in this set are finished
+    // and threads shutdown
+    virtual void finish () = 0;
+
+    // Make the provider non-copyable
+#if __cplusplus >= 201103L
+    ThreadPoolProvider (const ThreadPoolProvider &) = delete;
+    ThreadPoolProvider &operator= (const ThreadPoolProvider &) = delete;
+    ThreadPoolProvider (ThreadPoolProvider &&) = delete;
+    ThreadPoolProvider &operator= (ThreadPoolProvider &&) = delete;
+#else
+  private:
+    ThreadPoolProvider (const ThreadPoolProvider &);
+    ThreadPoolProvider &operator= (const ThreadPoolProvider &);
+#endif
+};  
 
-class ThreadPool
+class ILMTHREAD_EXPORT ThreadPool  
 {
   public:
 
+
     //-------------------------------------------------------
     // Constructor -- creates numThreads worker threads which
-    // wait until a task is available.
+    // wait until a task is available,
+    // using a default ThreadPoolProvider
     //-------------------------------------------------------
 
     ThreadPool (unsigned numThreads = 0);
@@ -84,7 +125,7 @@ class ThreadPool
     //-----------------------------------------------------------
 
     virtual ~ThreadPool ();
-
+    
 
     //--------------------------------------------------------
     // Query and set the number of worker threads in the pool.
@@ -93,10 +134,22 @@ class ThreadPool
     // thread as this will almost certainly cause a deadlock
     // or crash.
     //--------------------------------------------------------
-
+    
     int                numThreads () const;
     void       setNumThreads (int count);
 
+    //--------------------------------------------------------
+    // Set the thread provider for the pool.
+    //
+    // The ThreadPool takes ownership of the ThreadPoolProvider
+    // and will call delete on it when it is finished or when
+    // it is changed
+    //
+    // Warning: never call setThreadProvider from within a worker
+    // thread as this will almost certainly cause a deadlock
+    // or crash.
+    //--------------------------------------------------------
+    void    setThreadProvider (ThreadPoolProvider *provider);
 
     //------------------------------------------------------------
     // Add a task for processing.  The ThreadPool can handle any
@@ -106,12 +159,12 @@ class ThreadPool
     //------------------------------------------------------------
 
     void addTask (Task* task);
-
+    
 
     //-------------------------------------------
     // Access functions for the global threadpool
     //-------------------------------------------
-
+    
     static ThreadPool& globalThreadPool ();
     static void                addGlobalTask (Task* task);
 
@@ -123,7 +176,7 @@ class ThreadPool
 };
 
 
-class Task
+class ILMTHREAD_EXPORT Task
 {
   public:
 
@@ -139,18 +192,23 @@ class Task
 };
 
 
-class TaskGroup
+class ILMTHREAD_EXPORT TaskGroup
 {
   public:
 
-     TaskGroup();
+    TaskGroup();
     ~TaskGroup();
 
+    // marks one task as finished
+    // should be used by the thread pool provider to notify
+    // as it finishes tasks
+    void finishOneTask ();
+
     struct Data;
     Data* const                _data;
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_POOL_H
index 6b6f1ae..4aee3f3 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -42,6 +42,7 @@
 #include "IlmBaseConfig.h"
 
 #if HAVE_PTHREAD
+#ifdef ILMBASE_FORCE_CXX03
 
 #include "IlmThread.h"
 #include "Iex.h"
@@ -52,7 +53,7 @@ extern "C"
     typedef void * (* Start) (void *);
 }
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
@@ -89,10 +90,11 @@ void
 Thread::start ()
 {
     if (int error = ::pthread_create (&_thread, 0, Start (threadLoop), this))
-    Iex::throwErrnoExc ("Cannot create new thread (%T).", error);
+       IEX_NAMESPACE::throwErrnoExc ("Cannot create new thread (%T).", error);
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
+#endif
index de8998a..26ae763 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -44,7 +44,7 @@
 #if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
 #include "IlmThreadSemaphore.h"
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Semaphore::Semaphore (unsigned int value) {}
@@ -55,6 +55,6 @@ void Semaphore::post () {}
 int Semaphore::value () const {return 0;}
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
index 8e13cf9..adc52cd 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 #include "IlmBaseConfig.h"
+#include "IlmThreadExport.h"
+#include "IlmThreadNamespace.h"
 
 #if defined _WIN32 || defined _WIN64
-    #ifdef NOMINMAX
-        #undef NOMINMAX
-    #endif
-    #define NOMINMAX
-    #include <windows.h>
-#elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
-    #include <pthread.h>
-#elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES
-    #include <semaphore.h>
+#   ifdef NOMINMAX
+#      undef NOMINMAX
+#   endif
+#   define NOMINMAX
+#   include <windows.h>
+#elif HAVE_POSIX_SEMAPHORES
+#   include <semaphore.h>
+#else
+#   ifdef ILMBASE_FORCE_CXX03
+#      if HAVE_PTHREAD
+#         include <pthread.h>
+#      endif
+#   else
+#      include <mutex>
+#      include <condition_variable>
+#   endif
 #endif
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-class Semaphore
+class ILMTHREAD_EXPORT Semaphore
 {
   public:
 
@@ -73,38 +82,46 @@ class Semaphore
 
   private:
 
-    #if defined _WIN32 || defined _WIN64
-
-    mutable HANDLE _semaphore;
-
-    #elif HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
-
-    //
-    // If the platform has Posix threads but no semapohores,
-    // then we implement them ourselves using condition variables
-    //
-
-    struct sema_t
-    {
-        unsigned int count;
-        unsigned long numWaiting;
-        pthread_mutex_t mutex;
-        pthread_cond_t nonZero;
-    };
-
-    mutable sema_t _semaphore;
-
-    #elif HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES
-
-    mutable sem_t _semaphore;
+#if defined _WIN32 || defined _WIN64
 
-    #endif
+       mutable HANDLE _semaphore;
+
+#elif HAVE_POSIX_SEMAPHORES
+
+       mutable sem_t _semaphore;
+
+#else
+       //
+       // If the platform has Posix threads but no semapohores,
+       // then we implement them ourselves using condition variables
+       //
+
+       struct sema_t
+       {
+           unsigned int count;
+           unsigned long numWaiting;
+#   if ILMBASE_FORCE_CXX03
+#      if HAVE_PTHREAD
+           pthread_mutex_t mutex;
+           pthread_cond_t nonZero;
+#      else
+#         error unhandled legacy setup
+#      endif
+#   else
+        std::mutex mutex;
+        std::condition_variable nonZero;
+#   endif
+       };
+
+       mutable sema_t _semaphore;
+  
+#endif
 
     void operator = (const Semaphore& s);      // not implemented
     Semaphore (const Semaphore& s);            // not implemented
 };
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_ILM_THREAD_SEMAPHORE_H
index 745819f..400d90e 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include "IlmThreadSemaphore.h"
 #include "Iex.h"
 #include <assert.h>
+#include <errno.h>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Semaphore::Semaphore (unsigned int value)
 {
     if (::sem_init (&_semaphore, 0, value))
-    Iex::throwErrnoExc ("Cannot initialize semaphore (%T).");
+       IEX_NAMESPACE::throwErrnoExc ("Cannot initialize semaphore (%T).");
 }
 
 
@@ -67,7 +68,9 @@ Semaphore::~Semaphore ()
 void
 Semaphore::wait ()
 {
-    ::sem_wait (&_semaphore);
+    while( ::sem_wait( &_semaphore ) == -1 && errno == EINTR )
+    {
+    }
 }
 
 
@@ -82,7 +85,7 @@ void
 Semaphore::post ()
 {
     if (::sem_post (&_semaphore))
-        Iex::throwErrnoExc ("Post operation on semaphore failed (%T).");
+        IEX_NAMESPACE::throwErrnoExc ("Post operation on semaphore failed (%T).");
 }
 
 
@@ -92,12 +95,12 @@ Semaphore::value () const
     int value;
 
     if (::sem_getvalue (&_semaphore, &value))
-        Iex::throwErrnoExc ("Cannot read semaphore value (%T).");
+        IEX_NAMESPACE::throwErrnoExc ("Cannot read semaphore value (%T).");
 
     return value;
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
index 56769e7..fa41bb6 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "IlmBaseConfig.h"
 
-#if HAVE_PTHREAD && !HAVE_POSIX_SEMAPHORES
+#if (!HAVE_POSIX_SEMAPHORES) && !defined (_WIN32) && ! defined (_WIN64)
 
 #include "IlmThreadSemaphore.h"
 #include "Iex.h"
 #include <assert.h>
 
-namespace IlmThread {
-
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
+#if ILMBASE_FORCE_CXX03 && HAVE_PTHREAD
 Semaphore::Semaphore (unsigned int value)
 {
     if (int error = ::pthread_mutex_init (&_semaphore.mutex, 0))
-        Iex::throwErrnoExc ("Cannot initialize mutex (%T).", error);
+        IEX_NAMESPACE::throwErrnoExc ("Cannot initialize mutex (%T).", error);
 
     if (int error = ::pthread_cond_init (&_semaphore.nonZero, 0))
-        Iex::throwErrnoExc ("Cannot initialize condition variable (%T).",
+        IEX_NAMESPACE::throwErrnoExc ("Cannot initialize condition variable (%T).",
                             error);
 
     _semaphore.count = value;
@@ -85,12 +85,12 @@ Semaphore::wait ()
     {
         if (int error = ::pthread_cond_wait (&_semaphore.nonZero,
                                              &_semaphore.mutex))
-    {
+        {
             ::pthread_mutex_unlock (&_semaphore.mutex);
 
-            Iex::throwErrnoExc ("Cannot wait on condition variable (%T).",
-                                error);
-    }
+            IEX_NAMESPACE::throwErrnoExc ("Cannot wait on condition variable (%T).",
+                                          error);
+        }
     }
 
     _semaphore.numWaiting--;
@@ -104,7 +104,7 @@ bool
 Semaphore::tryWait ()
 {
     ::pthread_mutex_lock (&_semaphore.mutex);
-
+    
     if (_semaphore.count == 0)
     {
         ::pthread_mutex_unlock (&_semaphore.mutex);
@@ -126,13 +126,22 @@ Semaphore::post ()
 
     if (_semaphore.numWaiting > 0)
     {
-        if (int error = ::pthread_cond_signal (&_semaphore.nonZero))
-    {
+        int error;
+        if (_semaphore.numWaiting > 1 && _semaphore.count > 1)
+        {
+            error =  ::pthread_cond_broadcast (&_semaphore.nonZero);
+        }
+        else
+        {
+            error = ::pthread_cond_signal (&_semaphore.nonZero);
+        }
+        if (error)
+        {
             ::pthread_mutex_unlock (&_semaphore.mutex);
 
-            Iex::throwErrnoExc ("Cannot signal condition variable (%T).",
+            IEX_NAMESPACE::throwErrnoExc ("Cannot signal condition variable (%T).",
                                 error);
-    }
+        }
     }
 
     _semaphore.count++;
@@ -148,8 +157,71 @@ Semaphore::value () const
     ::pthread_mutex_unlock (&_semaphore.mutex);
     return value;
 }
+#else
+Semaphore::Semaphore (unsigned int value)
+{
+    _semaphore.count = value;
+    _semaphore.numWaiting = 0;
+}
+
+
+Semaphore::~Semaphore ()
+{
+}
+
+
+void
+Semaphore::wait ()
+{
+    std::unique_lock<std::mutex> lk(_semaphore.mutex);
+
+    _semaphore.numWaiting++;
+
+    while (_semaphore.count == 0)
+        _semaphore.nonZero.wait (lk);
+
+    _semaphore.numWaiting--;
+    _semaphore.count--;
+}
+
+
+bool
+Semaphore::tryWait ()
+{
+    std::lock_guard<std::mutex> lk(_semaphore.mutex);
+    
+    if (_semaphore.count == 0)
+        return false;
+
+    _semaphore.count--;
+    return true;
+}
+
+
+void
+Semaphore::post ()
+{
+    std::lock_guard<std::mutex> lk(_semaphore.mutex);
+
+    _semaphore.count++;
+    if (_semaphore.numWaiting > 0)
+    {
+        if (_semaphore.count > 1)
+            _semaphore.nonZero.notify_all();
+        else
+            _semaphore.nonZero.notify_one();
+    }
+}
+
 
+int
+Semaphore::value () const
+{
+    std::lock_guard<std::mutex> lk(_semaphore.mutex);
+    return _semaphore.count;
+}
+#endif
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
 
 #endif
index 0c6e2ae..3e5c372 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -44,9 +44,9 @@
 #include <assert.h>
 #include <iostream>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
-using namespace Iex;
+using namespace IEX_NAMESPACE;
 
 namespace {
 
@@ -58,22 +58,22 @@ errorString ()
     std::string message;
 
     //
-    // Call FormatMessage() to allow for message
+    // Call FormatMessage() to allow for message 
     // text to be acquired from the system.
     //
 
     if (bufferLength = FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
-                       FORMAT_MESSAGE_IGNORE_INSERTS |
-                       FORMAT_MESSAGE_FROM_SYSTEM,
-                       0,
-                       GetLastError (),
-                       MAKELANGID (LANG_NEUTRAL,
-                           SUBLANG_DEFAULT),
-                       (LPSTR) &messageBuffer,
-                       0,
-                       NULL))
+                                      FORMAT_MESSAGE_IGNORE_INSERTS |
+                                      FORMAT_MESSAGE_FROM_SYSTEM,
+                                      0,
+                                      GetLastError (),
+                                      MAKELANGID (LANG_NEUTRAL,
+                                                  SUBLANG_DEFAULT),
+                                      (LPSTR) &messageBuffer,
+                                      0,
+                                      NULL))
     {
-    message = messageBuffer;
+       message = messageBuffer;
         LocalFree (messageBuffer);
     }
 
@@ -87,8 +87,8 @@ Semaphore::Semaphore (unsigned int value)
 {
     if ((_semaphore = ::CreateSemaphore (0, value, 0x7fffffff, 0)) == 0)
     {
-    THROW (LogicExc, "Could not create semaphore "
-             "(" << errorString() << ").");
+       THROW (LogicExc, "Could not create semaphore "
+                        "(" << errorString() << ").");
     }
 }
 
@@ -105,8 +105,8 @@ Semaphore::wait()
 {
     if (::WaitForSingleObject (_semaphore, INFINITE) != WAIT_OBJECT_0)
     {
-    THROW (LogicExc, "Could not wait on semaphore "
-             "(" << errorString() << ").");
+       THROW (LogicExc, "Could not wait on semaphore "
+                        "(" << errorString() << ").");
     }
 }
 
@@ -123,8 +123,8 @@ Semaphore::post()
 {
     if (!::ReleaseSemaphore (_semaphore, 1, 0))
     {
-    THROW (LogicExc, "Could not post on semaphore "
-             "(" << errorString() << ").");
+       THROW (LogicExc, "Could not post on semaphore "
+                        "(" << errorString() << ").");
     }
 }
 
@@ -136,11 +136,12 @@ Semaphore::value() const
 
     if (!::ReleaseSemaphore (_semaphore, 0, &v) || v < 0)
     {
-    THROW (LogicExc, "Could not get value of semaphore "
-             "(" << errorString () << ").");
+       THROW (LogicExc, "Could not get value of semaphore "
+                        "(" << errorString () << ").");
     }
 
     return v;
 }
 
-} // namespace IlmThread
+
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
index 46a4250..43ec23f 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2005, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-----------------------------------------------------------------------------
 
 
+#include "IlmBaseConfig.h"
+
+#ifdef ILMBASE_FORCE_CXX03
+
 #include "IlmThread.h"
 #include "Iex.h"
 #include <iostream>
 #include <assert.h>
 
-namespace IlmThread {
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 bool
@@ -88,8 +92,10 @@ Thread::start ()
     _thread = (HANDLE)::_beginthreadex (0, 0, &threadLoop, this, 0, &id);
 
     if (_thread == 0)
-    Iex::throwErrnoExc ("Cannot create new thread (%T).");
+        IEX_NAMESPACE::throwErrnoExc ("Cannot create new thread (%T).");
 }
 
 
-} // namespace IlmThread
+ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
+
+#endif
diff --git a/3rdparty/openexr/Imath/ImathBox.cpp b/3rdparty/openexr/Imath/ImathBox.cpp
new file mode 100644 (file)
index 0000000..07bddfd
--- /dev/null
@@ -0,0 +1,37 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+//
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#include "ImathBox.h"
+
+// this file is necessary for template instantiation on windows
index 8a01385..45165ff 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //     class Imath::Box<class T>
 //     --------------------------------
 //
-//     This class imposes the following requirements on its
+//     This class imposes the following requirements on its 
 //     parameter class:
-//
+//     
 //     1) The class T must implement these operators:
-//                     + - < > <= >= =
-//        with the signature (T,T) and the expected
-//        return values for a numeric type.
+//                     + - < > <= >= = 
+//        with the signature (T,T) and the expected 
+//        return values for a numeric type. 
 //
 //     2) The class T must implement operator=
 //        with the signature (T,float and/or double)
 //-------------------------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-template <class T>
+template <class T>     
 class Box
 {
   public:
@@ -83,14 +84,14 @@ class Box
     // Constructors - an "empty" box is created by default
     //-----------------------------------------------------
 
-    Box ();
+    Box (); 
     Box (const T &point);
     Box (const T &minT, const T &maxT);
 
     //--------------------
     //  Operators:  ==, !=
     //--------------------
-
+    
     bool               operator == (const Box<T> &src) const;
     bool               operator != (const Box<T> &src) const;
 
@@ -101,7 +102,7 @@ class Box
     void               makeEmpty ();
     void               extendBy (const T &point);
     void               extendBy (const Box<T> &box);
-    void               makeInfinite ();
+    void               makeInfinite ();    
 
     //---------------------------------------------------
     // Query functions - these compute results each time
@@ -202,11 +203,11 @@ Box<T>::extendBy(const T &point)
 {
     for (unsigned int i = 0; i < min.dimensions(); i++)
     {
-    if (point[i] < min[i])
-        min[i] = point[i];
+       if (point[i] < min[i])
+           min[i] = point[i];
 
-    if (point[i] > max[i])
-        max[i] = point[i];
+       if (point[i] > max[i])
+           max[i] = point[i];
     }
 }
 
@@ -217,11 +218,11 @@ Box<T>::extendBy(const Box<T> &box)
 {
     for (unsigned int i = 0; i < min.dimensions(); i++)
     {
-    if (box.min[i] < min[i])
-        min[i] = box.min[i];
+       if (box.min[i] < min[i])
+           min[i] = box.min[i];
 
-    if (box.max[i] > max[i])
-        max[i] = box.max[i];
+       if (box.max[i] > max[i])
+           max[i] = box.max[i];
     }
 }
 
@@ -233,7 +234,7 @@ Box<T>::intersects(const T &point) const
     for (unsigned int i = 0; i < min.dimensions(); i++)
     {
         if (point[i] < min[i] || point[i] > max[i])
-        return false;
+           return false;
     }
 
     return true;
@@ -247,28 +248,28 @@ Box<T>::intersects(const Box<T> &box) const
     for (unsigned int i = 0; i < min.dimensions(); i++)
     {
         if (box.max[i] < min[i] || box.min[i] > max[i])
-        return false;
+           return false;
     }
 
     return true;
 }
 
 
-template <class T>
+template <class T> 
 inline T
-Box<T>::size() const
-{
+Box<T>::size() const 
+{ 
     if (isEmpty())
-    return T (0);
+       return T (0);
 
     return max - min;
 }
 
 
-template <class T>
+template <class T> 
 inline T
-Box<T>::center() const
-{
+Box<T>::center() const 
+{ 
     return (max + min) / 2;
 }
 
@@ -280,7 +281,7 @@ Box<T>::isEmpty() const
     for (unsigned int i = 0; i < min.dimensions(); i++)
     {
         if (max[i] < min[i])
-        return true;
+           return true;
     }
 
     return false;
@@ -293,7 +294,7 @@ Box<T>::isInfinite() const
     for (unsigned int i = 0; i < min.dimensions(); i++)
     {
         if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax())
-        return false;
+           return false;
     }
 
     return true;
@@ -307,7 +308,7 @@ Box<T>::hasVolume() const
     for (unsigned int i = 0; i < min.dimensions(); i++)
     {
         if (max[i] <= min[i])
-        return false;
+           return false;
     }
 
     return true;
@@ -323,8 +324,8 @@ Box<T>::majorAxis() const
 
     for (unsigned int i = 1; i < min.dimensions(); i++)
     {
-    if (s[i] > s[major])
-        major = i;
+       if (s[i] > s[major])
+           major = i;
     }
 
     return major;
@@ -354,7 +355,7 @@ class Box<Vec2<T> >
     //  Constructors - an "empty" box is created by default
     //-----------------------------------------------------
 
-    Box();
+    Box(); 
     Box (const Vec2<T> &point);
     Box (const Vec2<T> &minT, const Vec2<T> &maxT);
 
@@ -512,10 +513,10 @@ Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const
 }
 
 
-template <class T>
+template <class T> 
 inline Vec2<T>
-Box<Vec2<T> >::size() const
-{
+Box<Vec2<T> >::size() const 
+{ 
     if (isEmpty())
         return Vec2<T> (0);
 
@@ -523,10 +524,10 @@ Box<Vec2<T> >::size() const
 }
 
 
-template <class T>
+template <class T> 
 inline Vec2<T>
-Box<Vec2<T> >::center() const
-{
+Box<Vec2<T> >::center() const 
+{ 
     return (max + min) / 2;
 }
 
@@ -549,7 +550,7 @@ Box<Vec2<T> > ::isInfinite() const
     if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
         min[1] != limits<T>::min() || max[1] != limits<T>::max())
         return false;
-
+    
     return true;
 }
 
@@ -596,7 +597,7 @@ class Box<Vec3<T> >
     //  Constructors - an "empty" box is created by default
     //-----------------------------------------------------
 
-    Box();
+    Box(); 
     Box (const Vec3<T> &point);
     Box (const Vec3<T> &minT, const Vec3<T> &maxT);
 
@@ -769,10 +770,10 @@ Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const
 }
 
 
-template <class T>
+template <class T> 
 inline Vec3<T>
-Box<Vec3<T> >::size() const
-{
+Box<Vec3<T> >::size() const 
+{ 
     if (isEmpty())
         return Vec3<T> (0);
 
@@ -780,10 +781,10 @@ Box<Vec3<T> >::size() const
 }
 
 
-template <class T>
+template <class T> 
 inline Vec3<T>
-Box<Vec3<T> >::center() const
-{
+Box<Vec3<T> >::center() const 
+{ 
     return (max + min) / 2;
 }
 
@@ -808,7 +809,7 @@ Box<Vec3<T> >::isInfinite() const
         min[1] != limits<T>::min() || max[1] != limits<T>::max() ||
         min[2] != limits<T>::min() || max[2] != limits<T>::max())
         return false;
-
+    
     return true;
 }
 
@@ -843,8 +844,6 @@ Box<Vec3<T> >::majorAxis() const
 }
 
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-
-} // namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHBOX_H
index 5379e8f..63bd2f6 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002-2010, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -67,8 +67,8 @@
 //                                 Vec3<T> &enterPoint,
 //                                 Vec3<T> &exitPoint)
 //
-//     bool intersects(const Box<Vec3<T>> &box,
-//                     const Line3<T> &ray,
+//     bool intersects(const Box<Vec3<T>> &box, 
+//                     const Line3<T> &ray, 
 //                     Vec3<T> intersectionPoint)
 //
 //     bool intersects(const Box<Vec3<T>> &box, const Line3<T> &ray)
@@ -79,8 +79,9 @@
 #include "ImathMatrix.h"
 #include "ImathLineAlgo.h"
 #include "ImathPlane.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -96,12 +97,12 @@ clip (const T &p, const Box<T> &box)
 
     for (int i = 0; i < int (box.min.dimensions()); i++)
     {
-    if (p[i] < box.min[i])
-        q[i] = box.min[i];
-    else if (p[i] > box.max[i])
-        q[i] = box.max[i];
-    else
-        q[i] = p[i];
+       if (p[i] < box.min[i])
+           q[i] = box.min[i];
+       else if (p[i] > box.max[i])
+           q[i] = box.max[i];
+       else
+           q[i] = p[i];
     }
 
     return q;
@@ -128,31 +129,31 @@ closestPointOnBox (const Vec3<T> &p, const Box< Vec3<T> > &box)
     //
 
     if (box.isEmpty())
-    return p;
+       return p;
 
     Vec3<T> q = closestPointInBox (p, box);
 
     if (q == p)
     {
-    Vec3<T> d1 = p - box.min;
-    Vec3<T> d2 = box.max - p;
+       Vec3<T> d1 = p - box.min;
+       Vec3<T> d2 = box.max - p;
 
-    Vec3<T> d ((d1.x < d2.x)? d1.x: d2.x,
-           (d1.y < d2.y)? d1.y: d2.y,
-           (d1.z < d2.z)? d1.z: d2.z);
+       Vec3<T> d ((d1.x < d2.x)? d1.x: d2.x,
+                  (d1.y < d2.y)? d1.y: d2.y,
+                  (d1.z < d2.z)? d1.z: d2.z);
 
-    if (d.x < d.y && d.x < d.z)
-    {
-        q.x = (d1.x < d2.x)? box.min.x: box.max.x;
-    }
-    else if (d.y < d.z)
-    {
-        q.y = (d1.y < d2.y)? box.min.y: box.max.y;
-    }
-    else
-    {
-        q.z = (d1.z < d2.z)? box.min.z: box.max.z;
-    }
+       if (d.x < d.y && d.x < d.z)
+       {
+           q.x = (d1.x < d2.x)? box.min.x: box.max.x;
+       }
+       else if (d.y < d.z)
+       {
+           q.y = (d1.y < d2.y)? box.min.y: box.max.y;
+       }
+       else
+       {
+           q.z = (d1.z < d2.z)? box.min.z: box.max.z;
+       }
     }
 
     return q;
@@ -178,7 +179,7 @@ transform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
     //
 
     if (box.isEmpty() || box.isInfinite())
-    return box;
+       return box;
 
     //
     // If the last column of m is (0 0 0 1) then m is an affine
@@ -187,33 +188,33 @@ transform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
 
     if (m[0][3] == 0 && m[1][3] == 0 && m[2][3] == 0 && m[3][3] == 1)
     {
-    Box< Vec3<S> > newBox;
+       Box< Vec3<S> > newBox;
 
-    for (int i = 0; i < 3; i++)
+       for (int i = 0; i < 3; i++) 
         {
-        newBox.min[i] = newBox.max[i] = (S) m[3][i];
+           newBox.min[i] = newBox.max[i] = (S) m[3][i];
 
-        for (int j = 0; j < 3; j++)
+           for (int j = 0; j < 3; j++) 
             {
-        S a, b;
+               S a, b;
 
-        a = (S) m[j][i] * box.min[j];
-        b = (S) m[j][i] * box.max[j];
+               a = (S) m[j][i] * box.min[j];
+               b = (S) m[j][i] * box.max[j];
 
-        if (a < b)
+               if (a < b) 
                 {
-            newBox.min[i] += a;
-            newBox.max[i] += b;
-        }
-        else
+                   newBox.min[i] += a;
+                   newBox.max[i] += b;
+               }
+               else 
                 {
-            newBox.min[i] += b;
-            newBox.max[i] += a;
-        }
-        }
-    }
+                   newBox.min[i] += b;
+                   newBox.max[i] += a;
+               }
+           }
+       }
 
-    return newBox;
+       return newBox;
     }
 
     //
@@ -235,8 +236,8 @@ transform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
 
     Box< Vec3<S> > newBox;
 
-    for (int i = 0; i < 8; i++)
-    newBox.extendBy (points[i] * m);
+    for (int i = 0; i < 8; i++) 
+       newBox.extendBy (points[i] * m);
 
     return newBox;
 }
@@ -263,7 +264,7 @@ transform (const Box< Vec3<S> > &box,
 
     if (box.isEmpty() || box.isInfinite())
     {
-    return;
+       return;
     }
 
     //
@@ -273,31 +274,31 @@ transform (const Box< Vec3<S> > &box,
 
     if (m[0][3] == 0 && m[1][3] == 0 && m[2][3] == 0 && m[3][3] == 1)
     {
-    for (int i = 0; i < 3; i++)
+       for (int i = 0; i < 3; i++) 
         {
-        result.min[i] = result.max[i] = (S) m[3][i];
+           result.min[i] = result.max[i] = (S) m[3][i];
 
-        for (int j = 0; j < 3; j++)
+           for (int j = 0; j < 3; j++) 
             {
-        S a, b;
+               S a, b;
 
-        a = (S) m[j][i] * box.min[j];
-        b = (S) m[j][i] * box.max[j];
+               a = (S) m[j][i] * box.min[j];
+               b = (S) m[j][i] * box.max[j];
 
-        if (a < b)
+               if (a < b) 
                 {
-            result.min[i] += a;
-            result.max[i] += b;
-        }
-        else
+                   result.min[i] += a;
+                   result.max[i] += b;
+               }
+               else 
                 {
-            result.min[i] += b;
-            result.max[i] += a;
-        }
-        }
-    }
+                   result.min[i] += b;
+                   result.max[i] += a;
+               }
+           }
+       }
 
-    return;
+       return;
     }
 
     //
@@ -317,8 +318,8 @@ transform (const Box< Vec3<S> > &box,
     points[0][2] = points[2][2] = points[4][2] = points[6][2] = box.min[2];
     points[1][2] = points[3][2] = points[5][2] = points[7][2] = box.max[2];
 
-    for (int i = 0; i < 8; i++)
-    result.extendBy (points[i] * m);
+    for (int i = 0; i < 8; i++) 
+       result.extendBy (points[i] * m);
 }
 
 
@@ -337,37 +338,37 @@ affineTransform (const Box< Vec3<S> > &box, const Matrix44<T> &m)
 
     if (box.isEmpty() || box.isInfinite())
     {
-    //
-    // A transformed empty or infinite box is still empty or infinite
-    //
+       //
+       // A transformed empty or infinite box is still empty or infinite
+       //
 
-    return box;
+       return box;
     }
 
     Box< Vec3<S> > newBox;
 
-    for (int i = 0; i < 3; i++)
+    for (int i = 0; i < 3; i++) 
     {
-    newBox.min[i] = newBox.max[i] = (S) m[3][i];
+       newBox.min[i] = newBox.max[i] = (S) m[3][i];
 
-    for (int j = 0; j < 3; j++)
-    {
-        S a, b;
+       for (int j = 0; j < 3; j++) 
+       {
+           S a, b;
 
-        a = (S) m[j][i] * box.min[j];
-        b = (S) m[j][i] * box.max[j];
+           a = (S) m[j][i] * box.min[j];
+           b = (S) m[j][i] * box.max[j];
 
-        if (a < b)
-        {
-        newBox.min[i] += a;
-        newBox.max[i] += b;
-        }
-        else
-        {
-        newBox.min[i] += b;
-        newBox.max[i] += a;
-        }
-    }
+           if (a < b) 
+           {
+               newBox.min[i] += a;
+               newBox.max[i] += b;
+           }
+           else 
+           {
+               newBox.min[i] += b;
+               newBox.max[i] += a;
+           }
+       }
     }
 
     return newBox;
@@ -390,44 +391,44 @@ affineTransform (const Box< Vec3<S> > &box,
 
     if (box.isEmpty())
     {
-    //
-    // A transformed empty box is still empty
-    //
+       //
+       // A transformed empty box is still empty
+       //
         result.makeEmpty();
-    return;
+       return;
     }
 
     if (box.isInfinite())
     {
-    //
-    // A transformed infinite box is still infinite
-    //
+       //
+       // A transformed infinite box is still infinite
+       //
         result.makeInfinite();
-    return;
+       return;
     }
 
-    for (int i = 0; i < 3; i++)
+    for (int i = 0; i < 3; i++) 
     {
-    result.min[i] = result.max[i] = (S) m[3][i];
+       result.min[i] = result.max[i] = (S) m[3][i];
 
-    for (int j = 0; j < 3; j++)
-    {
-        S a, b;
+       for (int j = 0; j < 3; j++) 
+       {
+           S a, b;
 
-        a = (S) m[j][i] * box.min[j];
-        b = (S) m[j][i] * box.max[j];
+           a = (S) m[j][i] * box.min[j];
+           b = (S) m[j][i] * box.max[j];
 
-        if (a < b)
-        {
-        result.min[i] += a;
-        result.max[i] += b;
-        }
-        else
-        {
-        result.min[i] += b;
-        result.max[i] += a;
-        }
-    }
+           if (a < b) 
+           {
+               result.min[i] += a;
+               result.max[i] += b;
+           }
+           else 
+           {
+               result.min[i] += b;
+               result.max[i] += a;
+           }
+       }
     }
 }
 
@@ -435,9 +436,9 @@ affineTransform (const Box< Vec3<S> > &box,
 template <class T>
 bool
 findEntryAndExitPoints (const Line3<T> &r,
-            const Box<Vec3<T> > &b,
-            Vec3<T> &entry,
-            Vec3<T> &exit)
+                       const Box<Vec3<T> > &b,
+                       Vec3<T> &entry,
+                       Vec3<T> &exit)
 {
     //
     // Compute the points where a ray, r, enters and exits a box, b:
@@ -463,11 +464,11 @@ findEntryAndExitPoints (const Line3<T> &r,
 
     if (b.isEmpty())
     {
-    //
-    // No ray intersects an empty box
-    //
+       //
+       // No ray intersects an empty box
+       //
 
-    return false;
+       return false;
     }
 
     //
@@ -499,73 +500,73 @@ findEntryAndExitPoints (const Line3<T> &r,
 
     if (r.dir.x >= 0)
     {
-    T d1 = b.max.x - r.pos.x;
-    T d2 = b.min.x - r.pos.x;
-
-    if (r.dir.x > 1 ||
-        (abs (d1) < TMAX * r.dir.x &&
-         abs (d2) < TMAX * r.dir.x))
-    {
-        T t1 = d1 / r.dir.x;
-        T t2 = d2 / r.dir.x;
-
-        if (tBackMin > t1)
-        {
-        tBackMin = t1;
-
-        exit.x = b.max.x;
-        exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
-        exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
-        }
-
-        if (tFrontMax < t2)
-        {
-        tFrontMax = t2;
-
-        entry.x = b.min.x;
-        entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
-        entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
-        }
-    }
-    else if (r.pos.x < b.min.x || r.pos.x > b.max.x)
-    {
-        return false;
-    }
+       T d1 = b.max.x - r.pos.x;
+       T d2 = b.min.x - r.pos.x;
+
+       if (r.dir.x > 1 ||
+           (abs (d1) < TMAX * r.dir.x &&
+            abs (d2) < TMAX * r.dir.x))
+       {
+           T t1 = d1 / r.dir.x;
+           T t2 = d2 / r.dir.x;
+
+           if (tBackMin > t1)
+           {
+               tBackMin = t1;
+
+               exit.x = b.max.x; 
+               exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
+               exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
+           }
+
+           if (tFrontMax < t2)
+           {
+               tFrontMax = t2;
+
+               entry.x = b.min.x; 
+               entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
+               entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
+           }
+       }
+       else if (r.pos.x < b.min.x || r.pos.x > b.max.x)
+       {
+           return false;
+       }
     }
     else // r.dir.x < 0
     {
-    T d1 = b.min.x - r.pos.x;
-    T d2 = b.max.x - r.pos.x;
+       T d1 = b.min.x - r.pos.x;
+       T d2 = b.max.x - r.pos.x;
 
-    if (r.dir.x < -1 ||
-        (abs (d1) < -TMAX * r.dir.x &&
-         abs (d2) < -TMAX * r.dir.x))
-    {
-        T t1 = d1 / r.dir.x;
-        T t2 = d2 / r.dir.x;
+       if (r.dir.x < -1 ||
+           (abs (d1) < -TMAX * r.dir.x &&
+            abs (d2) < -TMAX * r.dir.x))
+       {
+           T t1 = d1 / r.dir.x;
+           T t2 = d2 / r.dir.x;
 
-        if (tBackMin > t1)
-        {
-        tBackMin = t1;
+           if (tBackMin > t1)
+           {
+               tBackMin = t1;
 
-        exit.x = b.min.x;
-        exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
-        exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
-        }
+               exit.x = b.min.x; 
+               exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
+               exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
+           }
 
-        if (tFrontMax < t2)
-        {
-        tFrontMax = t2;
+           if (tFrontMax < t2)
+           {
+               tFrontMax = t2;
 
-        entry.x = b.max.x;
-        entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
-        entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
-        }
-    }
-    else if (r.pos.x < b.min.x || r.pos.x > b.max.x)
-    {
-        return false;
-    }
+               entry.x = b.max.x; 
+               entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
+               entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
+           }
+       }
+       else if (r.pos.x < b.min.x || r.pos.x > b.max.x)
+       {
+           return false;
+       }
     }
 
     //
@@ -574,73 +575,73 @@ findEntryAndExitPoints (const Line3<T> &r,
 
     if (r.dir.y >= 0)
     {
-    T d1 = b.max.y - r.pos.y;
-    T d2 = b.min.y - r.pos.y;
-
-    if (r.dir.y > 1 ||
-        (abs (d1) < TMAX * r.dir.y &&
-         abs (d2) < TMAX * r.dir.y))
-    {
-        T t1 = d1 / r.dir.y;
-        T t2 = d2 / r.dir.y;
-
-        if (tBackMin > t1)
-        {
-        tBackMin = t1;
-
-        exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
-        exit.y = b.max.y;
-        exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
-        }
-
-        if (tFrontMax < t2)
-        {
-        tFrontMax = t2;
-
-        entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
-        entry.y = b.min.y;
-        entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
-        }
-    }
-    else if (r.pos.y < b.min.y || r.pos.y > b.max.y)
-    {
-        return false;
-    }
+       T d1 = b.max.y - r.pos.y;
+       T d2 = b.min.y - r.pos.y;
+
+       if (r.dir.y > 1 ||
+           (abs (d1) < TMAX * r.dir.y &&
+            abs (d2) < TMAX * r.dir.y))
+       {
+           T t1 = d1 / r.dir.y;
+           T t2 = d2 / r.dir.y;
+
+           if (tBackMin > t1)
+           {
+               tBackMin = t1;
+
+               exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
+               exit.y = b.max.y; 
+               exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
+           }
+
+           if (tFrontMax < t2)
+           {
+               tFrontMax = t2;
+
+               entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
+               entry.y = b.min.y; 
+               entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
+           }
+       }
+       else if (r.pos.y < b.min.y || r.pos.y > b.max.y)
+       {
+           return false;
+       }
     }
     else // r.dir.y < 0
     {
-    T d1 = b.min.y - r.pos.y;
-    T d2 = b.max.y - r.pos.y;
+       T d1 = b.min.y - r.pos.y;
+       T d2 = b.max.y - r.pos.y;
 
-    if (r.dir.y < -1 ||
-        (abs (d1) < -TMAX * r.dir.y &&
-         abs (d2) < -TMAX * r.dir.y))
-    {
-        T t1 = d1 / r.dir.y;
-        T t2 = d2 / r.dir.y;
+       if (r.dir.y < -1 ||
+           (abs (d1) < -TMAX * r.dir.y &&
+            abs (d2) < -TMAX * r.dir.y))
+       {
+           T t1 = d1 / r.dir.y;
+           T t2 = d2 / r.dir.y;
 
-        if (tBackMin > t1)
-        {
-        tBackMin = t1;
+           if (tBackMin > t1)
+           {
+               tBackMin = t1;
 
-        exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
-        exit.y = b.min.y;
-        exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
-        }
+               exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
+               exit.y = b.min.y; 
+               exit.z = clamp (r.pos.z + t1 * r.dir.z, b.min.z, b.max.z);
+           }
 
-        if (tFrontMax < t2)
-        {
-        tFrontMax = t2;
+           if (tFrontMax < t2)
+           {
+               tFrontMax = t2;
 
-        entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
-        entry.y = b.max.y;
-        entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
-        }
-    }
-    else if (r.pos.y < b.min.y || r.pos.y > b.max.y)
-    {
-        return false;
-    }
+               entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
+               entry.y = b.max.y; 
+               entry.z = clamp (r.pos.z + t2 * r.dir.z, b.min.z, b.max.z);
+           }
+       }
+       else if (r.pos.y < b.min.y || r.pos.y > b.max.y)
+       {
+           return false;
+       }
     }
 
     //
@@ -649,73 +650,73 @@ findEntryAndExitPoints (const Line3<T> &r,
 
     if (r.dir.z >= 0)
     {
-    T d1 = b.max.z - r.pos.z;
-    T d2 = b.min.z - r.pos.z;
-
-    if (r.dir.z > 1 ||
-        (abs (d1) < TMAX * r.dir.z &&
-         abs (d2) < TMAX * r.dir.z))
-    {
-        T t1 = d1 / r.dir.z;
-        T t2 = d2 / r.dir.z;
-
-        if (tBackMin > t1)
-        {
-        tBackMin = t1;
-
-        exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
-        exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
-        exit.z = b.max.z;
-        }
-
-        if (tFrontMax < t2)
-        {
-        tFrontMax = t2;
-
-        entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
-        entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
-        entry.z = b.min.z;
-        }
-    }
-    else if (r.pos.z < b.min.z || r.pos.z > b.max.z)
-    {
-        return false;
-    }
+       T d1 = b.max.z - r.pos.z;
+       T d2 = b.min.z - r.pos.z;
+
+       if (r.dir.z > 1 ||
+           (abs (d1) < TMAX * r.dir.z &&
+            abs (d2) < TMAX * r.dir.z))
+       {
+           T t1 = d1 / r.dir.z;
+           T t2 = d2 / r.dir.z;
+
+           if (tBackMin > t1)
+           {
+               tBackMin = t1;
+
+               exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
+               exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
+               exit.z = b.max.z; 
+           }
+
+           if (tFrontMax < t2)
+           {
+               tFrontMax = t2;
+
+               entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
+               entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
+               entry.z = b.min.z; 
+           }
+       }
+       else if (r.pos.z < b.min.z || r.pos.z > b.max.z)
+       {
+           return false;
+       }
     }
     else // r.dir.z < 0
     {
-    T d1 = b.min.z - r.pos.z;
-    T d2 = b.max.z - r.pos.z;
+       T d1 = b.min.z - r.pos.z;
+       T d2 = b.max.z - r.pos.z;
 
-    if (r.dir.z < -1 ||
-        (abs (d1) < -TMAX * r.dir.z &&
-         abs (d2) < -TMAX * r.dir.z))
-    {
-        T t1 = d1 / r.dir.z;
-        T t2 = d2 / r.dir.z;
+       if (r.dir.z < -1 ||
+           (abs (d1) < -TMAX * r.dir.z &&
+            abs (d2) < -TMAX * r.dir.z))
+       {
+           T t1 = d1 / r.dir.z;
+           T t2 = d2 / r.dir.z;
 
-        if (tBackMin > t1)
-        {
-        tBackMin = t1;
+           if (tBackMin > t1)
+           {
+               tBackMin = t1;
 
-        exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
-        exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
-        exit.z = b.min.z;
-        }
+               exit.x = clamp (r.pos.x + t1 * r.dir.x, b.min.x, b.max.x);
+               exit.y = clamp (r.pos.y + t1 * r.dir.y, b.min.y, b.max.y);
+               exit.z = b.min.z; 
+           }
 
-        if (tFrontMax < t2)
-        {
-        tFrontMax = t2;
+           if (tFrontMax < t2)
+           {
+               tFrontMax = t2;
 
-        entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
-        entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
-        entry.z = b.max.z;
-        }
-    }
-    else if (r.pos.z < b.min.z || r.pos.z > b.max.z)
-    {
-        return false;
-    }
+               entry.x = clamp (r.pos.x + t2 * r.dir.x, b.min.x, b.max.x);
+               entry.y = clamp (r.pos.y + t2 * r.dir.y, b.min.y, b.max.y);
+               entry.z = b.max.z; 
+           }
+       }
+       else if (r.pos.z < b.min.z || r.pos.z > b.max.z)
+       {
+           return false;
+       }
     }
 
     return tFrontMax <= tBackMin;
@@ -752,21 +753,21 @@ intersects (const Box< Vec3<T> > &b, const Line3<T> &r, Vec3<T> &ip)
 
     if (b.isEmpty())
     {
-    //
-    // No ray intersects an empty box
-    //
+       //
+       // No ray intersects an empty box
+       //
 
-    return false;
+       return false;
     }
 
     if (b.intersects (r.pos))
     {
-    //
-    // The ray starts inside the box
-    //
+       //
+       // The ray starts inside the box
+       //
 
-    ip = r.pos;
-    return true;
+       ip = r.pos;
+       return true;
     }
 
     //
@@ -793,68 +794,68 @@ intersects (const Box< Vec3<T> > &b, const Line3<T> &r, Vec3<T> &ip)
 
     if (r.dir.x > 0)
     {
-    if (r.pos.x > b.max.x)
-        return false;
+       if (r.pos.x > b.max.x)
+           return false;
 
-    T d = b.max.x - r.pos.x;
+       T d = b.max.x - r.pos.x;
 
-    if (r.dir.x > 1 || d < TMAX * r.dir.x)
-    {
-        T t = d / r.dir.x;
+       if (r.dir.x > 1 || d < TMAX * r.dir.x)
+       {
+           T t = d / r.dir.x;
 
-        if (tBackMin > t)
-        tBackMin = t;
-    }
+           if (tBackMin > t)
+               tBackMin = t;
+       }
 
-    if (r.pos.x <= b.min.x)
-    {
-        T d = b.min.x - r.pos.x;
-        T t = (r.dir.x > 1 || d < TMAX * r.dir.x)? d / r.dir.x: TMAX;
+       if (r.pos.x <= b.min.x)
+       {
+           T d = b.min.x - r.pos.x;
+           T t = (r.dir.x > 1 || d < TMAX * r.dir.x)? d / r.dir.x: TMAX;
 
-        if (tFrontMax < t)
-        {
-        tFrontMax = t;
+           if (tFrontMax < t)
+           {
+               tFrontMax = t;
 
-        ip.x = b.min.x;
-        ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
-        ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
-        }
-    }
+               ip.x = b.min.x; 
+               ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
+               ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
+           }
+       }
     }
     else if (r.dir.x < 0)
     {
-    if (r.pos.x < b.min.x)
-        return false;
+       if (r.pos.x < b.min.x)
+           return false;
 
-    T d = b.min.x - r.pos.x;
+       T d = b.min.x - r.pos.x;
 
-    if (r.dir.x < -1 || d > TMAX * r.dir.x)
-    {
-        T t = d / r.dir.x;
+       if (r.dir.x < -1 || d > TMAX * r.dir.x)
+       {
+           T t = d / r.dir.x;
 
-        if (tBackMin > t)
-        tBackMin = t;
-    }
+           if (tBackMin > t)
+               tBackMin = t;
+       }
 
-    if (r.pos.x >= b.max.x)
-    {
-        T d = b.max.x - r.pos.x;
-        T t = (r.dir.x < -1 || d > TMAX * r.dir.x)? d / r.dir.x: TMAX;
+       if (r.pos.x >= b.max.x)
+       {
+           T d = b.max.x - r.pos.x;
+           T t = (r.dir.x < -1 || d > TMAX * r.dir.x)? d / r.dir.x: TMAX;
 
-        if (tFrontMax < t)
-        {
-        tFrontMax = t;
+           if (tFrontMax < t)
+           {
+               tFrontMax = t;
 
-        ip.x = b.max.x;
-        ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
-        ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
-        }
-    }
+               ip.x = b.max.x; 
+               ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
+               ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
+           }
+       }
     }
     else // r.dir.x == 0
     {
-    if (r.pos.x < b.min.x || r.pos.x > b.max.x)
-        return false;
+       if (r.pos.x < b.min.x || r.pos.x > b.max.x)
+           return false;
     }
 
     //
@@ -863,68 +864,68 @@ intersects (const Box< Vec3<T> > &b, const Line3<T> &r, Vec3<T> &ip)
 
     if (r.dir.y > 0)
     {
-    if (r.pos.y > b.max.y)
-        return false;
+       if (r.pos.y > b.max.y)
+           return false;
 
-    T d = b.max.y - r.pos.y;
+       T d = b.max.y - r.pos.y;
 
-    if (r.dir.y > 1 || d < TMAX * r.dir.y)
-    {
-        T t = d / r.dir.y;
+       if (r.dir.y > 1 || d < TMAX * r.dir.y)
+       {
+           T t = d / r.dir.y;
 
-        if (tBackMin > t)
-        tBackMin = t;
-    }
+           if (tBackMin > t)
+               tBackMin = t;
+       }
 
-    if (r.pos.y <= b.min.y)
-    {
-        T d = b.min.y - r.pos.y;
-        T t = (r.dir.y > 1 || d < TMAX * r.dir.y)? d / r.dir.y: TMAX;
+       if (r.pos.y <= b.min.y)
+       {
+           T d = b.min.y - r.pos.y;
+           T t = (r.dir.y > 1 || d < TMAX * r.dir.y)? d / r.dir.y: TMAX;
 
-        if (tFrontMax < t)
-        {
-        tFrontMax = t;
+           if (tFrontMax < t)
+           {
+               tFrontMax = t;
 
-        ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
-        ip.y = b.min.y;
-        ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
-        }
-    }
+               ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
+               ip.y = b.min.y; 
+               ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
+           }
+       }
     }
     else if (r.dir.y < 0)
     {
-    if (r.pos.y < b.min.y)
-        return false;
+       if (r.pos.y < b.min.y)
+           return false;
 
-    T d = b.min.y - r.pos.y;
+       T d = b.min.y - r.pos.y;
 
-    if (r.dir.y < -1 || d > TMAX * r.dir.y)
-    {
-        T t = d / r.dir.y;
+       if (r.dir.y < -1 || d > TMAX * r.dir.y)
+       {
+           T t = d / r.dir.y;
 
-        if (tBackMin > t)
-        tBackMin = t;
-    }
+           if (tBackMin > t)
+               tBackMin = t;
+       }
 
-    if (r.pos.y >= b.max.y)
-    {
-        T d = b.max.y - r.pos.y;
-        T t = (r.dir.y < -1 || d > TMAX * r.dir.y)? d / r.dir.y: TMAX;
+       if (r.pos.y >= b.max.y)
+       {
+           T d = b.max.y - r.pos.y;
+           T t = (r.dir.y < -1 || d > TMAX * r.dir.y)? d / r.dir.y: TMAX;
+           
+           if (tFrontMax < t)
+           {
+               tFrontMax = t;
 
-        if (tFrontMax < t)
-        {
-        tFrontMax = t;
-
-        ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
-        ip.y = b.max.y;
-        ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
-        }
-    }
+               ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
+               ip.y = b.max.y; 
+               ip.z = clamp (r.pos.z + t * r.dir.z, b.min.z, b.max.z);
+           }
+       }
     }
     else // r.dir.y == 0
     {
-    if (r.pos.y < b.min.y || r.pos.y > b.max.y)
-        return false;
+       if (r.pos.y < b.min.y || r.pos.y > b.max.y)
+           return false;
     }
 
     //
@@ -933,68 +934,68 @@ intersects (const Box< Vec3<T> > &b, const Line3<T> &r, Vec3<T> &ip)
 
     if (r.dir.z > 0)
     {
-    if (r.pos.z > b.max.z)
-        return false;
+       if (r.pos.z > b.max.z)
+           return false;
 
-    T d = b.max.z - r.pos.z;
+       T d = b.max.z - r.pos.z;
 
-    if (r.dir.z > 1 || d < TMAX * r.dir.z)
-    {
-        T t = d / r.dir.z;
+       if (r.dir.z > 1 || d < TMAX * r.dir.z)
+       {
+           T t = d / r.dir.z;
 
-        if (tBackMin > t)
-        tBackMin = t;
-    }
+           if (tBackMin > t)
+               tBackMin = t;
+       }
 
-    if (r.pos.z <= b.min.z)
-    {
-        T d = b.min.z - r.pos.z;
-        T t = (r.dir.z > 1 || d < TMAX * r.dir.z)? d / r.dir.z: TMAX;
-
-        if (tFrontMax < t)
-        {
-        tFrontMax = t;
+       if (r.pos.z <= b.min.z)
+       {
+           T d = b.min.z - r.pos.z;
+           T t = (r.dir.z > 1 || d < TMAX * r.dir.z)? d / r.dir.z: TMAX;
+           
+           if (tFrontMax < t)
+           {
+               tFrontMax = t;
 
-        ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
-        ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
-        ip.z = b.min.z;
-        }
-    }
+               ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
+               ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
+               ip.z = b.min.z; 
+           }
+       }
     }
     else if (r.dir.z < 0)
     {
-    if (r.pos.z < b.min.z)
-        return false;
+       if (r.pos.z < b.min.z)
+           return false;
 
-    T d = b.min.z - r.pos.z;
+       T d = b.min.z - r.pos.z;
 
-    if (r.dir.z < -1 || d > TMAX * r.dir.z)
-    {
-        T t = d / r.dir.z;
+       if (r.dir.z < -1 || d > TMAX * r.dir.z)
+       {
+           T t = d / r.dir.z;
 
-        if (tBackMin > t)
-        tBackMin = t;
-    }
+           if (tBackMin > t)
+               tBackMin = t;
+       }
 
-    if (r.pos.z >= b.max.z)
-    {
-        T d = b.max.z - r.pos.z;
-        T t = (r.dir.z < -1 || d > TMAX * r.dir.z)? d / r.dir.z: TMAX;
+       if (r.pos.z >= b.max.z)
+       {
+           T d = b.max.z - r.pos.z;
+           T t = (r.dir.z < -1 || d > TMAX * r.dir.z)? d / r.dir.z: TMAX;
+           
+           if (tFrontMax < t)
+           {
+               tFrontMax = t;
 
-        if (tFrontMax < t)
-        {
-        tFrontMax = t;
-
-        ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
-        ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
-        ip.z = b.max.z;
-        }
-    }
+               ip.x = clamp (r.pos.x + t * r.dir.x, b.min.x, b.max.x);
+               ip.y = clamp (r.pos.y + t * r.dir.y, b.min.y, b.max.y);
+               ip.z = b.max.z; 
+           }
+       }
     }
     else // r.dir.z == 0
     {
-    if (r.pos.z < b.min.z || r.pos.z > b.max.z)
-        return false;
+       if (r.pos.z < b.min.z || r.pos.z > b.max.z)
+           return false;
     }
 
     return tFrontMax <= tBackMin;
@@ -1010,6 +1011,6 @@ intersects (const Box< Vec3<T> > &box, const Line3<T> &ray)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHBOXALGO_H
index 088653e..743c72d 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //----------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 #include "half.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -340,7 +341,7 @@ Color3<T>::operator += (const Color3 &c)
 }
 
 template <class T>
-inline Color3<T>
+inline Color3<T>       
 Color3<T>::operator + (const Color3 &c) const
 {
     return Color3 (*(Vec3<T> *)this + (const Vec3<T> &)c);
@@ -355,14 +356,14 @@ Color3<T>::operator -= (const Color3 &c)
 }
 
 template <class T>
-inline Color3<T>
+inline Color3<T>       
 Color3<T>::operator - (const Color3 &c) const
 {
     return Color3 (*(Vec3<T> *)this - (const Vec3<T> &)c);
 }
 
 template <class T>
-inline Color3<T>
+inline Color3<T>       
 Color3<T>::operator - () const
 {
     return Color3 (-(*(Vec3<T> *)this));
@@ -393,14 +394,14 @@ Color3<T>::operator *= (T a)
 }
 
 template <class T>
-inline Color3<T>
+inline Color3<T>       
 Color3<T>::operator * (const Color3 &c) const
 {
     return Color3 (*(Vec3<T> *)this * (const Vec3<T> &)c);
 }
 
 template <class T>
-inline Color3<T>
+inline Color3<T>       
 Color3<T>::operator * (T a) const
 {
     return Color3 (*(Vec3<T> *)this * a);
@@ -423,14 +424,14 @@ Color3<T>::operator /= (T a)
 }
 
 template <class T>
-inline Color3<T>
+inline Color3<T>       
 Color3<T>::operator / (const Color3 &c) const
 {
     return Color3 (*(Vec3<T> *)this / (const Vec3<T> &)c);
 }
 
 template <class T>
-inline Color3<T>
+inline Color3<T>       
 Color3<T>::operator / (T a) const
 {
     return Color3 (*(Vec3<T> *)this / a);
@@ -729,6 +730,7 @@ operator * (S x, const Color4<T> &v)
     return Color4<T> (x * v.r, x * v.g, x * v.b, x * v.a);
 }
 
-} // namespace Imath
 
-#endif
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IMATHCOLOR_H 
index 9c8ecac..a351c40 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -41,7 +41,7 @@
 
 #include "ImathColorAlgo.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 Vec3<double>
@@ -52,7 +52,7 @@ hsv2rgb_d(const Vec3<double> &hsv)
     double val = hsv.z;
 
     double x = 0.0, y = 0.0, z = 0.0;
-
+    
     if (hue == 1) hue = 0;
     else hue *= 6;
 
@@ -62,7 +62,7 @@ hsv2rgb_d(const Vec3<double> &hsv)
     double q = val*(1-(sat*f));
     double t = val*(1-(sat*(1-f)));
 
-    switch (i)
+    switch (i) 
     {
       case 0: x = val; y = t; z = p; break;
       case 1: x = q; y = val; z = p; break;
@@ -76,7 +76,7 @@ hsv2rgb_d(const Vec3<double> &hsv)
 }
 
 
-Color4<double>
+Color4<double> 
 hsv2rgb_d(const Color4<double> &hsv)
 {
     double hue = hsv.r;
@@ -84,7 +84,7 @@ hsv2rgb_d(const Color4<double> &hsv)
     double val = hsv.b;
 
     double   r = 0.0, g = 0.0, b = 0.0;
-
+    
     if (hue == 1) hue = 0;
     else hue *= 6;
 
@@ -94,7 +94,7 @@ hsv2rgb_d(const Color4<double> &hsv)
     double q = val*(1-(sat*f));
     double t = val*(1-(sat*(1-f)));
 
-    switch (i)
+    switch (i) 
     {
       case 0: r = val; g = t; b = p; break;
       case 1: r = q; g = val; b = p; break;
@@ -122,21 +122,21 @@ rgb2hsv_d(const Vec3<double> &c)
     double val  = max;
     double sat   = 0;
     double hue   = 0;
-
+    
     if (max != 0)   sat = range/max;
-
-    if (sat != 0)
+    
+    if (sat != 0) 
     {
-    double h;
-
-    if      (x == max) h =     (y - z) / range;
-    else if (y == max) h = 2 + (z - x) / range;
-    else               h = 4 + (x - y) / range;
-
-    hue = h/6.;
-
-    if (hue < 0.)
-        hue += 1.0;
+       double h;
+       
+       if      (x == max)      h =     (y - z) / range;
+       else if (y == max)      h = 2 + (z - x) / range;
+       else            h = 4 + (x - y) / range;
+
+       hue = h/6.;
+           
+       if (hue < 0.)
+           hue += 1.0;
     }
     return Vec3<double>(hue,sat,val);
 }
@@ -155,24 +155,24 @@ rgb2hsv_d(const Color4<double> &c)
     double val  = max;
     double sat   = 0;
     double hue   = 0;
-
+    
     if (max != 0)   sat = range/max;
-
-    if (sat != 0)
+    
+    if (sat != 0) 
     {
-    double h;
-
-    if      (r == max) h =     (g - b) / range;
-    else if (g == max) h = 2 + (b - r) / range;
-    else               h = 4 + (r - g) / range;
-
-    hue = h/6.;
-
-    if (hue < 0.)
-        hue += 1.0;
+       double h;
+       
+       if      (r == max)      h =     (g - b) / range;
+       else if (g == max)      h = 2 + (b - r) / range;
+       else            h = 4 + (r - g) / range;
+
+       hue = h/6.;
+           
+       if (hue < 0.)
+           hue += 1.0;
     }
     return Color4<double>(hue,sat,val,c.a);
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
index 0e8ad28..cbc3be4 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 
 #include "ImathColor.h"
+#include "ImathExport.h"
 #include "ImathMath.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //
@@ -50,14 +52,13 @@ namespace Imath {
 //     These routines eliminate type warnings under g++.
 //
 
-Vec3<double>   hsv2rgb_d(const Vec3<double> &hsv);
-
-Color4<double> hsv2rgb_d(const Color4<double> &hsv);
+IMATH_EXPORT Vec3<double>      hsv2rgb_d(const Vec3<double> &hsv);
 
+IMATH_EXPORT Color4<double>    hsv2rgb_d(const Color4<double> &hsv);
 
-Vec3<double>   rgb2hsv_d(const Vec3<double> &rgb);
+IMATH_EXPORT Vec3<double>      rgb2hsv_d(const Vec3<double> &rgb);
 
-Color4<double> rgb2hsv_d(const Color4<double> &rgb);
+IMATH_EXPORT Color4<double>    rgb2hsv_d(const Color4<double> &rgb);
 
 
 //
@@ -67,98 +68,98 @@ Color4<double>      rgb2hsv_d(const Color4<double> &rgb);
 //     see each funtion definition for details.
 //
 
-template<class T>
-Vec3<T>
+template<class T> 
+Vec3<T>  
 hsv2rgb(const Vec3<T> &hsv)
 {
     if ( limits<T>::isIntegral() )
     {
-    Vec3<double> v = Vec3<double>(hsv.x / double(limits<T>::max()),
-                      hsv.y / double(limits<T>::max()),
-                      hsv.z / double(limits<T>::max()));
-    Vec3<double> c = hsv2rgb_d(v);
-    return Vec3<T>((T) (c.x * limits<T>::max()),
-               (T) (c.y * limits<T>::max()),
-               (T) (c.z * limits<T>::max()));
+       Vec3<double> v = Vec3<double>(hsv.x / double(limits<T>::max()),
+                                     hsv.y / double(limits<T>::max()),
+                                     hsv.z / double(limits<T>::max()));
+       Vec3<double> c = hsv2rgb_d(v);
+       return Vec3<T>((T) (c.x * limits<T>::max()),
+                      (T) (c.y * limits<T>::max()),
+                      (T) (c.z * limits<T>::max()));
     }
     else
     {
-    Vec3<double> v = Vec3<double>(hsv.x, hsv.y, hsv.z);
-    Vec3<double> c = hsv2rgb_d(v);
-    return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
+       Vec3<double> v = Vec3<double>(hsv.x, hsv.y, hsv.z);
+       Vec3<double> c = hsv2rgb_d(v);
+       return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
     }
 }
 
 
-template<class T>
-Color4<T>
+template<class T> 
+Color4<T>  
 hsv2rgb(const Color4<T> &hsv)
 {
     if ( limits<T>::isIntegral() )
     {
-    Color4<double> v = Color4<double>(hsv.r / float(limits<T>::max()),
-                      hsv.g / float(limits<T>::max()),
-                      hsv.b / float(limits<T>::max()),
-                      hsv.a / float(limits<T>::max()));
-    Color4<double> c = hsv2rgb_d(v);
-    return Color4<T>((T) (c.r * limits<T>::max()),
-                         (T) (c.g * limits<T>::max()),
-                         (T) (c.b * limits<T>::max()),
-             (T) (c.a * limits<T>::max()));
+       Color4<double> v = Color4<double>(hsv.r / float(limits<T>::max()),
+                                         hsv.g / float(limits<T>::max()),
+                                         hsv.b / float(limits<T>::max()),
+                                         hsv.a / float(limits<T>::max()));
+       Color4<double> c = hsv2rgb_d(v);
+       return Color4<T>((T) (c.r * limits<T>::max()),
+                        (T) (c.g * limits<T>::max()),
+                        (T) (c.b * limits<T>::max()),
+                        (T) (c.a * limits<T>::max()));
     }
     else
     {
-    Color4<double> v = Color4<double>(hsv.r, hsv.g, hsv.b, hsv.a);
-    Color4<double> c = hsv2rgb_d(v);
-    return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
+       Color4<double> v = Color4<double>(hsv.r, hsv.g, hsv.b, hsv.a);
+       Color4<double> c = hsv2rgb_d(v);
+       return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
     }
 }
 
 
-template<class T>
-Vec3<T>
+template<class T> 
+Vec3<T>  
 rgb2hsv(const Vec3<T> &rgb)
 {
     if ( limits<T>::isIntegral() )
     {
-    Vec3<double> v = Vec3<double>(rgb.x / double(limits<T>::max()),
-                      rgb.y / double(limits<T>::max()),
-                      rgb.z / double(limits<T>::max()));
-    Vec3<double> c = rgb2hsv_d(v);
-    return Vec3<T>((T) (c.x * limits<T>::max()),
-               (T) (c.y * limits<T>::max()),
-               (T) (c.z * limits<T>::max()));
+       Vec3<double> v = Vec3<double>(rgb.x / double(limits<T>::max()),
+                                     rgb.y / double(limits<T>::max()),
+                                     rgb.z / double(limits<T>::max()));
+       Vec3<double> c = rgb2hsv_d(v);
+       return Vec3<T>((T) (c.x * limits<T>::max()),
+                      (T) (c.y * limits<T>::max()),
+                      (T) (c.z * limits<T>::max()));
     }
     else
     {
-    Vec3<double> v = Vec3<double>(rgb.x, rgb.y, rgb.z);
-    Vec3<double> c = rgb2hsv_d(v);
-    return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
+       Vec3<double> v = Vec3<double>(rgb.x, rgb.y, rgb.z);
+       Vec3<double> c = rgb2hsv_d(v);
+       return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
     }
 }
 
 
-template<class T>
-Color4<T>
+template<class T> 
+Color4<T>  
 rgb2hsv(const Color4<T> &rgb)
 {
     if ( limits<T>::isIntegral() )
     {
-    Color4<double> v = Color4<double>(rgb.r / float(limits<T>::max()),
-                      rgb.g / float(limits<T>::max()),
-                      rgb.b / float(limits<T>::max()),
-                      rgb.a / float(limits<T>::max()));
-    Color4<double> c = rgb2hsv_d(v);
-    return Color4<T>((T) (c.r * limits<T>::max()),
-                         (T) (c.g * limits<T>::max()),
-                         (T) (c.b * limits<T>::max()),
-             (T) (c.a * limits<T>::max()));
+       Color4<double> v = Color4<double>(rgb.r / float(limits<T>::max()),
+                                         rgb.g / float(limits<T>::max()),
+                                         rgb.b / float(limits<T>::max()),
+                                         rgb.a / float(limits<T>::max()));
+       Color4<double> c = rgb2hsv_d(v);
+       return Color4<T>((T) (c.r * limits<T>::max()),
+                        (T) (c.g * limits<T>::max()),
+                        (T) (c.b * limits<T>::max()),
+                        (T) (c.a * limits<T>::max()));
     }
     else
     {
-    Color4<double> v = Color4<double>(rgb.r, rgb.g, rgb.b, rgb.a);
-    Color4<double> c = rgb2hsv_d(v);
-    return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
+       Color4<double> v = Color4<double>(rgb.r, rgb.g, rgb.b, rgb.a);
+       Color4<double> c = rgb2hsv_d(v);
+       return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
     }
 }
 
@@ -168,16 +169,16 @@ rgb2packed(const Vec3<T> &c)
 {
     if ( limits<T>::isIntegral() )
     {
-    float x = c.x / float(limits<T>::max());
-    float y = c.y / float(limits<T>::max());
-    float z = c.z / float(limits<T>::max());
-    return rgb2packed( V3f(x,y,z) );
+       float x = c.x / float(limits<T>::max());
+       float y = c.y / float(limits<T>::max());
+       float z = c.z / float(limits<T>::max());
+       return rgb2packed( V3f(x,y,z) );
     }
     else
     {
-    return (  (PackedColor) (c.x * 255)                |
-        (((PackedColor) (c.y * 255)) << 8)     |
-        (((PackedColor) (c.z * 255)) << 16)    | 0xFF000000 );
+       return (  (PackedColor) (c.x * 255)             |
+               (((PackedColor) (c.y * 255)) << 8)      |
+               (((PackedColor) (c.z * 255)) << 16)     | 0xFF000000 );
     }
 }
 
@@ -187,18 +188,18 @@ rgb2packed(const Color4<T> &c)
 {
     if ( limits<T>::isIntegral() )
     {
-    float r = c.r / float(limits<T>::max());
-    float g = c.g / float(limits<T>::max());
-    float b = c.b / float(limits<T>::max());
-    float a = c.a / float(limits<T>::max());
-    return rgb2packed( C4f(r,g,b,a) );
+       float r = c.r / float(limits<T>::max());
+       float g = c.g / float(limits<T>::max());
+       float b = c.b / float(limits<T>::max());
+       float a = c.a / float(limits<T>::max());
+       return rgb2packed( C4f(r,g,b,a) );
     }
     else
     {
-    return (  (PackedColor) (c.r * 255)                |
-        (((PackedColor) (c.g * 255)) << 8)     |
-        (((PackedColor) (c.b * 255)) << 16)    |
-        (((PackedColor) (c.a * 255)) << 24));
+       return (  (PackedColor) (c.r * 255)             |
+               (((PackedColor) (c.g * 255)) << 8)      |
+               (((PackedColor) (c.b * 255)) << 16)     |
+               (((PackedColor) (c.a * 255)) << 24));
     }
 }
 
@@ -214,17 +215,17 @@ packed2rgb(PackedColor packed, Vec3<T> &out)
 {
     if ( limits<T>::isIntegral() )
     {
-    T f = limits<T>::max() / ((PackedColor)0xFF);
-    out.x =  (packed &     0xFF) * f;
-    out.y = ((packed &   0xFF00) >>  8) * f;
-    out.z = ((packed & 0xFF0000) >> 16) * f;
+       T f = limits<T>::max() / ((PackedColor)0xFF);
+       out.x =  (packed &     0xFF) * f;
+       out.y = ((packed &   0xFF00) >>  8) * f;
+       out.z = ((packed & 0xFF0000) >> 16) * f;
     }
     else
     {
-    T f = T(1) / T(255);
-    out.x =  (packed &     0xFF) * f;
-    out.y = ((packed &   0xFF00) >>  8) * f;
-    out.z = ((packed & 0xFF0000) >> 16) * f;
+       T f = T(1) / T(255);
+       out.x =  (packed &     0xFF) * f;
+       out.y = ((packed &   0xFF00) >>  8) * f;
+       out.z = ((packed & 0xFF0000) >> 16) * f;
     }
 }
 
@@ -234,23 +235,23 @@ packed2rgb(PackedColor packed, Color4<T> &out)
 {
     if ( limits<T>::isIntegral() )
     {
-    T f = limits<T>::max() / ((PackedColor)0xFF);
-    out.r =  (packed &       0xFF) * f;
-    out.g = ((packed &     0xFF00) >>  8) * f;
-    out.b = ((packed &   0xFF0000) >> 16) * f;
-    out.a = ((packed & 0xFF000000) >> 24) * f;
+       T f = limits<T>::max() / ((PackedColor)0xFF);
+       out.r =  (packed &       0xFF) * f;
+       out.g = ((packed &     0xFF00) >>  8) * f;
+       out.b = ((packed &   0xFF0000) >> 16) * f;
+       out.a = ((packed & 0xFF000000) >> 24) * f;
     }
     else
     {
-    T f = T(1) / T(255);
-    out.r =  (packed &       0xFF) * f;
-    out.g = ((packed &     0xFF00) >>  8) * f;
-    out.b = ((packed &   0xFF0000) >> 16) * f;
-    out.a = ((packed & 0xFF000000) >> 24) * f;
+       T f = T(1) / T(255);
+       out.r =  (packed &       0xFF) * f;
+       out.g = ((packed &     0xFF00) >>  8) * f;
+       out.b = ((packed &   0xFF0000) >> 16) * f;
+       out.a = ((packed & 0xFF000000) >> 24) * f;
     }
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHCOLORALGO_H
index ffb144d..6b2b39e 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -51,7 +51,7 @@
 //     There are 24 possible combonations of Euler angle
 //     representations of which 12 are common in CG and you will
 //     probably only use 6 of these which in this scheme are the
-//     non-relative-non-repeating types.
+//     non-relative-non-repeating types. 
 //
 //     The representations can be partitioned according to two
 //     criteria:
@@ -66,7 +66,7 @@
 //     When you construct a given representation from scratch you
 //     must order the angles according to their priorities. So, the
 //     easiest is a softimage or aerospace (yaw/pitch/roll) ordering
-//     of ZYX.
+//     of ZYX. 
 //
 //         float x_rot = 1;
 //         float y_rot = 2;
 //     If you want to set the Euler with an XYZVector use the
 //     optional layout argument:
 //
-//         Eulerf angles(x_rot, y_rot, z_rot,
+//         Eulerf angles(x_rot, y_rot, z_rot, 
 //                       Eulerf::YXZ,
 //                       Eulerf::XYZLayout);
 //
 //     This is the same as:
 //
 //         Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ);
-//
+//         
 //     Note that this won't do anything intelligent if you have a
 //     repeated axis in the euler angles (e.g. XYX)
 //
 //     If you need to use the "relative" versions of these, you will
-//     need to use the "r" enums.
+//     need to use the "r" enums. 
 //
 //      The units of the rotation angles are assumed to be radians.
 //
 #include "ImathQuat.h"
 #include "ImathMatrix.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
+
 #include <iostream>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
 // Disable MS VC++ warnings about conversion from double to float
@@ -143,61 +145,61 @@ template <class T>
 class Euler : public Vec3<T>
 {
   public:
-
     using Vec3<T>::x;
     using Vec3<T>::y;
     using Vec3<T>::z;
 
     enum Order
     {
-    //
-    //  All 24 possible orderings
-    //
-
-    XYZ        = 0x0101,       // "usual" orderings
-    XZY        = 0x0001,
-    YZX        = 0x1101,
-    YXZ        = 0x1001,
-    ZXY        = 0x2101,
-    ZYX        = 0x2001,
-
-    XZX        = 0x0011,       // first axis repeated
-    XYX        = 0x0111,
-    YXY        = 0x1011,
-    YZY        = 0x1111,
-    ZYZ        = 0x2011,
-    ZXZ        = 0x2111,
-
-    XYZr       = 0x2000,       // relative orderings -- not common
-    XZYr       = 0x2100,
-    YZXr       = 0x1000,
-    YXZr       = 0x1100,
-    ZXYr       = 0x0000,
-    ZYXr       = 0x0100,
-
-    XZXr       = 0x2110,       // relative first axis repeated
-    XYXr       = 0x2010,
-    YXYr       = 0x1110,
-    YZYr       = 0x1010,
-    ZYZr       = 0x0110,
-    ZXZr       = 0x0010,
-    //          ||||
-    //          VVVV
-    //  Legend: ABCD
-    //  A -> Initial Axis (0==x, 1==y, 2==z)
-    //  B -> Parity Even (1==true)
-    //  C -> Initial Repeated (1==true)
-    //  D -> Frame Static (1==true)
-    //
-
-    Legal      =   XYZ | XZY | YZX | YXZ | ZXY | ZYX |
-            XZX | XYX | YXY | YZY | ZYZ | ZXZ |
-            XYZr| XZYr| YZXr| YXZr| ZXYr| ZYXr|
-            XZXr| XYXr| YXYr| YZYr| ZYZr| ZXZr,
-
-    Min        = 0x0000,
-    Max        = 0x2111,
-    Default    = XYZ
+       //
+       //  All 24 possible orderings
+       //
+
+       XYZ     = 0x0101,       // "usual" orderings
+       XZY     = 0x0001,
+       YZX     = 0x1101,
+       YXZ     = 0x1001,
+       ZXY     = 0x2101,
+       ZYX     = 0x2001,
+       
+       XZX     = 0x0011,       // first axis repeated
+       XYX     = 0x0111,
+       YXY     = 0x1011,
+       YZY     = 0x1111,
+       ZYZ     = 0x2011,
+       ZXZ     = 0x2111,
+
+       XYZr    = 0x2000,       // relative orderings -- not common
+       XZYr    = 0x2100,
+       YZXr    = 0x1000,
+       YXZr    = 0x1100,
+       ZXYr    = 0x0000,
+       ZYXr    = 0x0100,
+       
+       XZXr    = 0x2110,       // relative first axis repeated 
+       XYXr    = 0x2010,
+       YXYr    = 0x1110,
+       YZYr    = 0x1010,
+       ZYZr    = 0x0110,
+       ZXZr    = 0x0010,
+       //          ||||
+       //          VVVV
+       //  Legend: ABCD
+       //  A -> Initial Axis (0==x, 1==y, 2==z)
+       //  B -> Parity Even (1==true)
+       //  C -> Initial Repeated (1==true)
+       //  D -> Frame Static (1==true)
+       //
+
+       Legal   =   XYZ | XZY | YZX | YXZ | ZXY | ZYX |
+                   XZX | XYX | YXY | YZY | ZYZ | ZXZ |
+                   XYZr| XZYr| YZXr| YXZr| ZXYr| ZYXr|
+                   XZXr| XYXr| YXYr| YZYr| ZYZr| ZXZr,
+
+       Min     = 0x0000,
+       Max     = 0x2111,
+       Default = XYZ
     };
 
     enum Axis { X = 0, Y = 1, Z = 2 };
@@ -233,7 +235,7 @@ class Euler : public Vec3<T>
 
     //--------------------------------------------------------
     // Set the euler value
-    //  This does NOT convert the angles, but setXYZVector()
+    //  This does NOT convert the angles, but setXYZVector() 
     // does reorder the input vector.
     //--------------------------------------------------------
 
@@ -245,9 +247,9 @@ class Euler : public Vec3<T>
     void               setOrder(Order);
 
     void               set(Axis initial,
-                bool relative,
-                bool parityEven,
-                bool firstRepeats);
+                           bool relative,
+                           bool parityEven,
+                           bool firstRepeats);
 
     //------------------------------------------------------------
     // Conversions, toXYZVector() reorders the angles so that
@@ -282,7 +284,7 @@ class Euler : public Vec3<T>
     // Use this function to determine mapping from xyz to ijk
     // - reshuffles the xyz to match the order
     //---------------------------------------------------
-
+    
     void               angleMapping(int &i, int &j, int &k) const;
 
     //----------------------------------------------------------------------
@@ -311,10 +313,10 @@ class Euler : public Vec3<T>
 
     static float       angleMod (T angle);
     static void                simpleXYZRotation (Vec3<T> &xyzRot,
-                       const Vec3<T> &targetXyzRot);
+                                          const Vec3<T> &targetXyzRot);
     static void                nearestRotation (Vec3<T> &xyzRot,
-                     const Vec3<T> &targetXyzRot,
-                     Order order = XYZ);
+                                        const Vec3<T> &targetXyzRot,
+                                        Order order = XYZ);
 
     void               makeNear (const Euler<T> &target);
 
@@ -413,11 +415,11 @@ Euler<T>::Euler(typename Euler<T>::Order p) :
 }
 
 template<class T>
-inline Euler<T>::Euler( const Vec3<T> &v,
-            typename Euler<T>::Order p,
-            typename Euler<T>::InputLayout l )
+inline Euler<T>::Euler( const Vec3<T> &v, 
+                       typename Euler<T>::Order p, 
+                       typename Euler<T>::InputLayout l ) 
 {
-    setOrder(p);
+    setOrder(p); 
     if ( l == XYZLayout ) setXYZVector(v);
     else { x = v.x; y = v.y; z = v.z; }
 }
@@ -437,9 +439,9 @@ inline Euler<T>::Euler(const Euler<T> &euler,Order p)
 }
 
 template<class T>
-inline Euler<T>::Euler( T xi, T yi, T zi,
-            typename Euler<T>::Order p,
-            typename Euler<T>::InputLayout l)
+inline Euler<T>::Euler( T xi, T yi, T zi, 
+                       typename Euler<T>::Order p,
+                       typename Euler<T>::InputLayout l)
 {
     setOrder(p);
     if ( l == XYZLayout ) setXYZVector(Vec3<T>(xi,yi,zi));
@@ -474,77 +476,77 @@ void Euler<T>::extract(const Matrix33<T> &M)
 
     if (_initialRepeated)
     {
-    //
-    // Extract the first angle, x.
-    //
-
-    x = Math<T>::atan2 (M[j][i], M[k][i]);
-
-    //
-    // Remove the x rotation from M, so that the remaining
-    // rotation, N, is only around two axes, and gimbal lock
-    // cannot occur.
-    //
-
-    Vec3<T> r (0, 0, 0);
-    r[i] = (_parityEven? -x: x);
-
-    Matrix44<T> N;
-    N.rotate (r);
-
-    N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
-                 M[1][0], M[1][1], M[1][2], 0,
-                 M[2][0], M[2][1], M[2][2], 0,
-                 0,       0,       0,       1);
-    //
-    // Extract the other two angles, y and z, from N.
-    //
-
-    T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
-    y = Math<T>::atan2 (sy, N[i][i]);
-    z = Math<T>::atan2 (N[j][k], N[j][j]);
+       //
+       // Extract the first angle, x.
+       // 
+
+       x = Math<T>::atan2 (M[j][i], M[k][i]);
+
+       //
+       // Remove the x rotation from M, so that the remaining
+       // rotation, N, is only around two axes, and gimbal lock
+       // cannot occur.
+       //
+
+       Vec3<T> r (0, 0, 0);
+       r[i] = (_parityEven? -x: x);
+
+       Matrix44<T> N;
+       N.rotate (r);
+
+       N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
+                            M[1][0], M[1][1], M[1][2], 0,
+                            M[2][0], M[2][1], M[2][2], 0,
+                            0,       0,       0,       1);
+       //
+       // Extract the other two angles, y and z, from N.
+       //
+
+       T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
+       y = Math<T>::atan2 (sy, N[i][i]);
+       z = Math<T>::atan2 (N[j][k], N[j][j]);
     }
     else
     {
-    //
-    // Extract the first angle, x.
-    //
-
-    x = Math<T>::atan2 (M[j][k], M[k][k]);
-
-    //
-    // Remove the x rotation from M, so that the remaining
-    // rotation, N, is only around two axes, and gimbal lock
-    // cannot occur.
-    //
-
-    Vec3<T> r (0, 0, 0);
-    r[i] = (_parityEven? -x: x);
-
-    Matrix44<T> N;
-    N.rotate (r);
-
-    N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
-                 M[1][0], M[1][1], M[1][2], 0,
-                 M[2][0], M[2][1], M[2][2], 0,
-                 0,       0,       0,       1);
-    //
-    // Extract the other two angles, y and z, from N.
-    //
-
-    T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
-    y = Math<T>::atan2 (-N[i][k], cy);
-    z = Math<T>::atan2 (-N[j][i], N[j][j]);
+       //
+       // Extract the first angle, x.
+       // 
+
+       x = Math<T>::atan2 (M[j][k], M[k][k]);
+
+       //
+       // Remove the x rotation from M, so that the remaining
+       // rotation, N, is only around two axes, and gimbal lock
+       // cannot occur.
+       //
+
+       Vec3<T> r (0, 0, 0);
+       r[i] = (_parityEven? -x: x);
+
+       Matrix44<T> N;
+       N.rotate (r);
+
+       N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
+                            M[1][0], M[1][1], M[1][2], 0,
+                            M[2][0], M[2][1], M[2][2], 0,
+                            0,       0,       0,       1);
+       //
+       // Extract the other two angles, y and z, from N.
+       //
+
+       T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
+       y = Math<T>::atan2 (-N[i][k], cy);
+       z = Math<T>::atan2 (-N[j][i], N[j][j]);
     }
 
     if (!_parityEven)
-    *this *= -1;
+       *this *= -1;
 
     if (!_frameStatic)
     {
-    T t = x;
-    x = z;
-    z = t;
+       T t = x;
+       x = z;
+       z = t;
     }
 }
 
@@ -556,71 +558,71 @@ void Euler<T>::extract(const Matrix44<T> &M)
 
     if (_initialRepeated)
     {
-    //
-    // Extract the first angle, x.
-    //
+       //
+       // Extract the first angle, x.
+       // 
 
-    x = Math<T>::atan2 (M[j][i], M[k][i]);
+       x = Math<T>::atan2 (M[j][i], M[k][i]);
 
-    //
-    // Remove the x rotation from M, so that the remaining
-    // rotation, N, is only around two axes, and gimbal lock
-    // cannot occur.
-    //
+       //
+       // Remove the x rotation from M, so that the remaining
+       // rotation, N, is only around two axes, and gimbal lock
+       // cannot occur.
+       //
 
-    Vec3<T> r (0, 0, 0);
-    r[i] = (_parityEven? -x: x);
+       Vec3<T> r (0, 0, 0);
+       r[i] = (_parityEven? -x: x);
 
-    Matrix44<T> N;
-    N.rotate (r);
-    N = N * M;
+       Matrix44<T> N;
+       N.rotate (r);
+       N = N * M;
 
-    //
-    // Extract the other two angles, y and z, from N.
-    //
+       //
+       // Extract the other two angles, y and z, from N.
+       //
 
-    T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
-    y = Math<T>::atan2 (sy, N[i][i]);
-    z = Math<T>::atan2 (N[j][k], N[j][j]);
+       T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
+       y = Math<T>::atan2 (sy, N[i][i]);
+       z = Math<T>::atan2 (N[j][k], N[j][j]);
     }
     else
     {
-    //
-    // Extract the first angle, x.
-    //
+       //
+       // Extract the first angle, x.
+       // 
 
-    x = Math<T>::atan2 (M[j][k], M[k][k]);
+       x = Math<T>::atan2 (M[j][k], M[k][k]);
 
-    //
-    // Remove the x rotation from M, so that the remaining
-    // rotation, N, is only around two axes, and gimbal lock
-    // cannot occur.
-    //
+       //
+       // Remove the x rotation from M, so that the remaining
+       // rotation, N, is only around two axes, and gimbal lock
+       // cannot occur.
+       //
 
-    Vec3<T> r (0, 0, 0);
-    r[i] = (_parityEven? -x: x);
+       Vec3<T> r (0, 0, 0);
+       r[i] = (_parityEven? -x: x);
 
-    Matrix44<T> N;
-    N.rotate (r);
-    N = N * M;
+       Matrix44<T> N;
+       N.rotate (r);
+       N = N * M;
 
-    //
-    // Extract the other two angles, y and z, from N.
-    //
+       //
+       // Extract the other two angles, y and z, from N.
+       //
 
-    T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
-    y = Math<T>::atan2 (-N[i][k], cy);
-    z = Math<T>::atan2 (-N[j][i], N[j][j]);
+       T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
+       y = Math<T>::atan2 (-N[i][k], cy);
+       z = Math<T>::atan2 (-N[j][i], N[j][j]);
     }
 
     if (!_parityEven)
-    *this *= -1;
+       *this *= -1;
 
     if (!_frameStatic)
     {
-    T t = x;
-    x = z;
-    z = t;
+       T t = x;
+       x = z;
+       z = t;
     }
 }
 
@@ -653,15 +655,15 @@ Matrix33<T> Euler<T>::toMatrix33() const
 
     if ( _initialRepeated )
     {
-    M[i][i] = cj;        M[j][i] =  sj*si;    M[k][i] =  sj*ci;
-    M[i][j] = sj*sh;  M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
-    M[i][k] = -sj*ch; M[j][k] =  cj*sc+cs; M[k][k] =  cj*cc-ss;
+       M[i][i] = cj;     M[j][i] =  sj*si;    M[k][i] =  sj*ci;
+       M[i][j] = sj*sh;  M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
+       M[i][k] = -sj*ch; M[j][k] =  cj*sc+cs; M[k][k] =  cj*cc-ss;
     }
     else
     {
-    M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
-    M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
-    M[i][k] = -sj;      M[j][k] = cj*si;    M[k][k] = cj*ci;
+       M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
+       M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
+       M[i][k] = -sj;   M[j][k] = cj*si;    M[k][k] = cj*ci;
     }
 
     return M;
@@ -696,15 +698,15 @@ Matrix44<T> Euler<T>::toMatrix44() const
 
     if ( _initialRepeated )
     {
-    M[i][i] = cj;        M[j][i] =  sj*si;    M[k][i] =  sj*ci;
-    M[i][j] = sj*sh;  M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
-    M[i][k] = -sj*ch; M[j][k] =  cj*sc+cs; M[k][k] =  cj*cc-ss;
+       M[i][i] = cj;     M[j][i] =  sj*si;    M[k][i] =  sj*ci;
+       M[i][j] = sj*sh;  M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
+       M[i][k] = -sj*ch; M[j][k] =  cj*sc+cs; M[k][k] =  cj*cc-ss;
     }
     else
     {
-    M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
-    M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
-    M[i][k] = -sj;      M[j][k] = cj*si;    M[k][k] = cj*ci;
+       M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
+       M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
+       M[i][k] = -sj;   M[j][k] = cj*si;    M[k][k] = cj*ci;
     }
 
     return M;
@@ -743,17 +745,17 @@ Quat<T> Euler<T>::toQuat() const
 
     if ( _initialRepeated )
     {
-    a[i]       = cj*(cs + sc);
-    a[j]       = sj*(cc + ss) * parity,
-    a[k]       = sj*(cs - sc);
-    q.r        = cj*(cc - ss);
+       a[i]    = cj*(cs + sc);
+       a[j]    = sj*(cc + ss) * parity,
+       a[k]    = sj*(cs - sc);
+       q.r     = cj*(cc - ss);
     }
     else
     {
-    a[i]       = cj*sc - sj*cs,
-    a[j]       = (cj*ss + sj*cc) * parity,
-    a[k]       = cj*cs - sj*sc;
-    q.r        = cj*cc + sj*ss;
+       a[i]    = cj*sc - sj*cs,
+       a[j]    = (cj*ss + sj*cc) * parity,
+       a[k]    = cj*cs - sj*sc;
+       q.r     = cj*cc + sj*ss;
     }
 
     q.v = a;
@@ -785,16 +787,16 @@ template<class T>
 inline void Euler<T>::setOrder(typename Euler<T>::Order p)
 {
     set( p & 0x2000 ? Z : (p & 0x1000 ? Y : X),        // initial axis
-     !(p & 0x1),                               // static?
-     !!(p & 0x100),                            // permutation even?
-     !!(p & 0x10));                            // initial repeats?
+        !(p & 0x1),                            // static?
+        !!(p & 0x100),                         // permutation even?
+        !!(p & 0x10));                         // initial repeats?
 }
 
 template<class T>
 void Euler<T>::set(typename Euler<T>::Axis axis,
-           bool relative,
-           bool parityEven,
-           bool firstRepeats)
+                  bool relative,
+                  bool parityEven,
+                  bool firstRepeats)
 {
     _initialAxis       = axis;
     _frameStatic       = !relative;
@@ -836,20 +838,21 @@ std::ostream& operator << (std::ostream &o, const Euler<T> &euler)
     if ( euler.initialRepeated() ) k = i;
 
     return o << "("
-         << euler.x << " "
-         << euler.y << " "
-         << euler.z << " "
-         << a[i] << a[j] << a[k] << r << ")";
+            << euler.x << " "
+            << euler.y << " "
+            << euler.z << " "
+            << a[i] << a[j] << a[k] << r << ")";
 }
 
 template <class T>
 float
 Euler<T>::angleMod (T angle)
 {
-    angle = fmod(T (angle), T (2 * M_PI));
+    const T pi = static_cast<T>(M_PI);
+    angle = fmod(T (angle), T (2 * pi));
 
-    if (angle < -M_PI) angle += 2 * M_PI;
-    if (angle > +M_PI) angle -= 2 * M_PI;
+    if (angle < -pi)   angle += 2 * pi;
+    if (angle > +pi)   angle -= 2 * pi;
 
     return angle;
 }
@@ -867,7 +870,7 @@ Euler<T>::simpleXYZRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot)
 template <class T>
 void
 Euler<T>::nearestRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot,
-               Order order)
+                          Order order)
 {
     int i,j,k;
     Euler<T> e (0,0,0, order);
@@ -881,7 +884,7 @@ Euler<T>::nearestRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot,
     otherXyzRot[k] = M_PI+xyzRot[k];
 
     simpleXYZRotation(otherXyzRot, targetXyzRot);
-
+           
     Vec3<T> d  = xyzRot - targetXyzRot;
     Vec3<T> od = otherXyzRot - targetXyzRot;
     T dMag     = d.dot(d);
@@ -889,7 +892,7 @@ Euler<T>::nearestRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot,
 
     if (odMag < dMag)
     {
-    xyzRot = otherXyzRot;
+       xyzRot = otherXyzRot;
     }
 }
 
@@ -918,7 +921,7 @@ Euler<T>::makeNear (const Euler<T> &target)
 #pragma warning(default:4244)
 #endif
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
-#endif
+#endif // INCLUDED_IMATHEULER_H
index 02ec627..65af3b5 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -33,7 +33,6 @@
 ///////////////////////////////////////////////////////////////////////////
 
 
-
 #ifndef INCLUDED_IMATHEXC_H
 #define INCLUDED_IMATHEXC_H
 
 //
 //-----------------------------------------------
 
+#include "ImathNamespace.h"
 #include "IexBaseExc.h"
+#include "ImathExport.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
+// Attempt to normalize null vector
+DEFINE_EXC_EXP (IMATH_EXPORT, NullVecExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (NullVecExc, ::Iex::MathExc)                // Attempt to normalize
-                        // null vector
+// Attempt to normalize a point at infinity
+DEFINE_EXC_EXP (IMATH_EXPORT, InfPointExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (InfPointExc, ::Iex::MathExc)       // Attempt to normalize
-                                                // a point at infinity
+// Attempt to normalize null quaternion
+DEFINE_EXC_EXP (IMATH_EXPORT, NullQuatExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (NullQuatExc, ::Iex::MathExc)       // Attempt to normalize
-                        // null quaternion
+// Attempt to invert singular matrix
+DEFINE_EXC_EXP (IMATH_EXPORT, SingMatrixExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (SingMatrixExc, ::Iex::MathExc)     // Attempt to invert
-                        // singular matrix
+// Attempt to remove zero scaling from matrix
+DEFINE_EXC_EXP (IMATH_EXPORT, ZeroScaleExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (ZeroScaleExc, ::Iex::MathExc)      // Attempt to remove zero
-                        // scaling from matrix
+// Attempt to normalize a vector of whose elementsare an integer type
+DEFINE_EXC_EXP (IMATH_EXPORT, IntVecNormalizeExc, ::IEX_NAMESPACE::MathExc)
 
-DEFINE_EXC (IntVecNormalizeExc, ::Iex::MathExc)        // Attempt to normalize
-                        // a vector of whose elements
-                                                // are an integer type
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHEXC_H
diff --git a/3rdparty/openexr/Imath/ImathExport.h b/3rdparty/openexr/Imath/ImathExport.h
new file mode 100644 (file)
index 0000000..4357c12
--- /dev/null
@@ -0,0 +1,46 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#if defined(OPENEXR_DLL)
+    #if defined(IMATH_EXPORTS)
+           #define IMATH_EXPORT __declspec(dllexport)
+        #define IMATH_EXPORT_CONST extern __declspec(dllexport)
+    #else
+           #define IMATH_EXPORT __declspec(dllimport)
+           #define IMATH_EXPORT_CONST extern __declspec(dllimport)
+    #endif
+#else
+    #define IMATH_EXPORT
+    #define IMATH_EXPORT_CONST extern const
+#endif
diff --git a/3rdparty/openexr/Imath/ImathForward.h b/3rdparty/openexr/Imath/ImathForward.h
new file mode 100644 (file)
index 0000000..39d398c
--- /dev/null
@@ -0,0 +1,72 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMATHFORWARD_H
+#define INCLUDED_IMATHFORWARD_H
+
+#include "ImathNamespace.h"
+
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
+
+//
+// Basic template type declarations.
+//
+
+template <class T> class Box;
+template <class T> class Color3;
+template <class T> class Color4;
+template <class T> class Euler;
+template <class T> class Frustum;
+template <class T> class FrustumTest;
+template <class T> class Interval;
+template <class T> class Line3;
+template <class T> class Matrix33;
+template <class T> class Matrix44;
+template <class T> class Plane3;
+template <class T> class Quat;
+template <class T> class Shear6;
+template <class T> class Sphere3;
+template <class T> class TMatrix;
+template <class T> class TMatrixBase;
+template <class T> class TMatrixData;
+template <class T> class Vec2;
+template <class T> class Vec3;
+template <class T> class Vec4;
+
+class Rand32;
+class Rand48;
+
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IMATHFORWARD_H
index c7645fc..95ebb66 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #ifndef INCLUDED_IMATHFRAME_H
 #define INCLUDED_IMATHFRAME_H
 
-namespace Imath {
+#include "ImathNamespace.h"
+
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template<class T> class Vec3;
 template<class T> class Matrix44;
 
 //
 //  These methods compute a set of reference frames, defined by their
-//  transformation matrix, along a curve. It is designed so that the
-//  array of points and the array of matrices used to fetch these routines
+//  transformation matrix, along a curve. It is designed so that the 
+//  array of points and the array of matrices used to fetch these routines 
 //  don't need to be ordered as the curve.
-//
+//  
 //  A typical usage would be :
 //
-//      m[0] = Imath::firstFrame( p[0], p[1], p[2] );
+//      m[0] = IMATH_INTERNAL_NAMESPACE::firstFrame( p[0], p[1], p[2] );
 //      for( int i = 1; i < n - 1; i++ )
 //      {
-//          m[i] = Imath::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
+//          m[i] = IMATH_INTERNAL_NAMESPACE::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
 //      }
-//      m[n-1] = Imath::lastFrame( m[n-2], p[n-2], p[n-1] );
+//      m[n-1] = IMATH_INTERNAL_NAMESPACE::lastFrame( m[n-2], p[n-2], p[n-1] );
 //
 //  See Graphics Gems I for the underlying algorithm.
-//
+// 
 
 template<class T> Matrix44<T> firstFrame( const Vec3<T>&,    // First point
-                                          const Vec3<T>&,    // Second point
+                                          const Vec3<T>&,    // Second point 
                                           const Vec3<T>& );  // Third point
 
 template<class T> Matrix44<T> nextFrame( const Matrix44<T>&, // Previous matrix
@@ -86,7 +88,7 @@ template<class T> Matrix44<T> lastFrame( const Matrix44<T>&, // Previous matrix
 //
 
 template<class T> Matrix44<T> firstFrame
-(
+( 
     const Vec3<T>& pi,             // First point
     const Vec3<T>& pj,             // Second point
     const Vec3<T>& pk )            // Third point
@@ -118,13 +120,13 @@ template<class T> Matrix44<T> firstFrame
 //
 //  nextFrame - Compute the next reference frame along a curve.
 //
-//  This function returns the transformation matrix to the next reference
+//  This function returns the transformation matrix to the next reference 
 //  frame defined by the previously computed transformation matrix and the
 //  new point and tangent vector along the curve.
 //
 
 template<class T> Matrix44<T> nextFrame
-(
+( 
     const Matrix44<T>&  Mi,             // Previous matrix
     const Vec3<T>&      pi,             // Previous point
     const Vec3<T>&      pj,             // Current point
@@ -137,13 +139,13 @@ template<class T> Matrix44<T> nextFrame
     if( ti.length() != 0.0 && tj.length() != 0.0 )
     {
         ti.normalize(); tj.normalize();
-        T dot = ti.dot( tj );
+        T dot = ti.dot( tj ); 
 
         //
         //  This is *really* necessary :
         //
 
-        if( dot > 1.0 ) dot = 1.0;
+        if( dot > 1.0 ) dot = 1.0; 
         else if( dot < -1.0 ) dot = -1.0;
 
         r = acosf( dot );
@@ -169,13 +171,13 @@ template<class T> Matrix44<T> nextFrame
 //
 //  lastFrame - Compute the last reference frame along a curve.
 //
-//  This function returns the transformation matrix to the last reference
+//  This function returns the transformation matrix to the last reference 
 //  frame defined by the previously computed transformation matrix and the
 //  last point along the curve.
 //
 
 template<class T> Matrix44<T> lastFrame
-(
+( 
     const Matrix44<T>&  Mi,             // Previous matrix
     const Vec3<T>&      pi,             // Previous point
     const Vec3<T>&      pj )            // Last point
@@ -185,6 +187,6 @@ template<class T> Matrix44<T> lastFrame
     return Mi * Tr;
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHFRAME_H
index d3e5dd4..4df92c9 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include "ImathMatrix.h"
 #include "ImathLimits.h"
 #include "ImathFun.h"
+#include "ImathNamespace.h"
+
 #include "IexMathExc.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //
-//     template class Frustum<T>
+//  template class Frustum<T>
 //
-//     The frustum is always located with the eye point at the
-//     origin facing down -Z. This makes the Frustum class
-//     compatable with OpenGL (or anything that assumes a camera
-//     looks down -Z, hence with a right-handed coordinate system)
-//     but not with RenderMan which assumes the camera looks down
-//     +Z. Additional functions are provided for conversion from
-//     and from various camera coordinate spaces.
+//  The frustum is always located with the eye point at the
+//  origin facing down -Z. This makes the Frustum class
+//  compatable with OpenGL (or anything that assumes a camera
+//  looks down -Z, hence with a right-handed coordinate system)
+//  but not with RenderMan which assumes the camera looks down
+//  +Z. Additional functions are provided for conversion from
+//  and from various camera coordinate spaces.
 //
-//      nearPlane/farPlane: near/far are keywords used by Microsoft's
-//      compiler, so we use nearPlane/farPlane instead to avoid
-//      issues.
+//  nearPlane/farPlane: near/far are keywords used by Microsoft's
+//  compiler, so we use nearPlane/farPlane instead to avoid
+//  issues.
 
 
 template<class T>
@@ -78,46 +80,46 @@ class Frustum
     // Assignment operator
     //--------------------
 
-    const Frustum &operator    = (const Frustum &);
+    const Frustum &     operator = (const Frustum &);
 
     //--------------------
     //  Operators:  ==, !=
     //--------------------
-
-    bool                        operator == (const Frustum<T> &src) const;
-    bool                        operator != (const Frustum<T> &src) const;
+    
+    bool                operator == (const Frustum<T> &src) const;
+    bool                operator != (const Frustum<T> &src) const;
 
     //--------------------------------------------------------
     //  Set functions change the entire state of the Frustum
     //--------------------------------------------------------
 
-    void               set(T nearPlane, T farPlane,
-                T left, T right,
-                T top, T bottom,
-                bool ortho=false);
+    void                set(T nearPlane, T farPlane,
+                            T left, T right,
+                            T top, T bottom,
+                            bool ortho=false);
 
-    void               set(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
+    void                set(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
 
     //------------------------------------------------------
     // These functions modify an already valid frustum state
     //------------------------------------------------------
 
-    void               modifyNearAndFar(T nearPlane, T farPlane);
-    void               setOrthographic(bool);
+    void                modifyNearAndFar(T nearPlane, T farPlane);
+    void                setOrthographic(bool);
 
     //--------------
     //  Access
     //--------------
-
-    bool               orthographic() const    { return _orthographic; }
-    T                  nearPlane() const       { return _nearPlane;    }
-    T                  hither() const          { return _nearPlane;    }
-    T                  farPlane() const        { return _farPlane;     }
-    T                  yon() const             { return _farPlane;     }
-    T                  left() const            { return _left;         }
-    T                  right() const           { return _right;        }
-    T                  bottom() const          { return _bottom;       }
-    T                  top() const             { return _top;          }
+    
+    bool                orthographic() const  { return _orthographic; }
+    T                   nearPlane() const     { return _nearPlane;    }
+    T                   hither() const        { return _nearPlane;    }
+    T                   farPlane() const      { return _farPlane;     }
+    T                   yon() const           { return _farPlane;     }
+    T                   left() const          { return _left;         }
+    T                   right() const         { return _right;        }
+    T                   bottom() const        { return _bottom;       }
+    T                   top() const           { return _top;          }
 
     //-----------------------------------------------------------------------
     //  Sets the planes in p to be the six bounding planes of the frustum, in
@@ -127,56 +129,56 @@ class Frustum
     //  to transform the frustum before setting the planes.
     //-----------------------------------------------------------------------
 
-    void               planes(Plane3<T> p[6]);
-    void               planes(Plane3<T> p[6], const Matrix44<T> &M);
+    void                planes(Plane3<T> p[6]) const;
+    void                planes(Plane3<T> p[6], const Matrix44<T> &M) const;
 
     //----------------------
     //  Derived Quantities
     //----------------------
 
-    T                           fovx() const;
-    T                           fovy() const;
-    T                           aspect() const;
-    Matrix44<T>                 projectionMatrix() const;
-    bool                        degenerate() const;
+    T                   fovx() const;
+    T                   fovy() const;
+    T                   aspect() const;
+    Matrix44<T>         projectionMatrix() const;
+    bool                degenerate() const;
 
     //-----------------------------------------------------------------------
-    //  Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1
+    //  Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1 
     //  and -1 <= bottom <= top <= 1) of this Frustum, and returns a new
     //  Frustum whose near clipping-plane window is that rectangle in local
-    //  space.
+    //  space.  
     //-----------------------------------------------------------------------
 
-    Frustum<T>         window(T left, T right, T top, T bottom) const;
+    Frustum<T>          window(T left, T right, T top, T bottom) const;
 
     //----------------------------------------------------------
     // Projection is in screen space / Conversion from Z-Buffer
     //----------------------------------------------------------
 
-    Line3<T>           projectScreenToRay( const Vec2<T> & ) const;
-    Vec2<T>            projectPointToScreen( const Vec3<T> & ) const;
+    Line3<T>            projectScreenToRay( const Vec2<T> & ) const;
+    Vec2<T>             projectPointToScreen( const Vec3<T> & ) const;
 
-    T                  ZToDepth(long zval, long min, long max) const;
-    T                  normalizedZToDepth(T zval) const;
-    long               DepthToZ(T depth, long zmin, long zmax) const;
+    T                   ZToDepth(long zval, long min, long max) const;
+    T                   normalizedZToDepth(T zval) const;
+    long                DepthToZ(T depth, long zmin, long zmax) const;
 
-    T                  worldRadius(const Vec3<T> &p, T radius) const;
-    T                  screenRadius(const Vec3<T> &p, T radius) const;
+    T                   worldRadius(const Vec3<T> &p, T radius) const;
+    T                   screenRadius(const Vec3<T> &p, T radius) const;
 
 
   protected:
 
-    Vec2<T>            screenToLocal( const Vec2<T> & ) const;
-    Vec2<T>            localToScreen( const Vec2<T> & ) const;
+    Vec2<T>             screenToLocal( const Vec2<T> & ) const;
+    Vec2<T>             localToScreen( const Vec2<T> & ) const;
 
   protected:
-    T                  _nearPlane;
-    T                  _farPlane;
-    T                  _left;
-    T                  _right;
-    T                  _top;
-    T                  _bottom;
-    bool               _orthographic;
+    T                   _nearPlane;
+    T                   _farPlane;
+    T                   _left;
+    T                   _right;
+    T                   _top;
+    T                   _bottom;
+    bool                _orthographic;
 };
 
 
@@ -184,12 +186,12 @@ template<class T>
 inline Frustum<T>::Frustum()
 {
     set(T (0.1),
-    T (1000.0),
-    T (-1.0),
-    T (1.0),
-    T (1.0),
-    T (-1.0),
-    false);
+        T (1000.0),
+        T (-1.0),
+        T (1.0),
+        T (1.0),
+        T (-1.0),
+        false);
 }
 
 template<class T>
@@ -255,11 +257,11 @@ template<class T>
 void Frustum<T>::set(T n, T f, T l, T r, T t, T b, bool o)
 {
     _nearPlane      = n;
-    _farPlane      = f;
-    _left          = l;
-    _right         = r;
-    _bottom        = b;
-    _top           = t;
+    _farPlane       = f;
+    _left           = l;
+    _right          = r;
+    _bottom         = b;
+    _top            = t;
     _orthographic   = o;
 }
 
@@ -268,24 +270,24 @@ void Frustum<T>::modifyNearAndFar(T n, T f)
 {
     if ( _orthographic )
     {
-    _nearPlane = n;
+        _nearPlane = n;
     }
     else
     {
-    Line3<T>  lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_nearPlane) );
-    Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_nearPlane) );
-    Plane3<T> nearPlane( Vec3<T>(0,0,-1), n );
-
-    Vec3<T> ll,ur;
-    nearPlane.intersect(lowerLeft,ll);
-    nearPlane.intersect(upperRight,ur);
-
-    _left      = ll.x;
-    _right     = ur.x;
-    _top       = ur.y;
-    _bottom    = ll.y;
-    _nearPlane = n;
-    _farPlane  = f;
+        Line3<T>  lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_nearPlane) );
+        Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_nearPlane) );
+        Plane3<T> nearPlane( Vec3<T>(0,0,-1), n );
+
+        Vec3<T> ll,ur;
+        nearPlane.intersect(lowerLeft,ll);
+        nearPlane.intersect(upperRight,ur);
+
+        _left      = ll.x;
+        _right     = ur.x;
+        _top       = ur.y;
+        _bottom    = ll.y;
+        _nearPlane = n;
+        _farPlane  = f;
     }
 
     _farPlane = f;
@@ -301,27 +303,27 @@ template<class T>
 void Frustum<T>::set(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
 {
     if (fovx != 0 && fovy != 0)
-    throw Iex::ArgExc ("fovx and fovy cannot both be non-zero.");
+        throw IEX_NAMESPACE::ArgExc ("fovx and fovy cannot both be non-zero.");
 
     const T two = static_cast<T>(2);
 
     if (fovx != 0)
     {
-    _right         = nearPlane * Math<T>::tan(fovx / two);
-    _left          = -_right;
-    _top           = ((_right - _left) / aspect) / two;
-    _bottom        = -_top;
+        _right    = nearPlane * Math<T>::tan(fovx / two);
+        _left     = -_right;
+        _top      = ((_right - _left) / aspect) / two;
+        _bottom   = -_top;
     }
     else
     {
-    _top           = nearPlane * Math<T>::tan(fovy / two);
-    _bottom        = -_top;
-    _right         = (_top - _bottom) * aspect / two;
-    _left          = -_right;
+        _top      = nearPlane * Math<T>::tan(fovy / two);
+        _bottom   = -_top;
+        _right    = (_top - _bottom) * aspect / two;
+        _left     = -_right;
     }
-    _nearPlane     = nearPlane;
-    _farPlane      = farPlane;
-    _orthographic   = false;
+    _nearPlane    = nearPlane;
+    _farPlane     = farPlane;
+    _orthographic = false;
 }
 
 template<class T>
@@ -343,10 +345,10 @@ T Frustum<T>::aspect() const
     T topMinusBottom = _top-_bottom;
 
     if (abs(topMinusBottom) < 1 &&
-    abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
+        abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
     {
-    throw Iex::DivzeroExc ("Bad viewing frustum: "
-                   "aspect ratio cannot be computed.");
+        throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                               "aspect ratio cannot be computed.");
     }
 
     return rightMinusLeft / topMinusBottom;
@@ -365,76 +367,76 @@ Matrix44<T> Frustum<T>::projectionMatrix() const
     T farMinusNear   = _farPlane-_nearPlane;
 
     if ((abs(rightMinusLeft) < 1 &&
-     abs(rightPlusLeft) > limits<T>::max() * abs(rightMinusLeft)) ||
-    (abs(topMinusBottom) < 1 &&
-     abs(topPlusBottom) > limits<T>::max() * abs(topMinusBottom)) ||
-    (abs(farMinusNear) < 1 &&
-     abs(farPlusNear) > limits<T>::max() * abs(farMinusNear)))
-    {
-    throw Iex::DivzeroExc ("Bad viewing frustum: "
-                   "projection matrix cannot be computed.");
-    }
-
-    if ( _orthographic )
-    {
-    T tx = -rightPlusLeft / rightMinusLeft;
-    T ty = -topPlusBottom / topMinusBottom;
-    T tz = -farPlusNear   / farMinusNear;
-
-    if ((abs(rightMinusLeft) < 1 &&
-         2 > limits<T>::max() * abs(rightMinusLeft)) ||
+         abs(rightPlusLeft) > limits<T>::max() * abs(rightMinusLeft)) ||
         (abs(topMinusBottom) < 1 &&
-         2 > limits<T>::max() * abs(topMinusBottom)) ||
+         abs(topPlusBottom) > limits<T>::max() * abs(topMinusBottom)) ||
         (abs(farMinusNear) < 1 &&
-         2 > limits<T>::max() * abs(farMinusNear)))
+         abs(farPlusNear) > limits<T>::max() * abs(farMinusNear)))
     {
-        throw Iex::DivzeroExc ("Bad viewing frustum: "
-                   "projection matrix cannot be computed.");
-    }
-
-    T A  =  2 / rightMinusLeft;
-    T B  =  2 / topMinusBottom;
-    T C  = -2 / farMinusNear;
-
-    return Matrix44<T>( A,  0,  0,  0,
-                0,  B,  0,  0,
-                0,  0,  C,  0,
-                tx, ty, tz, 1.f );
+        throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                 "projection matrix cannot be computed.");
     }
-    else
-    {
-    T A =  rightPlusLeft / rightMinusLeft;
-    T B =  topPlusBottom / topMinusBottom;
-    T C = -farPlusNear   / farMinusNear;
 
-    T farTimesNear = -2 * _farPlane * _nearPlane;
-    if (abs(farMinusNear) < 1 &&
-        abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
+    if ( _orthographic )
     {
-        throw Iex::DivzeroExc ("Bad viewing frustum: "
-                   "projection matrix cannot be computed.");
+        T tx = -rightPlusLeft / rightMinusLeft;
+        T ty = -topPlusBottom / topMinusBottom;
+        T tz = -farPlusNear   / farMinusNear;
+
+        if ((abs(rightMinusLeft) < 1 &&
+             2 > limits<T>::max() * abs(rightMinusLeft)) ||
+            (abs(topMinusBottom) < 1 &&
+             2 > limits<T>::max() * abs(topMinusBottom)) ||
+            (abs(farMinusNear) < 1 &&
+             2 > limits<T>::max() * abs(farMinusNear)))
+        {
+            throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                         "projection matrix cannot be computed.");
+        }
+
+        T A  =  2 / rightMinusLeft;
+        T B  =  2 / topMinusBottom;
+        T C  = -2 / farMinusNear;
+
+        return Matrix44<T>( A,  0,  0,  0,
+                            0,  B,  0,  0,
+                            0,  0,  C,  0,
+                            tx, ty, tz, 1.f );
     }
-
-    T D = farTimesNear / farMinusNear;
-
-    T twoTimesNear = 2 * _nearPlane;
-
-    if ((abs(rightMinusLeft) < 1 &&
-         abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
-        (abs(topMinusBottom) < 1 &&
-         abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
+    else
     {
-        throw Iex::DivzeroExc ("Bad viewing frustum: "
-                   "projection matrix cannot be computed.");
-    }
-
-    T E = twoTimesNear / rightMinusLeft;
-    T F = twoTimesNear / topMinusBottom;
-
-    return Matrix44<T>( E,  0,  0,  0,
-                0,  F,  0,  0,
-                A,  B,  C, -1,
-                0,  0,  D,  0 );
+        T A =  rightPlusLeft / rightMinusLeft;
+        T B =  topPlusBottom / topMinusBottom;
+        T C = -farPlusNear   / farMinusNear;
+
+        T farTimesNear = -2 * _farPlane * _nearPlane;
+        if (abs(farMinusNear) < 1 &&
+            abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                         "projection matrix cannot be computed.");
+        }
+
+        T D = farTimesNear / farMinusNear;
+
+        T twoTimesNear = 2 * _nearPlane;
+
+        if ((abs(rightMinusLeft) < 1 &&
+             abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
+            (abs(topMinusBottom) < 1 &&
+             abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
+        {
+            throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
+                                                         "projection matrix cannot be computed.");
+        }
+
+        T E = twoTimesNear / rightMinusLeft;
+        T F = twoTimesNear / topMinusBottom;
+
+        return Matrix44<T>( E,  0,  0,  0,
+                            0,  F,  0,  0,
+                            A,  B,  C, -1,
+                            0,  0,  D,  0 );
     }
 }
 
@@ -462,7 +464,7 @@ template<class T>
 Vec2<T> Frustum<T>::screenToLocal(const Vec2<T> &s) const
 {
     return Vec2<T>( _left + (_right-_left) * (1.f+s.x) / 2.f,
-            _bottom + (_top-_bottom) * (1.f+s.y) / 2.f );
+                    _bottom + (_top-_bottom) * (1.f+s.y) / 2.f );
 }
 
 template<class T>
@@ -474,17 +476,17 @@ Vec2<T> Frustum<T>::localToScreen(const Vec2<T> &p) const
     T bottomMinusTop = _bottom-_top;
 
     if ((abs(leftMinusRight) < T (1) &&
-     abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
-    (abs(bottomMinusTop) < T (1) &&
-     abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
+         abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
+        (abs(bottomMinusTop) < T (1) &&
+         abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
     {
-    throw Iex::DivzeroExc
-        ("Bad viewing frustum: "
-         "local-to-screen transformation cannot be computed");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad viewing frustum: "
+             "local-to-screen transformation cannot be computed");
     }
 
     return Vec2<T>( leftPlusRight / leftMinusRight,
-            bottomPlusTop / bottomMinusTop );
+                    bottomPlusTop / bottomMinusTop );
 }
 
 template<class T>
@@ -492,20 +494,20 @@ Line3<T> Frustum<T>::projectScreenToRay(const Vec2<T> &p) const
 {
     Vec2<T> point = screenToLocal(p);
     if (orthographic())
-    return Line3<T>( Vec3<T>(point.x,point.y, 0.0),
-             Vec3<T>(point.x,point.y,-_nearPlane));
+        return Line3<T>( Vec3<T>(point.x,point.y, 0.0),
+                         Vec3<T>(point.x,point.y,-1.0));
     else
-    return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_nearPlane));
+        return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_nearPlane));
 }
 
 template<class T>
 Vec2<T> Frustum<T>::projectPointToScreen(const Vec3<T> &point) const
 {
     if (orthographic() || point.z == T (0))
-    return localToScreen( Vec2<T>( point.x, point.y ) );
+        return localToScreen( Vec2<T>( point.x, point.y ) );
     else
-    return localToScreen( Vec2<T>( point.x * _nearPlane / -point.z,
-                       point.y * _nearPlane / -point.z ) );
+        return localToScreen( Vec2<T>( point.x * _nearPlane / -point.z,
+                                       point.y * _nearPlane / -point.z ) );
 }
 
 template<class T>
@@ -515,8 +517,8 @@ T Frustum<T>::ZToDepth(long zval,long zmin,long zmax) const
 
     if (zdiff == 0)
     {
-    throw Iex::DivzeroExc
-        ("Bad call to Frustum::ZToDepth: zmax == zmin");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad call to Frustum::ZToDepth: zmax == zmin");
     }
 
     if ( zval > zmax+1 ) zval -= zdiff;
@@ -534,21 +536,21 @@ T Frustum<T>::normalizedZToDepth(T zval) const
     {
         return   -(Zp*(_farPlane-_nearPlane) + (_farPlane+_nearPlane))/2;
     }
-    else
-    {
-    T farTimesNear = 2 * _farPlane * _nearPlane;
-    T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
-
-    if (abs(farMinusNear) < 1 &&
-        abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
+    else 
     {
-        throw Iex::DivzeroExc
-        ("Frustum::normalizedZToDepth cannot be computed.  The "
-         "near and far clipping planes of the viewing frustum "
-         "may be too close to each other");
-    }
-
-    return farTimesNear / farMinusNear;
+        T farTimesNear = 2 * _farPlane * _nearPlane;
+        T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
+
+        if (abs(farMinusNear) < 1 &&
+            abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Frustum::normalizedZToDepth cannot be computed.  The "
+                 "near and far clipping planes of the viewing frustum "
+                 "may be too close to each other");
+        }
+
+        return farTimesNear / farMinusNear;
     }
 }
 
@@ -560,43 +562,43 @@ long Frustum<T>::DepthToZ(T depth,long zmin,long zmax) const
 
     if ( _orthographic )
     {
-    T farPlusNear = 2*depth + _farPlane + _nearPlane;
-
-    if (abs(farMinusNear) < 1 &&
-        abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
-    {
-        throw Iex::DivzeroExc
-        ("Bad viewing frustum: near and far clipping planes "
-         "are too close to each other");
-    }
-
-    T Zp = -farPlusNear/farMinusNear;
-    return long(0.5*(Zp+1)*zdiff) + zmin;
-    }
-    else
-    {
-    // Perspective
-
-    T farTimesNear = 2*_farPlane*_nearPlane;
-    if (abs(depth) < 1 &&
-        abs(farTimesNear) > limits<T>::max() * abs(depth))
-    {
-        throw Iex::DivzeroExc
-        ("Bad call to DepthToZ function: value of `depth' "
-         "is too small");
+        T farPlusNear = 2*depth + _farPlane + _nearPlane;
+
+        if (abs(farMinusNear) < 1 &&
+            abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Bad viewing frustum: near and far clipping planes "
+                 "are too close to each other");
+        }
+
+        T Zp = -farPlusNear/farMinusNear;
+        return long(0.5*(Zp+1)*zdiff) + zmin;
     }
-
-    T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane;
-    if (abs(farMinusNear) < 1 &&
-        abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
-    {
-        throw Iex::DivzeroExc
-        ("Bad viewing frustum: near and far clipping planes "
-         "are too close to each other");
-    }
-
-    T Zp = farPlusNear/farMinusNear;
-    return long(0.5*(Zp+1)*zdiff) + zmin;
+    else 
+    { 
+        // Perspective
+
+        T farTimesNear = 2*_farPlane*_nearPlane;
+        if (abs(depth) < 1 &&
+            abs(farTimesNear) > limits<T>::max() * abs(depth))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Bad call to DepthToZ function: value of `depth' "
+                 "is too small");
+        }
+
+        T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane;
+        if (abs(farMinusNear) < 1 &&
+            abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
+        {
+            throw IEX_NAMESPACE::DivzeroExc
+                ("Bad viewing frustum: near and far clipping planes "
+                 "are too close to each other");
+        }
+
+        T Zp = farPlusNear/farMinusNear;
+        return long(0.5*(Zp+1)*zdiff) + zmin;
     }
 }
 
@@ -615,13 +617,13 @@ T Frustum<T>::screenRadius(const Vec3<T> &p, T radius) const
 
     if (abs(p.z) > 1 || abs(-_nearPlane) < limits<T>::max() * abs(p.z))
     {
-    return radius * (-_nearPlane / p.z);
+        return radius * (-_nearPlane / p.z);
     }
     else
     {
-    throw Iex::DivzeroExc
-        ("Bad call to Frustum::screenRadius: the magnitude of `p' "
-         "is too small");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad call to Frustum::screenRadius: the magnitude of `p' "
+             "is too small");
     }
 
     return radius * (-_nearPlane / p.z);
@@ -632,21 +634,21 @@ T Frustum<T>::worldRadius(const Vec3<T> &p, T radius) const
 {
     if (abs(-_nearPlane) > 1 || abs(p.z) < limits<T>::max() * abs(-_nearPlane))
     {
-    return radius * (p.z / -_nearPlane);
+        return radius * (p.z / -_nearPlane);
     }
     else
     {
-    throw Iex::DivzeroExc
-        ("Bad viewing frustum: the near clipping plane is too "
-         "close to zero");
+        throw IEX_NAMESPACE::DivzeroExc
+            ("Bad viewing frustum: the near clipping plane is too "
+             "close to zero");
     }
 }
 
 template<class T>
-void Frustum<T>::planes(Plane3<T> p[6])
+void Frustum<T>::planes(Plane3<T> p[6]) const
 {
     //
-    // Plane order: Top, Right, Bottom, Left, Near, Far.
+    //        Plane order: Top, Right, Bottom, Left, Near, Far.
     //  Normals point outwards.
     //
 
@@ -676,10 +678,10 @@ void Frustum<T>::planes(Plane3<T> p[6])
 
 
 template<class T>
-void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M)
+void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M) const
 {
     //
-    // Plane order: Top, Right, Bottom, Left, Near, Far.
+    //  Plane order: Top, Right, Bottom, Left, Near, Far.
     //  Normals point outwards.
     //
 
@@ -720,11 +722,11 @@ void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M)
     }
 }
 
-typedef Frustum<float> Frustumf;
+typedef Frustum<float>  Frustumf;
 typedef Frustum<double> Frustumd;
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
 
 #if defined _WIN32 || defined _WIN64
@@ -736,4 +738,4 @@ typedef Frustum<double> Frustumd;
     #endif
 #endif
 
-#endif
+#endif // INCLUDED_IMATHFRUSTUM_H
index 7ac3406..d9c10cc 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2011, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2011-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 //-------------------------------------------------------------------------
 //
-//      This file contains algorithms applied to or in conjunction with
-//     Frustum visibility testing (Imath::Frustum).
+//  This file contains algorithms applied to or in conjunction with
+//  Frustum visibility testing (Imath::Frustum).
 //
-//     Methods for frustum-based rejection of primitives are contained here.
+//  Methods for frustum-based rejection of primitives are contained here.
 //
 //-------------------------------------------------------------------------
 
@@ -50,8 +50,9 @@
 #include "ImathSphere.h"
 #include "ImathMatrix.h"
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 /////////////////////////////////////////////////////////////////
 // FrustumTest
@@ -73,7 +74,7 @@ namespace Imath {
 //
 // Given that you already have:
 //    Imath::Frustum   myFrustum
-//    IMath::Matrix44  myCameraWorldMatrix
+//    Imath::Matrix44  myCameraWorldMatrix
 //
 // First, make a frustum test object:
 //    FrustumTest myFrustumTest(myFrustum, myCameraWorldMatrix)
@@ -133,7 +134,7 @@ public:
         cameraMat.makeIdentity();
         setFrustum(frust, cameraMat);
     }
-    FrustumTest(Frustum<T> &frustum, const Matrix44<T> &cameraMat)
+    FrustumTest(const Frustum<T> &frustum, const Matrix44<T> &cameraMat)
     {
         setFrustum(frustum, cameraMat);
     }
@@ -142,7 +143,7 @@ public:
     // setFrustum()
     // This updates the frustum test with a new frustum and matrix.
     // This should usually be called just once per frame.
-    void setFrustum(Frustum<T> &frustum, const Matrix44<T> &cameraMat);
+    void setFrustum(const Frustum<T> &frustum, const Matrix44<T> &cameraMat);
 
     ////////////////////////////////////////////////////////////////////
     // isVisible()
@@ -150,18 +151,18 @@ public:
     bool isVisible(const Sphere3<T> &sphere) const;
     bool isVisible(const Box<Vec3<T> > &box) const;
     bool isVisible(const Vec3<T> &vec) const;
-
+    
     ////////////////////////////////////////////////////////////////////
     // completelyContains()
     // Check to see if shapes are entirely contained.
     bool completelyContains(const Sphere3<T> &sphere) const;
     bool completelyContains(const Box<Vec3<T> > &box) const;
-
+    
     // These next items are kept primarily for debugging tools.
     // It's useful for drawing the culling environment, and also
     // for getting an "outside view" of the culling frustum.
-    Imath::Matrix44<T> cameraMat() const {return cameraMatrix;}
-    Imath::Frustum<T> currentFrustum() const {return currFrustum;}
+    IMATH_INTERNAL_NAMESPACE::Matrix44<T> cameraMat() const {return cameraMatrix;}
+    IMATH_INTERNAL_NAMESPACE::Frustum<T> currentFrustum() const {return currFrustum;}
 
 protected:
     // To understand why the planes are stored this way, see
@@ -188,7 +189,7 @@ protected:
 // This should usually only be called once per frame, or however
 // often the camera moves.
 template<class T>
-void FrustumTest<T>::setFrustum(Frustum<T> &frustum,
+void FrustumTest<T>::setFrustum(const Frustum<T> &frustum,
                                 const Matrix44<T> &cameraMat)
 {
     Plane3<T> frustumPlanes[6];
@@ -201,7 +202,7 @@ void FrustumTest<T>::setFrustum(Frustum<T> &frustum,
         int index = i * 3;
 
         planeNormX[i]     = Vec3<T>(frustumPlanes[index + 0].normal.x,
-                                    frustumPlanes[index + 1].normal.x,
+                                    frustumPlanes[index + 1].normal.x, 
                                     frustumPlanes[index + 2].normal.x);
         planeNormY[i]     = Vec3<T>(frustumPlanes[index + 0].normal.y,
                                     frustumPlanes[index + 1].normal.y,
@@ -210,15 +211,15 @@ void FrustumTest<T>::setFrustum(Frustum<T> &frustum,
                                     frustumPlanes[index + 1].normal.z,
                                     frustumPlanes[index + 2].normal.z);
 
-        planeNormAbsX[i]  = Vec3<T>(Imath::abs(planeNormX[i].x),
-                                    Imath::abs(planeNormX[i].y),
-                                    Imath::abs(planeNormX[i].z));
-        planeNormAbsY[i]  = Vec3<T>(Imath::abs(planeNormY[i].x),
-                                    Imath::abs(planeNormY[i].y),
-                                    Imath::abs(planeNormY[i].z));
-        planeNormAbsZ[i]  = Vec3<T>(Imath::abs(planeNormZ[i].x),
-                                    Imath::abs(planeNormZ[i].y),
-                                    Imath::abs(planeNormZ[i].z));
+        planeNormAbsX[i]  = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].x),
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].y), 
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].z));
+        planeNormAbsY[i]  = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].x), 
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].y),
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].z));
+        planeNormAbsZ[i]  = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].x), 
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].y),
+                                    IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].z));
 
         planeOffsetVec[i] = Vec3<T>(frustumPlanes[index + 0].distance,
                                     frustumPlanes[index + 1].distance,
@@ -242,18 +243,18 @@ bool FrustumTest<T>::isVisible(const Sphere3<T> &sphere) const
     Vec3<T> radiusVec = Vec3<T>(sphere.radius, sphere.radius, sphere.radius);
 
     // This is a vertical dot-product on three vectors at once.
-    Vec3<T> d0  = planeNormX[0] * center.x
-                + planeNormY[0] * center.y
-                + planeNormZ[0] * center.z
+    Vec3<T> d0  = planeNormX[0] * center.x 
+                + planeNormY[0] * center.y 
+                + planeNormZ[0] * center.z 
                 - radiusVec
                 - planeOffsetVec[0];
 
     if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
         return false;
 
-    Vec3<T> d1  = planeNormX[1] * center.x
-                + planeNormY[1] * center.y
-                + planeNormZ[1] * center.z
+    Vec3<T> d1  = planeNormX[1] * center.x 
+                + planeNormY[1] * center.y 
+                + planeNormZ[1] * center.z 
                 - radiusVec
                 - planeOffsetVec[1];
 
@@ -276,18 +277,18 @@ bool FrustumTest<T>::completelyContains(const Sphere3<T> &sphere) const
     Vec3<T> radiusVec = Vec3<T>(sphere.radius, sphere.radius, sphere.radius);
 
     // This is a vertical dot-product on three vectors at once.
-    Vec3<T> d0  = planeNormX[0] * center.x
-                + planeNormY[0] * center.y
-                + planeNormZ[0] * center.z
+    Vec3<T> d0  = planeNormX[0] * center.x 
+                + planeNormY[0] * center.y 
+                + planeNormZ[0] * center.z 
                 + radiusVec
                 - planeOffsetVec[0];
 
     if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
         return false;
 
-    Vec3<T> d1  = planeNormX[1] * center.x
-                + planeNormY[1] * center.y
-                + planeNormZ[1] * center.z
+    Vec3<T> d1  = planeNormX[1] * center.x 
+                + planeNormY[1] * center.y 
+                + planeNormZ[1] * center.z 
                 + radiusVec
                 - planeOffsetVec[1];
 
@@ -306,27 +307,30 @@ bool FrustumTest<T>::completelyContains(const Sphere3<T> &sphere) const
 template<typename T>
 bool FrustumTest<T>::isVisible(const Box<Vec3<T> > &box) const
 {
+    if (box.isEmpty())
+        return false;
+    
     Vec3<T> center = (box.min + box.max) / 2;
     Vec3<T> extent = (box.max - center);
 
     // This is a vertical dot-product on three vectors at once.
-    Vec3<T> d0  = planeNormX[0] * center.x
-                + planeNormY[0] * center.y
+    Vec3<T> d0  = planeNormX[0] * center.x 
+                + planeNormY[0] * center.y 
                 + planeNormZ[0] * center.z
-                - planeNormAbsX[0] * extent.x
-                - planeNormAbsY[0] * extent.y
-                - planeNormAbsZ[0] * extent.z
+                - planeNormAbsX[0] * extent.x 
+                - planeNormAbsY[0] * extent.y 
+                - planeNormAbsZ[0] * extent.z 
                 - planeOffsetVec[0];
 
     if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
         return false;
 
-    Vec3<T> d1  = planeNormX[1] * center.x
-                + planeNormY[1] * center.y
+    Vec3<T> d1  = planeNormX[1] * center.x 
+                + planeNormY[1] * center.y 
                 + planeNormZ[1] * center.z
-                - planeNormAbsX[1] * extent.x
-                - planeNormAbsY[1] * extent.y
-                - planeNormAbsZ[1] * extent.z
+                - planeNormAbsX[1] * extent.x 
+                - planeNormAbsY[1] * extent.y 
+                - planeNormAbsZ[1] * extent.z 
                 - planeOffsetVec[1];
 
     if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
@@ -344,27 +348,30 @@ bool FrustumTest<T>::isVisible(const Box<Vec3<T> > &box) const
 template<typename T>
 bool FrustumTest<T>::completelyContains(const Box<Vec3<T> > &box) const
 {
+    if (box.isEmpty())
+        return false;
+    
     Vec3<T> center = (box.min + box.max) / 2;
     Vec3<T> extent = (box.max - center);
 
     // This is a vertical dot-product on three vectors at once.
-    Vec3<T> d0  = planeNormX[0] * center.x
-                + planeNormY[0] * center.y
+    Vec3<T> d0  = planeNormX[0] * center.x 
+                + planeNormY[0] * center.y 
                 + planeNormZ[0] * center.z
-                + planeNormAbsX[0] * extent.x
-                + planeNormAbsY[0] * extent.y
-                + planeNormAbsZ[0] * extent.z
+                + planeNormAbsX[0] * extent.x 
+                + planeNormAbsY[0] * extent.y 
+                + planeNormAbsZ[0] * extent.z 
                 - planeOffsetVec[0];
 
     if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
         return false;
 
-    Vec3<T> d1  = planeNormX[1] * center.x
-                + planeNormY[1] * center.y
+    Vec3<T> d1  = planeNormX[1] * center.x 
+                + planeNormY[1] * center.y 
                 + planeNormZ[1] * center.z
-                + planeNormAbsX[1] * extent.x
-                + planeNormAbsY[1] * extent.y
-                + planeNormAbsZ[1] * extent.z
+                + planeNormAbsX[1] * extent.x 
+                + planeNormAbsY[1] * extent.y 
+                + planeNormAbsZ[1] * extent.z 
                 - planeOffsetVec[1];
 
     if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
@@ -382,17 +389,17 @@ template<typename T>
 bool FrustumTest<T>::isVisible(const Vec3<T> &vec) const
 {
     // This is a vertical dot-product on three vectors at once.
-    Vec3<T> d0  = (planeNormX[0] * vec.x)
-                + (planeNormY[0] * vec.y)
-                + (planeNormZ[0] * vec.z)
+    Vec3<T> d0  = (planeNormX[0] * vec.x) 
+                + (planeNormY[0] * vec.y) 
+                + (planeNormZ[0] * vec.z) 
                 - planeOffsetVec[0];
 
     if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
         return false;
 
-    Vec3<T> d1  = (planeNormX[1] * vec.x)
-                + (planeNormY[1] * vec.y)
-                + (planeNormZ[1] * vec.z)
+    Vec3<T> d1  = (planeNormX[1] * vec.x) 
+                + (planeNormY[1] * vec.y) 
+                + (planeNormZ[1] * vec.z) 
                 - planeOffsetVec[1];
 
     if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
@@ -405,6 +412,6 @@ bool FrustumTest<T>::isVisible(const Vec3<T> &vec) const
 typedef FrustumTest<float>     FrustumTestf;
 typedef FrustumTest<double> FrustumTestd;
 
-} //namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHFRUSTUMTEST_H
index e4ddf37..65cf620 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -35,7 +35,7 @@
 
 #include "ImathFun.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 
 float
@@ -124,7 +124,7 @@ succd (double d)
 
         u.i = 0x0000000000000001LL;
     }
-    else if (u.i > 0)
+    else if (u.d > 0)
     {
         // Positive double, normalized or denormalized.
         // Incrementing the largest positive double
@@ -159,7 +159,7 @@ predd (double d)
 
         u.i = 0x8000000000000001LL;
     }
-    else if (u.i > 0)
+    else if (u.d > 0)
     {
         // Positive double, normalized or denormalized.
 
@@ -178,4 +178,4 @@ predd (double d)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
index 863db75..068c682 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
+#include "ImathExport.h"
 #include "ImathLimits.h"
 #include "ImathInt64.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T>
 inline T
@@ -98,7 +100,7 @@ lerpfactor(T m, T a, T b)
     T n = m - a;
 
     if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d))
-    return n / d;
+       return n / d;
 
     return T(0);
 }
@@ -116,7 +118,7 @@ template <class T>
 inline int
 cmp (T a, T b)
 {
-    return Imath::sign (a - b);
+    return IMATH_INTERNAL_NAMESPACE::sign (a - b);
 }
 
 
@@ -124,7 +126,7 @@ template <class T>
 inline int
 cmpt (T a, T b, T t)
 {
-    return (Imath::abs (a - b) <= t)? 0 : cmp (a, b);
+    return (IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t)? 0 : cmp (a, b);
 }
 
 
@@ -132,7 +134,7 @@ template <class T>
 inline bool
 iszero (T a, T t)
 {
-    return (Imath::abs (a) <= t) ? 1 : 0;
+    return (IMATH_INTERNAL_NAMESPACE::abs (a) <= t) ? 1 : 0;
 }
 
 
@@ -140,7 +142,7 @@ template <class T1, class T2, class T3>
 inline bool
 equal (T1 a, T2 b, T3 t)
 {
-    return Imath::abs (a - b) <= t;
+    return IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t;
 }
 
 template <class T>
@@ -178,7 +180,7 @@ inline int
 divs (int x, int y)
 {
     return (x >= 0)? ((y >= 0)?  ( x / y): -( x / -y)):
-             ((y >= 0)? -(-x / y):  (-x / -y));
+                    ((y >= 0)? -(-x / y):  (-x / -y));
 }
 
 
@@ -186,7 +188,7 @@ inline int
 mods (int x, int y)
 {
     return (x >= 0)? ((y >= 0)?  ( x % y):  ( x % -y)):
-             ((y >= 0)? -(-x % y): -(-x % -y));
+                    ((y >= 0)? -(-x % y): -(-x % -y));
 }
 
 
@@ -196,13 +198,13 @@ mods (int x, int y)
 //
 //     divp(x,y) == floor (double(x) / double (y))
 //     modp(x,y) == x - y * divp(x,y)
-//
+// 
 
 inline int
 divp (int x, int y)
 {
     return (x >= 0)? ((y >= 0)?  (     x  / y): -(      x  / -y)):
-             ((y >= 0)? -((y-1-x) / y):  ((-y-1-x) / -y));
+                    ((y >= 0)? -((y-1-x) / y):  ((-y-1-x) / -y));
 }
 
 
@@ -220,7 +222,7 @@ modp (int x, int y)
 //
 // predf(f)     returns float(f-e), where e is the smallest
 //              positive number such that float(f-e) != f.
-//
+// 
 // succd(d)     returns double(d+e), where e is the smallest
 //              positive number such that double(d+e) != d.
 //
@@ -230,20 +232,20 @@ modp (int x, int y)
 // Exceptions:  If the input value is an infinity or a nan,
 //              succf(), predf(), succd(), and predd() all
 //              return the input value without changing it.
-//
+// 
 //----------------------------------------------------------
 
-float succf (float f);
-float predf (float f);
+IMATH_EXPORT float succf (float f);
+IMATH_EXPORT float predf (float f);
 
-double succd (double d);
-double predd (double d);
+IMATH_EXPORT double succd (double d);
+IMATH_EXPORT double predd (double d);
 
 //
 // Return true if the number is not a NaN or Infinity.
 //
 
-inline bool
+inline bool 
 finitef (float f)
 {
     union {float f; int i;} u;
@@ -252,7 +254,7 @@ finitef (float f)
     return (u.i & 0x7f800000) != 0x7f800000;
 }
 
-inline bool
+inline bool 
 finited (double d)
 {
     union {double d; Int64 i;} u;
@@ -262,6 +264,6 @@ finited (double d)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHFUN_H
diff --git a/3rdparty/openexr/Imath/ImathGL.h b/3rdparty/openexr/Imath/ImathGL.h
deleted file mode 100644 (file)
index 6217f50..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-///////////////////////////////////////////////////////////////////////////
-//
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
-// Digital Ltd. LLC
-//
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-// *       Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// *       Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-///////////////////////////////////////////////////////////////////////////
-
-
-#ifndef INCLUDED_IMATHGL_H
-#define INCLUDED_IMATHGL_H
-
-#include <GL/gl.h>
-
-#include "ImathVec.h"
-#include "ImathMatrix.h"
-#include "IexMathExc.h"
-#include "ImathFun.h"
-
-inline void glVertex    ( const Imath::V3f &v ) { glVertex3f(v.x,v.y,v.z);   }
-inline void glVertex    ( const Imath::V2f &v ) { glVertex2f(v.x,v.y);       }
-inline void glNormal    ( const Imath::V3f &n ) { glNormal3f(n.x,n.y,n.z);   }
-inline void glColor     ( const Imath::V3f &c ) { glColor3f(c.x,c.y,c.z);    }
-inline void glTranslate ( const Imath::V3f &t ) { glTranslatef(t.x,t.y,t.z); }
-
-inline void glTexCoord( const Imath::V2f &t )
-{
-    glTexCoord2f(t.x,t.y);
-}
-
-inline void glDisableTexture()
-{
-    glActiveTexture(GL_TEXTURE1);
-    glBindTexture(GL_TEXTURE_2D, 0);
-    glDisable(GL_TEXTURE_2D);
-
-    glActiveTexture(GL_TEXTURE0);
-}
-
-namespace {
-
-const float GL_FLOAT_MAX = 1.8e+19; // sqrt (FLT_MAX)
-
-inline bool
-badFloat (float f)
-{
-    return !Imath::finitef (f) || f < - GL_FLOAT_MAX || f > GL_FLOAT_MAX;
-}
-
-} // namespace
-
-inline void
-throwBadMatrix (const Imath::M44f& m)
-{
-    if (badFloat (m[0][0]) ||
-    badFloat (m[0][1]) ||
-    badFloat (m[0][2]) ||
-    badFloat (m[0][3]) ||
-    badFloat (m[1][0]) ||
-    badFloat (m[1][1]) ||
-    badFloat (m[1][2]) ||
-    badFloat (m[1][3]) ||
-    badFloat (m[2][0]) ||
-    badFloat (m[2][1]) ||
-    badFloat (m[2][2]) ||
-    badFloat (m[2][3]) ||
-    badFloat (m[3][0]) ||
-    badFloat (m[3][1]) ||
-    badFloat (m[3][2]) ||
-    badFloat (m[3][3]))
-    throw Iex::OverflowExc ("GL matrix overflow");
-}
-
-inline void
-glMultMatrix( const Imath::M44f& m )
-{
-    throwBadMatrix (m);
-    glMultMatrixf( (GLfloat*)m[0] );
-}
-
-inline void
-glMultMatrix( const Imath::M44f* m )
-{
-    throwBadMatrix (*m);
-    glMultMatrixf( (GLfloat*)(*m)[0] );
-}
-
-inline void
-glLoadMatrix( const Imath::M44f& m )
-{
-    throwBadMatrix (m);
-    glLoadMatrixf( (GLfloat*)m[0] );
-}
-
-inline void
-glLoadMatrix( const Imath::M44f* m )
-{
-    throwBadMatrix (*m);
-    glLoadMatrixf( (GLfloat*)(*m)[0] );
-}
-
-
-namespace Imath {
-
-//
-// Class objects that push/pop the GL state. These objects assist with
-// proper cleanup of the state when exceptions are thrown.
-//
-
-class GLPushMatrix {
-  public:
-
-    GLPushMatrix ()                    { glPushMatrix(); }
-    ~GLPushMatrix()                    { glPopMatrix(); }
-};
-
-class GLPushAttrib {
-  public:
-
-    GLPushAttrib (GLbitfield mask)     { glPushAttrib (mask); }
-    ~GLPushAttrib()                    { glPopAttrib(); }
-};
-
-class GLBegin {
-  public:
-
-    GLBegin (GLenum mode)              { glBegin (mode); }
-    ~GLBegin()                         { glEnd(); }
-};
-
-} // namespace Imath
-
-#endif
index a45c6f8..de54bd6 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //--------------------------------------------------
 
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
+
 #include "half.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <>
@@ -61,6 +63,6 @@ struct limits <half>
 };
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHHALFLIMITS_H
index 0719f83..00102d6 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2006-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //----------------------------------------------------------------------------
 
+#include "ImathNamespace.h"
 #include <limits.h>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 #if (defined _WIN32 || defined _WIN64) && _MSC_VER >= 1300
     typedef unsigned __int64 Int64;
+    typedef __int64 SInt64;
 #elif ULONG_MAX == 18446744073709551615LU
     typedef long unsigned int Int64;
+    typedef long int SInt64;
 #else
     typedef long long unsigned int Int64;
+    typedef long long int SInt64;
 #endif
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATH_INT64_H
index 84ef124..0062f4d 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //-------------------------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
-template <class T>
+template <class T>     
 class Interval
 {
   public:
@@ -70,14 +71,14 @@ class Interval
     // Constructors - an "empty" Interval is created by default
     //-----------------------------------------------------
 
-    Interval();
+    Interval(); 
     Interval(const T& point);
     Interval(const T& minT, const T& maxT);
 
     //--------------------------------
     //  Operators:  we get != from STL
     //--------------------------------
-
+    
     bool                        operator == (const Interval<T> &src) const;
 
     //------------------
@@ -161,10 +162,10 @@ inline void
 Interval<T>::extendBy(const T& point)
 {
     if ( point < min )
-    min = point;
-
+       min = point;
+    
     if ( point > max )
-    max = point;
+       max = point;
 }
 
 template <class T>
@@ -172,10 +173,10 @@ inline void
 Interval<T>::extendBy(const Interval<T>& interval)
 {
     if ( interval.min < min )
-    min = interval.min;
+       min = interval.min;
 
     if ( interval.max > max )
-    max = interval.max;
+       max = interval.max;
 }
 
 template <class T>
@@ -192,17 +193,17 @@ Interval<T>::intersects(const Interval<T>& interval) const
     return interval.max >= min && interval.min <= max;
 }
 
-template <class T>
+template <class T> 
 inline T
-Interval<T>::size() const
-{
+Interval<T>::size() const 
+{ 
     return max-min;
 }
 
-template <class T>
+template <class T> 
 inline T
-Interval<T>::center() const
-{
+Interval<T>::center() const 
+{ 
     return (max+min)/2;
 }
 
@@ -219,6 +220,7 @@ inline bool Interval<T>::hasVolume() const
     return max > min;
 }
 
-} // namespace Imath
 
-#endif
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
+
+#endif // INCLUDED_IMATHINTERVAL_H
index 544578a..eb6f999 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,6 +43,7 @@
 //
 //----------------------------------------------------------------
 
+#include "ImathNamespace.h"
 #include <float.h>
 #include <limits.h>
 
@@ -59,7 +60,7 @@
     #endif
 #endif
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-----------------------------------------------------------------
@@ -262,6 +263,6 @@ struct limits <long double>
 };
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHLIMITS_H
index 92d941d..61e4508 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -46,8 +46,9 @@
 #include "ImathVec.h"
 #include "ImathLimits.h"
 #include "ImathMatrix.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -57,7 +58,7 @@ class Line3
 
     Vec3<T>                    pos;
     Vec3<T>                    dir;
-
+    
     //-------------------------------------------------------------
     // Constructors - default is normalized units along direction
     //-------------------------------------------------------------
@@ -69,8 +70,8 @@ class Line3
     // State Query/Set
     //------------------
 
-    void                       set(const Vec3<T>& point1,
-                    const Vec3<T>& point2);
+    void                       set(const Vec3<T>& point1, 
+                                   const Vec3<T>& point2);
 
     //-------
     // F(t)
@@ -140,7 +141,7 @@ inline T Line3<T>::distanceTo(const Line3<T>& line) const
 }
 
 template <class T>
-inline Vec3<T>
+inline Vec3<T> 
 Line3<T>::closestPointTo(const Line3<T>& line) const
 {
     // Assumes the lines are normalized
@@ -157,10 +158,10 @@ Line3<T>::closestPointTo(const Line3<T>& line) const
 
     if (absDenom < 1)
     {
-    T absNum = ((num >= 0)? num: -num);
+       T absNum = ((num >= 0)? num: -num);
 
-    if (absNum >= absDenom * limits<T>::max())
-        return pos;
+       if (absNum >= absDenom * limits<T>::max())
+           return pos;
     }
 
     return pos + dir * (num / denom);
@@ -179,6 +180,6 @@ inline Line3<S> operator * (const Line3<S> &line, const Matrix44<T> &M)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHLINE_H
index 62bd6f5..b08a1ff 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -74,8 +74,9 @@
 #include "ImathLine.h"
 #include "ImathVecAlgo.h"
 #include "ImathFun.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -104,16 +105,16 @@ closestPoints
     T absD = abs (d);
 
     if ((absD > 1) ||
-    (abs (n1) < limits<T>::max() * absD &&
-     abs (n2) < limits<T>::max() * absD))
+       (abs (n1) < limits<T>::max() * absD &&
+        abs (n2) < limits<T>::max() * absD))
     {
-    point1 = line1 (n1 / d);
-    point2 = line2 (n2 / d);
-    return true;
+       point1 = line1 (n1 / d);
+       point2 = line2 (n2 / d);
+       return true;
     }
     else
     {
-    return false;
+       return false;
     }
 }
 
@@ -160,9 +161,9 @@ intersect
     T l = normal.length();
 
     if (l != 0)
-    normal /= l;
+       normal /= l;
     else
-    return false;      // zero-area triangle
+       return false;   // zero-area triangle
 
     //
     // d is the distance of line.pos from the plane that contains the triangle.
@@ -173,9 +174,9 @@ intersect
     T nd = normal ^ line.dir;
 
     if (abs (nd) > 1 || abs (d) < limits<T>::max() * abs (nd))
-    pt = line (d / nd);
+       pt = line (d / nd);
     else
-    return false;  // line and plane are nearly parallel
+       return false;  // line and plane are nearly parallel
 
     //
     // Compute the barycentric coordinates of the intersection point.
@@ -184,39 +185,39 @@ intersect
     //
 
     {
-    Vec3<T> en = edge0.normalized();
-    Vec3<T> a = pt - v0;
-    Vec3<T> b = v2 - v0;
-    Vec3<T> c = (a - en * (en ^ a));
-    Vec3<T> d = (b - en * (en ^ b));
-    T e = c ^ d;
-    T f = d ^ d;
-
-    if (e >= 0 && e <= f)
-        barycentric.z = e / f;
-    else
-        return false; // outside
+       Vec3<T> en = edge0.normalized();
+       Vec3<T> a = pt - v0;
+       Vec3<T> b = v2 - v0;
+       Vec3<T> c = (a - en * (en ^ a));
+       Vec3<T> d = (b - en * (en ^ b));
+       T e = c ^ d;
+       T f = d ^ d;
+
+       if (e >= 0 && e <= f)
+           barycentric.z = e / f;
+       else
+           return false; // outside
     }
 
     {
-    Vec3<T> en = edge1.normalized();
-    Vec3<T> a = pt - v1;
-    Vec3<T> b = v0 - v1;
-    Vec3<T> c = (a - en * (en ^ a));
-    Vec3<T> d = (b - en * (en ^ b));
-    T e = c ^ d;
-    T f = d ^ d;
-
-    if (e >= 0 && e <= f)
-        barycentric.x = e / f;
-    else
-        return false; // outside
+       Vec3<T> en = edge1.normalized();
+       Vec3<T> a = pt - v1;
+       Vec3<T> b = v0 - v1;
+       Vec3<T> c = (a - en * (en ^ a));
+       Vec3<T> d = (b - en * (en ^ b));
+       T e = c ^ d;
+       T f = d ^ d;
+
+       if (e >= 0 && e <= f)
+           barycentric.x = e / f;
+       else
+           return false; // outside
     }
 
     barycentric.y = 1 - barycentric.x - barycentric.z;
 
     if (barycentric.y < 0)
-    return false; // outside
+       return false; // outside
 
     front = ((line.dir ^ normal) < 0);
     return true;
@@ -233,7 +234,7 @@ closestVertex
 {
     Vec3<T> nearest = v0;
     T neardot       = (v0 - l.closestPointTo(v0)).length2();
-
+    
     T tmp           = (v1 - l.closestPointTo(v1)).length2();
 
     if (tmp < neardot)
@@ -276,12 +277,12 @@ rotatePoint (const Vec3<T> p, Line3<T> l, T angle)
     T cosangle = Math<T>::cos(angle);
     T sinangle = Math<T>::sin(angle);
 
-    Vec3<T> r = q + x * radius * cosangle + y * radius * sinangle;
+    Vec3<T> r = q + x * radius * cosangle + y * radius * sinangle; 
 
     return r;
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHLINEALGO_H
index ae2503d..1961d5a 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "ImathPlatform.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 #include <math.h>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
 struct Math
 {
-   static T    acos  (T x)             {return ::acos (double(x));}
+   static T    acos  (T x)             {return ::acos (double(x));}    
    static T    asin  (T x)             {return ::asin (double(x));}
    static T    atan  (T x)             {return ::atan (double(x));}
    static T    atan2 (T x, T y)        {return ::atan2 (double(x), double(y));}
@@ -107,8 +108,8 @@ struct Math
    {
         double ival;
         T rval( ::modf (double(x),&ival));
-    *iptr = ival;
-    return rval;
+       *iptr = ival;
+       return rval;
    }
    static T    pow   (T x, T y)        {return ::pow (double(x), double(y));}
    static T    sqrt  (T x)             {return ::sqrt (double(x));}
@@ -123,7 +124,7 @@ struct Math
 template <>
 struct Math<float>
 {
-   static float        acos  (float x)                 {return ::acosf (x);}
+   static float        acos  (float x)                 {return ::acosf (x);}   
    static float        asin  (float x)                 {return ::asinf (x);}
    static float        atan  (float x)                 {return ::atanf (x);}
    static float        atan2 (float x, float y)        {return ::atan2f (x, y);}
@@ -161,9 +162,9 @@ inline T
 sinx_over_x (T x)
 {
     if (x * x < limits<T>::epsilon())
-    return T (1);
+       return T (1);
     else
-    return Math<T>::sin (x) / x;
+       return Math<T>::sin (x) / x;
 }
 
 
@@ -174,14 +175,14 @@ sinx_over_x (T x)
 //
 //     Returns true if x1 is the same as x2 with an absolute error of
 //     no more than e,
-//
+//     
 //     abs (x1 - x2) <= e
 //
 // equalWithRelError (x1, x2, e)
 //
 //     Returns true if x1 is the same as x2 with an relative error of
 //     no more than e,
-//
+//     
 //     abs (x1 - x2) <= e * x1
 //
 //--------------------------------------------------------------------------
@@ -202,7 +203,6 @@ equalWithRelError (T x1, T x2, T e)
 }
 
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHMATH_H
index f1bf2cd..5729c73 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -48,6 +48,7 @@
 #include "ImathExc.h"
 #include "ImathVec.h"
 #include "ImathShear.h"
+#include "ImathNamespace.h"
 
 #include <cstring>
 #include <iostream>
@@ -60,7 +61,7 @@
 #endif
 
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 enum Uninitialized {UNINITIALIZED};
 
@@ -121,7 +122,7 @@ template <class T> class Matrix33
     //----------------------
     // Compatibility with Sb
     //----------------------
-
+    
     T *                 getValue ();
     const T *           getValue () const;
 
@@ -258,20 +259,16 @@ template <class T> class Matrix33
     // inverse() and invert() are significantly faster than
     // gjInverse() and gjInvert(), but the results may be slightly
     // less accurate.
-    //
+    // 
     //------------------------------------------------------------
 
-    const Matrix33 &    invert (bool singExc = false)
-                        throw (Iex::MathExc);
+    const Matrix33 &    invert (bool singExc = false);
 
-    Matrix33<T>         inverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+    Matrix33<T>         inverse (bool singExc = false) const;
 
-    const Matrix33 &    gjInvert (bool singExc = false)
-                        throw (Iex::MathExc);
+    const Matrix33 &    gjInvert (bool singExc = false);
 
-    Matrix33<T>         gjInverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+    Matrix33<T>         gjInverse (bool singExc = false) const;
 
 
     //------------------------------------------------
@@ -284,7 +281,7 @@ template <class T> class Matrix33
     // Build a minor using the specified rows and columns
     //---------------------------------------------------
 
-    T                   fastMinor (const int r0, const int r1,
+    T                   fastMinor (const int r0, const int r1, 
                                    const int c0, const int c1) const;
 
     //------------
@@ -492,7 +489,7 @@ template <class T> class Matrix44
     //----------------------
     // Compatibility with Sb
     //----------------------
-
+    
     T *                 getValue ();
     const T *           getValue () const;
 
@@ -632,20 +629,16 @@ template <class T> class Matrix44
     // inverse() and invert() are significantly faster than
     // gjInverse() and gjInvert(), but the results may be slightly
     // less accurate.
-    //
+    // 
     //------------------------------------------------------------
 
-    const Matrix44 &    invert (bool singExc = false)
-                        throw (Iex::MathExc);
+    const Matrix44 &    invert (bool singExc = false);
 
-    Matrix44<T>         inverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+    Matrix44<T>         inverse (bool singExc = false) const;
 
-    const Matrix44 &    gjInvert (bool singExc = false)
-                        throw (Iex::MathExc);
+    const Matrix44 &    gjInvert (bool singExc = false);
 
-    Matrix44<T>         gjInverse (bool singExc = false) const
-                        throw (Iex::MathExc);
+    Matrix44<T>         gjInverse (bool singExc = false) const;
 
 
     //------------------------------------------------
@@ -752,7 +745,7 @@ template <class T> class Matrix44
     // Set matrix to shear by given factors.  The resulting matrix
     //    will shear x for each y coord. by a factor of h.xy ;
     //    will shear x for each z coord. by a factor of h.xz ;
-    //    will shear y for each z coord. by a factor of h.yz ;
+    //    will shear y for each z coord. by a factor of h.yz ; 
     //    will shear y for each x coord. by a factor of h.yx ;
     //    will shear z for each x coord. by a factor of h.zx ;
     //    will shear z for each y coord. by a factor of h.zy .
@@ -763,7 +756,7 @@ template <class T> class Matrix44
 
 
     //--------------------------------------------------------
-    // Shear the matrix by given vector.  The composed matrix
+    // Shear the matrix by given vector.  The composed matrix 
     // will be <shear> * <this>, where the shear matrix ...
     //    will shear x for each y coord. by a factor of h[0] ;
     //    will shear x for each z coord. by a factor of h[1] ;
@@ -782,7 +775,7 @@ template <class T> class Matrix44
 
 
     //------------------------------------------------------------
-    // Shear the matrix by the given factors.  The composed matrix
+    // Shear the matrix by the given factors.  The composed matrix 
     // will be <shear> * <this>, where the shear matrix ...
     //    will shear x for each y coord. by a factor of h.xy ;
     //    will shear x for each z coord. by a factor of h.xz ;
@@ -829,10 +822,10 @@ template <class T> class Matrix44
 //--------------
 
 template <class T>
-std::ostream &  operator << (std::ostream & s, const Matrix33<T> &m);
+std::ostream &  operator << (std::ostream & s, const Matrix33<T> &m); 
 
 template <class T>
-std::ostream &  operator << (std::ostream & s, const Matrix44<T> &m);
+std::ostream &  operator << (std::ostream & s, const Matrix44<T> &m); 
 
 
 //---------------------------------------------
@@ -918,7 +911,7 @@ Matrix33<T>::Matrix33 (T a)
 
 template <class T>
 inline
-Matrix33<T>::Matrix33 (const T a[3][3])
+Matrix33<T>::Matrix33 (const T a[3][3]) 
 {
     memcpy (x, a, sizeof (x));
 }
@@ -1118,7 +1111,7 @@ Matrix33<T>::equalWithAbsError (const Matrix33<T> &m, T e) const
 {
     for (int i = 0; i < 3; i++)
         for (int j = 0; j < 3; j++)
-            if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -1130,7 +1123,7 @@ Matrix33<T>::equalWithRelError (const Matrix33<T> &m, T e) const
 {
     for (int i = 0; i < 3; i++)
         for (int j = 0; j < 3; j++)
-            if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -1166,7 +1159,7 @@ Matrix33<T>::operator += (T a)
     x[2][0] += a;
     x[2][1] += a;
     x[2][2] += a;
-
+  
     return *this;
 }
 
@@ -1198,7 +1191,7 @@ Matrix33<T>::operator -= (const Matrix33<T> &v)
     x[2][0] -= v.x[2][0];
     x[2][1] -= v.x[2][1];
     x[2][2] -= v.x[2][2];
-
+  
     return *this;
 }
 
@@ -1215,7 +1208,7 @@ Matrix33<T>::operator -= (T a)
     x[2][0] -= a;
     x[2][1] -= a;
     x[2][2] -= a;
-
+  
     return *this;
 }
 
@@ -1279,7 +1272,7 @@ Matrix33<T>::operator *= (T a)
     x[2][0] *= a;
     x[2][1] *= a;
     x[2][2] *= a;
-
+  
     return *this;
 }
 
@@ -1376,7 +1369,7 @@ Matrix33<T>::operator /= (T a)
     x[2][0] /= a;
     x[2][1] /= a;
     x[2][2] /= a;
-
+  
     return *this;
 }
 
@@ -1429,7 +1422,7 @@ Matrix33<T>::transposed () const
 
 template <class T>
 const Matrix33<T> &
-Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc)
+Matrix33<T>::gjInvert (bool singExc)
 {
     *this = gjInverse (singExc);
     return *this;
@@ -1437,7 +1430,7 @@ Matrix33<T>::gjInvert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix33<T>
-Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
+Matrix33<T>::gjInverse (bool singExc) const
 {
     int i, j, k;
     Matrix33 s;
@@ -1471,7 +1464,7 @@ Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if (pivotsize == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix33();
         }
@@ -1513,7 +1506,7 @@ Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if ((f = t[i][i]) == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix33();
         }
@@ -1541,7 +1534,7 @@ Matrix33<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
 
 template <class T>
 const Matrix33<T> &
-Matrix33<T>::invert (bool singExc) throw (Iex::MathExc)
+Matrix33<T>::invert (bool singExc)
 {
     *this = inverse (singExc);
     return *this;
@@ -1549,7 +1542,7 @@ Matrix33<T>::invert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix33<T>
-Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
+Matrix33<T>::inverse (bool singExc) const
 {
     if (x[0][2] != 0 || x[1][2] != 0 || x[2][2] != 1)
     {
@@ -1567,7 +1560,7 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
 
         T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
 
-        if (Imath::abs (r) >= 1)
+        if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
         {
             for (int i = 0; i < 3; ++i)
             {
@@ -1579,13 +1572,13 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
         }
         else
         {
-            T mr = Imath::abs (r) / limits<T>::smallest();
+            T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / limits<T>::smallest();
 
             for (int i = 0; i < 3; ++i)
             {
                 for (int j = 0; j < 3; ++j)
                 {
-                    if (mr > Imath::abs (s[i][j]))
+                    if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
                     {
                         s[i][j] /= r;
                     }
@@ -1606,7 +1599,7 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
     {
         Matrix33 s ( x[1][1],
                     -x[0][1],
-                     0,
+                     0, 
 
                     -x[1][0],
                      x[0][0],
@@ -1618,7 +1611,7 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
 
         T r = x[0][0] * x[1][1] - x[1][0] * x[0][1];
 
-        if (Imath::abs (r) >= 1)
+        if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
         {
             for (int i = 0; i < 2; ++i)
             {
@@ -1630,13 +1623,13 @@ Matrix33<T>::inverse (bool singExc) const throw (Iex::MathExc)
         }
         else
         {
-            T mr = Imath::abs (r) / limits<T>::smallest();
+            T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / limits<T>::smallest();
 
             for (int i = 0; i < 2; ++i)
             {
                 for (int j = 0; j < 2; ++j)
                 {
-                    if (mr > Imath::abs (s[i][j]))
+                    if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
                     {
                         s[i][j] /= r;
                     }
@@ -1783,7 +1776,7 @@ Matrix33<T>::setTranslation (const Vec2<S> &t)
 }
 
 template <class T>
-inline Vec2<T>
+inline Vec2<T> 
 Matrix33<T>::translation () const
 {
     return Vec2<T> (x[2][0], x[2][1]);
@@ -1847,10 +1840,10 @@ const Matrix33<T> &
 Matrix33<T>::shear (const S &xy)
 {
     //
-    // In this case, we don't need a temp. copy of the matrix
-    // because we never use a value on the RHS after we've
+    // In this case, we don't need a temp. copy of the matrix 
+    // because we never use a value on the RHS after we've 
     // changed it on the LHS.
-    //
+    // 
 
     x[1][0] += xy * x[0][0];
     x[1][1] += xy * x[0][1];
@@ -1865,11 +1858,11 @@ const Matrix33<T> &
 Matrix33<T>::shear (const Vec2<S> &h)
 {
     Matrix33<T> P (*this);
-
+    
     x[0][0] = P[0][0] + h[1] * P[1][0];
     x[0][1] = P[0][1] + h[1] * P[1][1];
     x[0][2] = P[0][2] + h[1] * P[1][2];
-
+    
     x[1][0] = P[1][0] + h[0] * P[0][0];
     x[1][1] = P[1][1] + h[0] * P[0][1];
     x[1][2] = P[1][2] + h[0] * P[0][2];
@@ -1931,7 +1924,7 @@ Matrix44<T>::Matrix44 (T a)
 
 template <class T>
 inline
-Matrix44<T>::Matrix44 (const T a[4][4])
+Matrix44<T>::Matrix44 (const T a[4][4]) 
 {
     memcpy (x, a, sizeof (x));
 }
@@ -2242,7 +2235,7 @@ Matrix44<T>::equalWithAbsError (const Matrix44<T> &m, T e) const
 {
     for (int i = 0; i < 4; i++)
         for (int j = 0; j < 4; j++)
-            if (!Imath::equalWithAbsError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -2254,7 +2247,7 @@ Matrix44<T>::equalWithRelError (const Matrix44<T> &m, T e) const
 {
     for (int i = 0; i < 4; i++)
         for (int j = 0; j < 4; j++)
-            if (!Imath::equalWithRelError ((*this)[i][j], m[i][j], e))
+            if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i][j], m[i][j], e))
                 return false;
 
     return true;
@@ -2526,11 +2519,11 @@ Matrix44<T>::multiply (const Matrix44<T> &a,
                        const Matrix44<T> &b,
                        Matrix44<T> &c)
 {
-    register const T * IMATH_RESTRICT ap = &a.x[0][0];
-    register const T * IMATH_RESTRICT bp = &b.x[0][0];
-    register       T * IMATH_RESTRICT cp = &c.x[0][0];
+    const T * IMATH_RESTRICT ap = &a.x[0][0];
+    const T * IMATH_RESTRICT bp = &b.x[0][0];
+          T * IMATH_RESTRICT cp = &c.x[0][0];
 
-    register T a0, a1, a2, a3;
+    T a0, a1, a2, a3;
 
     a0 = ap[0];
     a1 = ap[1];
@@ -2698,7 +2691,7 @@ Matrix44<T>::transposed () const
 
 template <class T>
 const Matrix44<T> &
-Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc)
+Matrix44<T>::gjInvert (bool singExc)
 {
     *this = gjInverse (singExc);
     return *this;
@@ -2706,7 +2699,7 @@ Matrix44<T>::gjInvert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix44<T>
-Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
+Matrix44<T>::gjInverse (bool singExc) const
 {
     int i, j, k;
     Matrix44 s;
@@ -2740,7 +2733,7 @@ Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if (pivotsize == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix44();
         }
@@ -2782,7 +2775,7 @@ Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
         if ((f = t[i][i]) == 0)
         {
             if (singExc)
-                throw ::Imath::SingMatrixExc ("Cannot invert singular matrix.");
+                throw ::IMATH_INTERNAL_NAMESPACE::SingMatrixExc ("Cannot invert singular matrix.");
 
             return Matrix44();
         }
@@ -2810,7 +2803,7 @@ Matrix44<T>::gjInverse (bool singExc) const throw (Iex::MathExc)
 
 template <class T>
 const Matrix44<T> &
-Matrix44<T>::invert (bool singExc) throw (Iex::MathExc)
+Matrix44<T>::invert (bool singExc)
 {
     *this = inverse (singExc);
     return *this;
@@ -2818,7 +2811,7 @@ Matrix44<T>::invert (bool singExc) throw (Iex::MathExc)
 
 template <class T>
 Matrix44<T>
-Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
+Matrix44<T>::inverse (bool singExc) const
 {
     if (x[0][3] != 0 || x[1][3] != 0 || x[2][3] != 0 || x[3][3] != 1)
         return gjInverse(singExc);
@@ -2845,7 +2838,7 @@ Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
 
     T r = x[0][0] * s[0][0] + x[0][1] * s[1][0] + x[0][2] * s[2][0];
 
-    if (Imath::abs (r) >= 1)
+    if (IMATH_INTERNAL_NAMESPACE::abs (r) >= 1)
     {
         for (int i = 0; i < 3; ++i)
         {
@@ -2857,13 +2850,13 @@ Matrix44<T>::inverse (bool singExc) const throw (Iex::MathExc)
     }
     else
     {
-        T mr = Imath::abs (r) / limits<T>::smallest();
+        T mr = IMATH_INTERNAL_NAMESPACE::abs (r) / limits<T>::smallest();
 
         for (int i = 0; i < 3; ++i)
         {
             for (int j = 0; j < 3; ++j)
             {
-                if (mr > Imath::abs (s[i][j]))
+                if (mr > IMATH_INTERNAL_NAMESPACE::abs (s[i][j]))
                 {
                     s[i][j] /= r;
                 }
@@ -2933,25 +2926,25 @@ const Matrix44<T> &
 Matrix44<T>::setEulerAngles (const Vec3<S>& r)
 {
     S cos_rz, sin_rz, cos_ry, sin_ry, cos_rx, sin_rx;
-
+    
     cos_rz = Math<T>::cos (r[2]);
     cos_ry = Math<T>::cos (r[1]);
     cos_rx = Math<T>::cos (r[0]);
-
+    
     sin_rz = Math<T>::sin (r[2]);
     sin_ry = Math<T>::sin (r[1]);
     sin_rx = Math<T>::sin (r[0]);
-
+    
     x[0][0] =  cos_rz * cos_ry;
     x[0][1] =  sin_rz * cos_ry;
     x[0][2] = -sin_ry;
     x[0][3] =  0;
-
+    
     x[1][0] = -sin_rz * cos_rx + cos_rz * sin_ry * sin_rx;
     x[1][1] =  cos_rz * cos_rx + sin_rz * sin_ry * sin_rx;
     x[1][2] =  cos_ry * sin_rx;
     x[1][3] =  0;
-
+    
     x[2][0] =  sin_rz * sin_rx + cos_rz * sin_ry * cos_rx;
     x[2][1] = -cos_rz * sin_rx + sin_rz * sin_ry * cos_rx;
     x[2][2] =  cos_ry * cos_rx;
@@ -3010,7 +3003,7 @@ Matrix44<T>::rotate (const Vec3<S> &r)
     cos_rz = Math<S>::cos (r[2]);
     cos_ry = Math<S>::cos (r[1]);
     cos_rx = Math<S>::cos (r[0]);
-
+    
     sin_rz = Math<S>::sin (r[2]);
     sin_ry = Math<S>::sin (r[1]);
     sin_rx = Math<S>::sin (r[0]);
@@ -3205,10 +3198,10 @@ const Matrix44<T> &
 Matrix44<T>::shear (const Vec3<S> &h)
 {
     //
-    // In this case, we don't need a temp. copy of the matrix
-    // because we never use a value on the RHS after we've
+    // In this case, we don't need a temp. copy of the matrix 
+    // because we never use a value on the RHS after we've 
     // changed it on the LHS.
-    //
+    // 
 
     for (int i=0; i < 4; i++)
     {
@@ -3251,13 +3244,13 @@ operator << (std::ostream &s, const Matrix33<T> &m)
     if (s.flags() & std::ios_base::fixed)
     {
         s.setf (std::ios_base::showpoint);
-        width = s.precision() + 5;
+        width = static_cast<int>(s.precision()) + 5;
     }
     else
     {
         s.setf (std::ios_base::scientific);
         s.setf (std::ios_base::showpoint);
-        width = s.precision() + 8;
+        width = static_cast<int>(s.precision()) + 8;
     }
 
     s << "(" << std::setw (width) << m[0][0] <<
@@ -3286,13 +3279,13 @@ operator << (std::ostream &s, const Matrix44<T> &m)
     if (s.flags() & std::ios_base::fixed)
     {
         s.setf (std::ios_base::showpoint);
-        width = s.precision() + 5;
+        width = static_cast<int>(s.precision()) + 5;
     }
     else
     {
         s.setf (std::ios_base::scientific);
         s.setf (std::ios_base::showpoint);
-        width = s.precision() + 8;
+        width = static_cast<int>(s.precision()) + 8;
     }
 
     s << "(" << std::setw (width) << m[0][0] <<
@@ -3435,8 +3428,6 @@ operator * (const Vec4<S> &v, const Matrix44<T> &m)
     return Vec4<S> (x, y, z, w);
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-
-
-#endif
+#endif // INCLUDED_IMATHMATRIX_H
index 7ddc649..0cafd5c 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -44,7 +44,7 @@
 
 #include "ImathMatrixAlgo.h"
 #include <cmath>
-#include <algorithm> // for std::max()
+#include <algorithm>
 
 #if defined(OPENEXR_DLL)
     #define EXPORT_CONST __declspec(dllexport)
     #define EXPORT_CONST const
 #endif
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 EXPORT_CONST M33f identity33f ( 1, 0, 0,
-                0, 1, 0,
-                0, 0, 1);
+                               0, 1, 0,
+                               0, 0, 1);
 
 EXPORT_CONST M33d identity33d ( 1, 0, 0,
-                0, 1, 0,
-                0, 0, 1);
+                               0, 1, 0,
+                               0, 0, 1);
 
 EXPORT_CONST M44f identity44f ( 1, 0, 0, 0,
-                0, 1, 0, 0,
-                0, 0, 1, 0,
-                0, 0, 0, 1);
+                               0, 1, 0, 0,
+                               0, 0, 1, 0,
+                               0, 0, 0, 1);
 
 EXPORT_CONST M44d identity44d ( 1, 0, 0, 0,
-                0, 1, 0, 0,
-                0, 0, 1, 0,
-                0, 0, 0, 1);
+                               0, 1, 0, 0,
+                               0, 0, 1, 0,
+                               0, 0, 0, 1);
 
 namespace
 {
@@ -166,7 +166,7 @@ procrustesRotationAndTranslation (const Vec3<T>* A, const Vec3<T>* B, const T* w
 
     M33d U, V;
     V3d S;
-    jacobiSVD (C, U, S, V, Imath::limits<double>::epsilon(), true);
+    jacobiSVD (C, U, S, V, IMATH_INTERNAL_NAMESPACE::limits<double>::epsilon(), true);
 
     // We want Q.transposed() here since we are going to be using it in the
     // Imath style (multiplying vectors on the right, v' = v*A^T):
@@ -176,10 +176,10 @@ procrustesRotationAndTranslation (const Vec3<T>* A, const Vec3<T>* B, const T* w
     if (doScale && numPoints > 1)
     {
         // Finding a uniform scale: let us assume the Q is completely fixed
-        // at this point (solving for both simultaneously seems much harder).
+        // at this point (solving for both simultaneously seems much harder).  
         // We are trying to compute (again, per Golub and van Loan)
         //    min || s*A*Q - B ||_F
-        // Notice that we've jammed a uniform scale in front of the Q.
+        // Notice that we've jammed a uniform scale in front of the Q.  
         // Now, the Frobenius norm (the least squares norm over matrices)
         // has the neat property that it is equivalent to minimizing the trace
         // of M^T*M (see your friendly neighborhood linear algebra text for a
@@ -232,7 +232,7 @@ procrustesRotationAndTranslation (const Vec3<T>* A, const Vec3<T>* B, const T* w
     //   [ 0 1 0 tb ] [  s*Q  0 ] [ 0 1 0 -ta ] = [ 0 1 0 tb ] [  s*Q  -s*Q*ta ] = [   Q   tb-s*Q*ta ]
     //   [ 0 0 1  | ] [       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    1      ]
-    // (ofc the whole thing is transposed for Imath).
+    // (ofc the whole thing is transposed for Imath).  
     const V3d translate = Bcenter - s*Acenter*Qt;
 
     return M44d (s*Qt.x[0][0], s*Qt.x[0][1], s*Qt.x[0][2], T(0),
@@ -249,10 +249,10 @@ procrustesRotationAndTranslation (const Vec3<T>* A, const Vec3<T>* B, const size
 } // procrustesRotationAndTranslation
 
 
-template M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const size_t numPoints, const bool doScale);
-template M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const size_t numPoints, const bool doScale);
-template M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const double* weights, const size_t numPoints, const bool doScale);
-template M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const float* weights, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3d* from, const V3d* to, const double* weights, const size_t numPoints, const bool doScale);
+template IMATH_EXPORT M44d procrustesRotationAndTranslation (const V3f* from, const V3f* to, const float* weights, const size_t numPoints, const bool doScale);
 
 
 namespace
@@ -266,10 +266,10 @@ namespace
 //   J * A
 // for the Jacobi rotation J and the matrix A.  This is efficient because we
 // only need to touch exactly the 2 columns that are affected, so we never
-// need to explicitly construct the J matrix.
+// need to explicitly construct the J matrix.  
 template <typename T, int j, int k>
 void
-jacobiRotateRight (Imath::Matrix33<T>& A,
+jacobiRotateRight (IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
                    const T c,
                    const T s)
 {
@@ -284,7 +284,7 @@ jacobiRotateRight (Imath::Matrix33<T>& A,
 
 template <typename T>
 void
-jacobiRotateRight (Imath::Matrix44<T>& A,
+jacobiRotateRight (IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
                    const int j,
                    const int k,
                    const T c,
@@ -313,12 +313,12 @@ jacobiRotateRight (Imath::Matrix44<T>& A,
 //    'Computation of the Singular Value Decomposition using Mesh-Connected Processors'
 //    by Richard P. Brent, Franklin T. Luk, and Charles Van Loan
 // It breaks the computation into two steps: the first symmetrizes the matrix,
-// and the second diagonalizes the symmetric matrix.
+// and the second diagonalizes the symmetric matrix.  
 template <typename T, int j, int k, int l>
 bool
-twoSidedJacobiRotation (Imath::Matrix33<T>& A,
-                        Imath::Matrix33<T>& U,
-                        Imath::Matrix33<T>& V,
+twoSidedJacobiRotation (IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
+                        IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+                        IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
                         const T tol)
 {
     // Load everything into local variables to make things easier on the
@@ -403,7 +403,7 @@ twoSidedJacobiRotation (Imath::Matrix33<T>& A,
     const T d_2 = s_1*(w*s_2 + x*c_2) + c_1*(y*s_2 + z*c_2);
 
     // For the entries we just zeroed out, we'll just set them to 0, since
-    // they should be 0 up to machine precision.
+    // they should be 0 up to machine precision.  
     A[j][j] = d_1;
     A[k][k] = d_2;
     A[k][j] = 0;
@@ -416,7 +416,7 @@ twoSidedJacobiRotation (Imath::Matrix33<T>& A,
         //    [ -s1 c1 0 ]    or  [   0 1  0 ]    or  [ 0  c1 s1 ]
         //    [   0  0 1 ]        [ -s1 0 c1 ]        [ 0 -s1 c1 ]
         // This has the effect of adding the (weighted) ith and jth _rows_ to
-        // each other.
+        // each other.  
         const T tau1 = A[j][l];
         const T tau2 = A[k][l];
         A[j][l] = c_1 * tau1 - s_1 * tau2;
@@ -429,7 +429,7 @@ twoSidedJacobiRotation (Imath::Matrix33<T>& A,
         //    [ -s2 c2 0 ]  or  [   0 1  0 ]  or  [ 0  c2 s2 ]
         //    [   0  0 1 ]      [ -s2 0 c2 ]      [ 0 -s2 c2 ]
         // This has the effect of adding the (weighted) ith and jth _columns_ to
-        // each other.
+        // each other.  
         const T tau1 = A[l][j];
         const T tau2 = A[l][k];
         A[l][j] = c_2 * tau1 - s_2 * tau2;
@@ -437,7 +437,7 @@ twoSidedJacobiRotation (Imath::Matrix33<T>& A,
     }
 
     // Now apply the rotations to U and V:
-    // Remember that we have
+    // Remember that we have 
     //    R1^T * A * R2 = D
     // This is in the 2x2 case, but after doing a bunch of these
     // we will get something like this for the 3x3 case:
@@ -455,11 +455,11 @@ twoSidedJacobiRotation (Imath::Matrix33<T>& A,
 
 template <typename T>
 bool
-twoSidedJacobiRotation (Imath::Matrix44<T>& A,
+twoSidedJacobiRotation (IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
                         int j,
                         int k,
-                        Imath::Matrix44<T>& U,
-                        Imath::Matrix44<T>& V,
+                        IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+                        IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
                         const T tol)
 {
     // Load everything into local variables to make things easier on the
@@ -544,7 +544,7 @@ twoSidedJacobiRotation (Imath::Matrix44<T>& A,
     const T d_2 = s_1*(w*s_2 + x*c_2) + c_1*(y*s_2 + z*c_2);
 
     // For the entries we just zeroed out, we'll just set them to 0, since
-    // they should be 0 up to machine precision.
+    // they should be 0 up to machine precision.  
     A[j][j] = d_1;
     A[k][k] = d_2;
     A[k][j] = 0;
@@ -567,7 +567,7 @@ twoSidedJacobiRotation (Imath::Matrix44<T>& A,
         //          j    k
         //
         // This has the effect of adding the (weighted) ith and jth _rows_ to
-        // each other.
+        // each other.  
         const T tau1 = A[j][l];
         const T tau2 = A[k][l];
         A[j][l] = c_1 * tau1 - s_1 * tau2;
@@ -591,7 +591,7 @@ twoSidedJacobiRotation (Imath::Matrix44<T>& A,
         //          j    k
         //
         // This has the effect of adding the (weighted) ith and jth _columns_ to
-        // each other.
+        // each other.  
         const T tau1 = A[l][j];
         const T tau2 = A[l][k];
         A[l][j] = c_2 * tau1 - s_2 * tau2;
@@ -599,7 +599,7 @@ twoSidedJacobiRotation (Imath::Matrix44<T>& A,
     }
 
     // Now apply the rotations to U and V:
-    // Remember that we have
+    // Remember that we have 
     //    R1^T * A * R2 = D
     // This is in the 2x2 case, but after doing a bunch of these
     // we will get something like this for the 3x3 case:
@@ -617,7 +617,7 @@ twoSidedJacobiRotation (Imath::Matrix44<T>& A,
 
 template <typename T>
 void
-swapColumns (Imath::Matrix33<T>& A, int j, int k)
+swapColumns (IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A, int j, int k)
 {
     for (int i = 0; i < 3; ++i)
         std::swap (A[i][j], A[i][k]);
@@ -625,7 +625,7 @@ swapColumns (Imath::Matrix33<T>& A, int j, int k)
 
 template <typename T>
 T
-maxOffDiag (const Imath::Matrix33<T>& A)
+maxOffDiag (const IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A)
 {
     T result = 0;
     result = std::max (result, std::abs (A[0][1]));
@@ -639,7 +639,7 @@ maxOffDiag (const Imath::Matrix33<T>& A)
 
 template <typename T>
 T
-maxOffDiag (const Imath::Matrix44<T>& A)
+maxOffDiag (const IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A)
 {
     T result = 0;
     for (int i = 0; i < 4; ++i)
@@ -656,10 +656,10 @@ maxOffDiag (const Imath::Matrix44<T>& A)
 
 template <typename T>
 void
-twoSidedJacobiSVD (Imath::Matrix33<T> A,
-                   Imath::Matrix33<T>& U,
-                   Imath::Vec3<T>& S,
-                   Imath::Matrix33<T>& V,
+twoSidedJacobiSVD (IMATH_INTERNAL_NAMESPACE::Matrix33<T> A,
+                   IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+                   IMATH_INTERNAL_NAMESPACE::Vec3<T>& S,
+                   IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
                    const T tol,
                    const bool forcePositiveDeterminant)
 {
@@ -680,7 +680,7 @@ twoSidedJacobiSVD (Imath::Matrix33<T> A,
     //  [-s1 c1  ] [  * *] [-s2 c2  ] = [* * *]
     //  [       1] [* * *] [       1]   [  * *]
     // However, if we keep doing this, we'll find that the off-diagonal entries
-    // converge to 0 fairly quickly (convergence should be roughly cubic).  The
+    // converge to 0 fairly quickly (convergence should be roughly cubic).  The 
     // result is a diagonal A matrix and a bunch of orthogonal transforms:
     //               [* * *]                [*    ]
     //  L1 L2 ... Ln [* * *] Rn ... R2 R1 = [  *  ]
@@ -691,7 +691,7 @@ twoSidedJacobiSVD (Imath::Matrix33<T> A,
     // are extremely stable to compute and apply (this is why QR factorization
     // works so well, FWIW) and because (2) by applying everything to the original
     // matrix A instead of computing (A^T * A) we avoid any precision loss that
-    // would result from that.
+    // would result from that.  
     U.makeIdentity();
     V.makeIdentity();
 
@@ -770,7 +770,7 @@ twoSidedJacobiSVD (Imath::Matrix33<T> A,
                 U[i][2] = -U[i][2];
             S.z = -S.z;
         }
-
+   
         if (V.determinant() < 0)
         {
             for (int i = 0; i < 3; ++i)
@@ -782,10 +782,10 @@ twoSidedJacobiSVD (Imath::Matrix33<T> A,
 
 template <typename T>
 void
-twoSidedJacobiSVD (Imath::Matrix44<T> A,
-                   Imath::Matrix44<T>& U,
-                   Imath::Vec4<T>& S,
-                   Imath::Matrix44<T>& V,
+twoSidedJacobiSVD (IMATH_INTERNAL_NAMESPACE::Matrix44<T> A,
+                   IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+                   IMATH_INTERNAL_NAMESPACE::Vec4<T>& S,
+                   IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
                    const T tol,
                    const bool forcePositiveDeterminant)
 {
@@ -837,8 +837,8 @@ twoSidedJacobiSVD (Imath::Matrix44<T> A,
     // Order the singular values from largest to smallest using insertion sort:
     for (int i = 1; i < 4; ++i)
     {
-        const Imath::Vec4<T> uCol (U[0][i], U[1][i], U[2][i], U[3][i]);
-        const Imath::Vec4<T> vCol (V[0][i], V[1][i], V[2][i], V[3][i]);
+        const IMATH_INTERNAL_NAMESPACE::Vec4<T> uCol (U[0][i], U[1][i], U[2][i], U[3][i]);
+        const IMATH_INTERNAL_NAMESPACE::Vec4<T> vCol (V[0][i], V[1][i], V[2][i], V[3][i]);
         const T sVal = S[i];
 
         int j = i - 1;
@@ -882,7 +882,7 @@ twoSidedJacobiSVD (Imath::Matrix44<T> A,
                 U[i][3] = -U[i][3];
             S[3] = -S[3];
         }
-
+   
         if (V.determinant() < 0)
         {
             for (int i = 0; i < 4; ++i)
@@ -896,10 +896,10 @@ twoSidedJacobiSVD (Imath::Matrix44<T> A,
 
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix33<T>& A,
-           Imath::Matrix33<T>& U,
-           Imath::Vec3<T>& S,
-           Imath::Matrix33<T>& V,
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec3<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
            const T tol,
            const bool forcePositiveDeterminant)
 {
@@ -908,46 +908,46 @@ jacobiSVD (const Imath::Matrix33<T>& A,
 
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix44<T>& A,
-           Imath::Matrix44<T>& U,
-           Imath::Vec4<T>& S,
-           Imath::Matrix44<T>& V,
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec4<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
            const T tol,
            const bool forcePositiveDeterminant)
 {
     twoSidedJacobiSVD (A, U, S, V, tol, forcePositiveDeterminant);
 }
 
-template void jacobiSVD (const Imath::Matrix33<float>& A,
-                         Imath::Matrix33<float>& U,
-                         Imath::Vec3<float>& S,
-                         Imath::Matrix33<float>& V,
-                         const float tol,
-                         const bool forcePositiveDeterminant);
-template void jacobiSVD (const Imath::Matrix33<double>& A,
-                         Imath::Matrix33<double>& U,
-                         Imath::Vec3<double>& S,
-                         Imath::Matrix33<double>& V,
-                         const double tol,
-                         const bool forcePositiveDeterminant);
-template void jacobiSVD (const Imath::Matrix44<float>& A,
-                         Imath::Matrix44<float>& U,
-                         Imath::Vec4<float>& S,
-                         Imath::Matrix44<float>& V,
-                         const float tol,
-                         const bool forcePositiveDeterminant);
-template void jacobiSVD (const Imath::Matrix44<double>& A,
-                         Imath::Matrix44<double>& U,
-                         Imath::Vec4<double>& S,
-                         Imath::Matrix44<double>& V,
-                         const double tol,
-                         const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<float>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<float>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec3<float>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<float>& V,
+                                      const float tol,
+                                      const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<double>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<double>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec3<double>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix33<double>& V,
+                                      const double tol,
+                                      const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<float>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<float>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec4<float>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<float>& V,
+                                      const float tol,
+                                      const bool forcePositiveDeterminant);
+template IMATH_EXPORT void jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<double>& A,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<double>& U,
+                                      IMATH_INTERNAL_NAMESPACE::Vec4<double>& S,
+                                      IMATH_INTERNAL_NAMESPACE::Matrix44<double>& V,
+                                      const double tol,
+                                      const bool forcePositiveDeterminant);
 
 namespace
 {
 
 template <int j, int k, typename TM>
-inline
+inline 
 void
 jacobiRotateRight (TM& A,
                    const typename TM::BaseType s,
@@ -1006,7 +1006,7 @@ jacobiRotation (Matrix33<T>& A,
     A[k][k] += h;
 
     // For the entries we just zeroed out, we'll just set them to 0, since
-    // they should be 0 up to machine precision.
+    // they should be 0 up to machine precision.  
     A[j][k] = 0;
 
     // We only update upper triagnular elements of A, since
@@ -1016,7 +1016,7 @@ jacobiRotation (Matrix33<T>& A,
     const T nu1 = offd1;
     const T nu2 = offd2;
     offd1 = nu1 - s * (nu2 + tau * nu1);
-    offd2 = nu2 + s * (nu1 - tau * nu2);
+    offd2 = nu2 + s * (nu1 - tau * nu2); 
 
     // Apply rotation to V
     jacobiRotateRight<j, k> (V, s, tau);
@@ -1039,7 +1039,7 @@ jacobiRotation (Matrix44<T>& A,
     const T mu2 = T(2) * y;
 
     // Let's see if rho^(-1) = mu2 / mu1 is less than tol
-    // This test also checks if rho^2 will overflow
+    // This test also checks if rho^2 will overflow 
     // when tol^(-1) < sqrt(limits<T>::max()).
     if (std::abs(mu2) <= tol*std::abs(mu1))
     {
@@ -1066,7 +1066,7 @@ jacobiRotation (Matrix44<T>& A,
         const T nu1 = offd1;
         const T nu2 = offd2;
         offd1 -= s * (nu2 + tau * nu1);
-        offd2 += s * (nu1 - tau * nu2);
+        offd2 += s * (nu1 - tau * nu2); 
     }
 
     {
@@ -1075,7 +1075,7 @@ jacobiRotation (Matrix44<T>& A,
         const T nu1 = offd1;
         const T nu2 = offd2;
         offd1 -= s * (nu2 + tau * nu1);
-        offd2 += s * (nu1 - tau * nu2);
+        offd2 += s * (nu1 - tau * nu2); 
     }
 
     jacobiRotateRight<j, k> (V, s, tau);
@@ -1120,8 +1120,8 @@ jacobiEigenSolver (Matrix33<T>& A,
         {
             // Z is for accumulating small changes (h) to diagonal entries
             // of A for one sweep. Adding h's directly to A might cause
-            // a cancellation effect when h is relatively very small to
-            // the corresponding diagonal entry of A and
+            // a cancellation effect when h is relatively very small to 
+            // the corresponding diagonal entry of A and 
             // this will increase numerical errors
             Vec3<T> Z(0, 0, 0);
             ++numIter;
@@ -1214,39 +1214,39 @@ minEigenVector (TM& A, TV& V)
         V[i] = MV[i][minIdx];
 }
 
-template void jacobiEigenSolver (Matrix33<float>& A,
-                                 Vec3<float>& S,
-                                 Matrix33<float>& V,
-                                 const float tol);
-template void jacobiEigenSolver (Matrix33<double>& A,
-                                 Vec3<double>& S,
-                                 Matrix33<double>& V,
-                                 const double tol);
-template void jacobiEigenSolver (Matrix44<float>& A,
-                                 Vec4<float>& S,
-                                 Matrix44<float>& V,
-                                 const float tol);
-template void jacobiEigenSolver (Matrix44<double>& A,
-                                 Vec4<double>& S,
-                                 Matrix44<double>& V,
-                                 const double tol);
-
-template void maxEigenVector (Matrix33<float>& A,
-                              Vec3<float>& S);
-template void maxEigenVector (Matrix44<float>& A,
-                              Vec4<float>& S);
-template void maxEigenVector (Matrix33<double>& A,
-                              Vec3<double>& S);
-template void maxEigenVector (Matrix44<double>& A,
-                              Vec4<double>& S);
-
-template void minEigenVector (Matrix33<float>& A,
-                              Vec3<float>& S);
-template void minEigenVector (Matrix44<float>& A,
-                              Vec4<float>& S);
-template void minEigenVector (Matrix33<double>& A,
-                              Vec3<double>& S);
-template void minEigenVector (Matrix44<double>& A,
-                              Vec4<double>& S);
-
-} // namespace Imath
+template IMATH_EXPORT void jacobiEigenSolver (Matrix33<float>& A,
+                                              Vec3<float>& S,
+                                              Matrix33<float>& V,
+                                              const float tol);
+template IMATH_EXPORT void jacobiEigenSolver (Matrix33<double>& A,
+                                              Vec3<double>& S,
+                                              Matrix33<double>& V,
+                                              const double tol);
+template IMATH_EXPORT void jacobiEigenSolver (Matrix44<float>& A,
+                                              Vec4<float>& S,
+                                              Matrix44<float>& V,
+                                              const float tol);
+template IMATH_EXPORT void jacobiEigenSolver (Matrix44<double>& A,
+                                              Vec4<double>& S,
+                                              Matrix44<double>& V,
+                                              const double tol);
+
+template IMATH_EXPORT void maxEigenVector (Matrix33<float>& A,
+                                           Vec3<float>& S);
+template IMATH_EXPORT void maxEigenVector (Matrix44<float>& A,
+                                           Vec4<float>& S);
+template IMATH_EXPORT void maxEigenVector (Matrix33<double>& A,
+                                           Vec3<double>& S);
+template IMATH_EXPORT void maxEigenVector (Matrix44<double>& A,
+                                           Vec4<double>& S);
+
+template IMATH_EXPORT void minEigenVector (Matrix33<float>& A,
+                                           Vec3<float>& S);
+template IMATH_EXPORT void minEigenVector (Matrix44<float>& A,
+                                           Vec4<float>& S);
+template IMATH_EXPORT void minEigenVector (Matrix33<double>& A,
+                                           Vec3<double>& S);
+template IMATH_EXPORT void minEigenVector (Matrix44<double>& A,
+                                           Vec4<double>& S);
+
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
index 707b77d..8e90b02 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 //-------------------------------------------------------------------------
 //
-//      This file contains algorithms applied to or in conjunction with
-//     transformation matrices (Imath::Matrix33 and Imath::Matrix44).
-//     The assumption made is that these functions are called much less
-//     often than the basic point functions or these functions require
-//     more support classes.
+//  This file contains algorithms applied to or in conjunction with
+//  transformation matrices (Imath::Matrix33 and Imath::Matrix44).
+//  The assumption made is that these functions are called much less
+//  often than the basic point functions or these functions require
+//  more support classes.
 //
-//     This file also defines a few predefined constant matrices.
+//  This file also defines a few predefined constant matrices.
 //
 //-------------------------------------------------------------------------
 
+#include "ImathExport.h"
 #include "ImathMatrix.h"
 #include "ImathQuat.h"
 #include "ImathEuler.h"
 #include "ImathExc.h"
 #include "ImathVec.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 #include <math.h>
 
-
-#ifdef OPENEXR_DLL
-    #ifdef IMATH_EXPORTS
-        #define IMATH_EXPORT_CONST extern __declspec(dllexport)
-    #else
-    #define IMATH_EXPORT_CONST extern __declspec(dllimport)
-    #endif
-#else
-    #define IMATH_EXPORT_CONST extern const
-#endif
-
-
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //------------------
 // Identity matrices
@@ -81,11 +71,11 @@ IMATH_EXPORT_CONST M44d identity44d;
 
 //----------------------------------------------------------------------
 // Extract scale, shear, rotation, and translation values from a matrix:
-//
+// 
 // Notes:
 //
 // This implementation follows the technique described in the paper by
-// Spencer W. Thomas in the Graphics Gems II article: "Decomposing a
+// Spencer W. Thomas in the Graphics Gems II article: "Decomposing a 
 // Matrix into Simple Transformations", p. 320.
 //
 // - Some of the functions below have an optional exc parameter
@@ -101,23 +91,23 @@ IMATH_EXPORT_CONST M44d identity44d;
 //     removeScaling (m)                returns false, m is unchanged
 //      sansScalingAndShear (m)          returns m
 //      removeScalingAndShear (m)        returns false, m is unchanged
-//      extractAndRemoveScalingAndShear (m, s, h)
-//                                       returns false, m is unchanged,
+//      extractAndRemoveScalingAndShear (m, s, h)  
+//                                       returns false, m is unchanged, 
 //                                                      (sh) are invalid
 //      checkForZeroScaleInRow ()        returns false
 //     extractSHRT (m, s, h, r, t)      returns false, (shrt) are invalid
 //
-// - Functions extractEuler(), extractEulerXYZ() and extractEulerZYX()
-//   assume that the matrix does not include shear or non-uniform scaling,
-//   but they do not examine the matrix to verify this assumption.
-//   Matrices with shear or non-uniform scaling are likely to produce
-//   meaningless results.  Therefore, you should use the
+// - Functions extractEuler(), extractEulerXYZ() and extractEulerZYX() 
+//   assume that the matrix does not include shear or non-uniform scaling, 
+//   but they do not examine the matrix to verify this assumption.  
+//   Matrices with shear or non-uniform scaling are likely to produce 
+//   meaningless results.  Therefore, you should use the 
 //   removeScalingAndShear() routine, if necessary, prior to calling
 //   extractEuler...() .
 //
 // - All functions assume that the matrix does not include perspective
-//   transformation(s), but they do not examine the matrix to verify
-//   this assumption.  Matrices with perspective transformations are
+//   transformation(s), but they do not examine the matrix to verify 
+//   this assumption.  Matrices with perspective transformations are 
 //   likely to produce meaningless results.
 //
 //----------------------------------------------------------------------
@@ -127,86 +117,86 @@ IMATH_EXPORT_CONST M44d identity44d;
 // Declarations for 4x4 matrix.
 //
 
-template <class T>  bool        extractScaling
+template <class T>  bool        extractScaling 
                                             (const Matrix44<T> &mat,
-                         Vec3<T> &scl,
-                         bool exc = true);
+                                            Vec3<T> &scl,
+                                            bool exc = true);
+  
+template <class T>  Matrix44<T> sansScaling (const Matrix44<T> &mat, 
+                                            bool exc = true);
 
-template <class T>  Matrix44<T> sansScaling (const Matrix44<T> &mat,
-                         bool exc = true);
-
-template <class T>  bool        removeScaling
-                                            (Matrix44<T> &mat,
-                         bool exc = true);
+template <class T>  bool        removeScaling 
+                                            (Matrix44<T> &mat, 
+                                            bool exc = true);
 
-template <class T>  bool        extractScalingAndShear
+template <class T>  bool        extractScalingAndShear 
                                             (const Matrix44<T> &mat,
-                         Vec3<T> &scl,
-                         Vec3<T> &shr,
-                         bool exc = true);
-
-template <class T>  Matrix44<T> sansScalingAndShear
-                                            (const Matrix44<T> &mat,
-                         bool exc = true);
-
-template <class T>  void        sansScalingAndShear
+                                            Vec3<T> &scl,
+                                            Vec3<T> &shr,
+                                            bool exc = true);
+  
+template <class T>  Matrix44<T> sansScalingAndShear 
+                                            (const Matrix44<T> &mat, 
+                                            bool exc = true);
+
+template <class T>  void        sansScalingAndShear 
                                             (Matrix44<T> &result,
-                                             const Matrix44<T> &mat,
-                         bool exc = true);
+                                             const Matrix44<T> &mat, 
+                                            bool exc = true);
 
-template <class T>  bool        removeScalingAndShear
+template <class T>  bool        removeScalingAndShear 
                                             (Matrix44<T> &mat,
-                         bool exc = true);
+                                            bool exc = true);
 
 template <class T>  bool        extractAndRemoveScalingAndShear
                                             (Matrix44<T> &mat,
-                         Vec3<T>     &scl,
-                         Vec3<T>     &shr,
-                         bool exc = true);
+                                            Vec3<T>     &scl,
+                                            Vec3<T>     &shr,
+                                            bool exc = true);
 
-template <class T>  void       extractEulerXYZ
+template <class T>  void       extractEulerXYZ 
                                             (const Matrix44<T> &mat,
-                         Vec3<T> &rot);
+                                            Vec3<T> &rot);
 
-template <class T>  void       extractEulerZYX
+template <class T>  void       extractEulerZYX 
                                             (const Matrix44<T> &mat,
-                         Vec3<T> &rot);
+                                            Vec3<T> &rot);
 
 template <class T>  Quat<T>    extractQuat (const Matrix44<T> &mat);
 
-template <class T>  bool       extractSHRT
+template <class T>  bool       extractSHRT 
                                     (const Matrix44<T> &mat,
-                     Vec3<T> &s,
-                     Vec3<T> &h,
-                     Vec3<T> &r,
-                     Vec3<T> &t,
-                     bool exc /*= true*/,
-                     typename Euler<T>::Order rOrder);
-
-template <class T>  bool       extractSHRT
+                                    Vec3<T> &s,
+                                    Vec3<T> &h,
+                                    Vec3<T> &r,
+                                    Vec3<T> &t,
+                                    bool exc /*= true*/,
+                                    typename Euler<T>::Order rOrder);
+
+template <class T>  bool       extractSHRT 
                                     (const Matrix44<T> &mat,
-                     Vec3<T> &s,
-                     Vec3<T> &h,
-                     Vec3<T> &r,
-                     Vec3<T> &t,
-                     bool exc = true);
+                                    Vec3<T> &s,
+                                    Vec3<T> &h,
+                                    Vec3<T> &r,
+                                    Vec3<T> &t,
+                                    bool exc = true);
 
-template <class T>  bool       extractSHRT
+template <class T>  bool       extractSHRT 
                                     (const Matrix44<T> &mat,
-                     Vec3<T> &s,
-                     Vec3<T> &h,
-                     Euler<T> &r,
-                     Vec3<T> &t,
-                     bool exc = true);
+                                    Vec3<T> &s,
+                                    Vec3<T> &h,
+                                    Euler<T> &r,
+                                    Vec3<T> &t,
+                                    bool exc = true);
 
 //
 // Internal utility function.
 //
 
 template <class T>  bool       checkForZeroScaleInRow
-                                            (const T       &scl,
-                         const Vec3<T> &row,
-                         bool exc = true);
+                                            (const T       &scl, 
+                                            const Vec3<T> &row,
+                                            bool exc = true);
 
 template <class T>  Matrix44<T> outerProduct
                                             ( const Vec4<T> &a,
@@ -219,45 +209,45 @@ template <class T>  Matrix44<T> outerProduct
 //
 
 template <class T> Matrix44<T> rotationMatrix (const Vec3<T> &fromDirection,
-                        const Vec3<T> &toDirection);
+                                               const Vec3<T> &toDirection);
 
 
 
 //
-// Returns a matrix that rotates the "fromDir" vector
-// so that it points towards "toDir".  You may also
-// specify that you want the up vector to be pointing
+// Returns a matrix that rotates the "fromDir" vector 
+// so that it points towards "toDir".  You may also 
+// specify that you want the up vector to be pointing 
 // in a certain direction "upDir".
 //
 
-template <class T> Matrix44<T> rotationMatrixWithUpDir
+template <class T> Matrix44<T> rotationMatrixWithUpDir 
                                             (const Vec3<T> &fromDir,
-                         const Vec3<T> &toDir,
-                         const Vec3<T> &upDir);
+                                            const Vec3<T> &toDir,
+                                            const Vec3<T> &upDir);
 
 
 //
-// Constructs a matrix that rotates the z-axis so that it
-// points towards "targetDir".  You must also specify
-// that you want the up vector to be pointing in a
+// Constructs a matrix that rotates the z-axis so that it 
+// points towards "targetDir".  You must also specify 
+// that you want the up vector to be pointing in a 
 // certain direction "upDir".
 //
 // Notes: The following degenerate cases are handled:
-//        (a) when the directions given by "toDir" and "upDir"
+//        (a) when the directions given by "toDir" and "upDir" 
 //            are parallel or opposite;
 //            (the direction vectors must have a non-zero cross product)
 //        (b) when any of the given direction vectors have zero length
 //
 
-template <class T> void        alignZAxisWithTargetDir
+template <class T> void        alignZAxisWithTargetDir 
                                             (Matrix44<T> &result,
-                                             Vec3<T>      targetDir,
-                         Vec3<T>      upDir);
+                                             Vec3<T>      targetDir, 
+                                            Vec3<T>      upDir);
 
 
 // Compute an orthonormal direct frame from : a position, an x axis direction and a normal to the y axis
 // If the x axis and normal are perpendicular, then the normal will have the same direction as the z axis.
-// Inputs are :
+// Inputs are : 
 //     -the position of the frame
 //     -the x axis direction of the frame
 //     -a normal to the y axis of the frame
@@ -289,7 +279,7 @@ template <class T> Matrix44<T> addOffset( const Matrix44<T>& inMat,
 //      -Matrix B
 // Return Matrix A with tweaked rotation/scale
 template <class T> Matrix44<T> computeRSMatrix( bool               keepRotateA,
-                                                bool               keepScaleA,
+                                                bool               keepScaleA, 
                                                 const Matrix44<T>& A,
                                                 const Matrix44<T>& B);
 
@@ -297,58 +287,58 @@ template <class T> Matrix44<T> computeRSMatrix( bool               keepRotateA,
 //----------------------------------------------------------------------
 
 
-//
+// 
 // Declarations for 3x3 matrix.
 //
 
-
-template <class T>  bool        extractScaling
+template <class T>  bool        extractScaling 
                                             (const Matrix33<T> &mat,
-                         Vec2<T> &scl,
-                         bool exc = true);
-
-template <class T>  Matrix33<T> sansScaling (const Matrix33<T> &mat,
-                         bool exc = true);
-
-template <class T>  bool        removeScaling
-                                            (Matrix33<T> &mat,
-                         bool exc = true);
+                                            Vec2<T> &scl,
+                                            bool exc = true);
+  
+template <class T>  Matrix33<T> sansScaling (const Matrix33<T> &mat, 
+                                            bool exc = true);
 
-template <class T>  bool        extractScalingAndShear
-                                            (const Matrix33<T> &mat,
-                         Vec2<T> &scl,
-                         T &h,
-                         bool exc = true);
+template <class T>  bool        removeScaling 
+                                            (Matrix33<T> &mat, 
+                                            bool exc = true);
 
-template <class T>  Matrix33<T> sansScalingAndShear
+template <class T>  bool        extractScalingAndShear 
                                             (const Matrix33<T> &mat,
-                         bool exc = true);
-
-template <class T>  bool        removeScalingAndShear
+                                            Vec2<T> &scl,
+                                            T &h,
+                                            bool exc = true);
+  
+template <class T>  Matrix33<T> sansScalingAndShear 
+                                            (const Matrix33<T> &mat, 
+                                            bool exc = true);
+
+template <class T>  bool        removeScalingAndShear 
                                             (Matrix33<T> &mat,
-                         bool exc = true);
+                                            bool exc = true);
 
 template <class T>  bool        extractAndRemoveScalingAndShear
                                             (Matrix33<T> &mat,
-                         Vec2<T>     &scl,
-                         T           &shr,
-                         bool exc = true);
+                                            Vec2<T>     &scl,
+                                            T           &shr,
+                                            bool exc = true);
 
 template <class T>  void       extractEuler
                                             (const Matrix33<T> &mat,
-                         T       &rot);
+                                            T       &rot);
 
 template <class T>  bool       extractSHRT (const Matrix33<T> &mat,
-                         Vec2<T> &s,
-                         T       &h,
-                         T       &r,
-                         Vec2<T> &t,
-                         bool exc = true);
+                                            Vec2<T> &s,
+                                            T       &h,
+                                            T       &r,
+                                            Vec2<T> &t,
+                                            bool exc = true);
 
 template <class T>  bool       checkForZeroScaleInRow
-                                            (const T       &scl,
-                         const Vec2<T> &row,
-                         bool exc = true);
+                                            (const T       &scl, 
+                                            const Vec2<T> &row,
+                                            bool exc = true);
 
 template <class T>  Matrix33<T> outerProduct
                                             ( const Vec3<T> &a,
@@ -368,8 +358,8 @@ extractScaling (const Matrix44<T> &mat, Vec3<T> &scl, bool exc)
     Matrix44<T> M (mat);
 
     if (! extractAndRemoveScalingAndShear (M, scl, shr, exc))
-    return false;
-
+       return false;
+    
     return true;
 }
 
@@ -384,10 +374,10 @@ sansScaling (const Matrix44<T> &mat, bool exc)
     Vec3<T> tran;
 
     if (! extractSHRT (mat, scl, shr, rot, tran, exc))
-    return mat;
+       return mat;
 
     Matrix44<T> M;
-
+    
     M.translate (tran);
     M.rotate (rot);
     M.shear (shr);
@@ -406,7 +396,7 @@ removeScaling (Matrix44<T> &mat, bool exc)
     Vec3<T> tran;
 
     if (! extractSHRT (mat, scl, shr, rot, tran, exc))
-    return false;
+       return false;
 
     mat.makeIdentity ();
     mat.translate (tran);
@@ -419,14 +409,14 @@ removeScaling (Matrix44<T> &mat, bool exc)
 
 template <class T>
 bool
-extractScalingAndShear (const Matrix44<T> &mat,
-            Vec3<T> &scl, Vec3<T> &shr, bool exc)
+extractScalingAndShear (const Matrix44<T> &mat, 
+                       Vec3<T> &scl, Vec3<T> &shr, bool exc)
 {
     Matrix44<T> M (mat);
 
     if (! extractAndRemoveScalingAndShear (M, scl, shr, exc))
-    return false;
-
+       return false;
+    
     return true;
 }
 
@@ -440,8 +430,8 @@ sansScalingAndShear (const Matrix44<T> &mat, bool exc)
     Matrix44<T> M (mat);
 
     if (! extractAndRemoveScalingAndShear (M, scl, shr, exc))
-    return mat;
-
+       return mat;
+    
     return M;
 }
 
@@ -454,7 +444,7 @@ sansScalingAndShear (Matrix44<T> &result, const Matrix44<T> &mat, bool exc)
     Vec3<T> shr;
 
     if (! extractAndRemoveScalingAndShear (result, scl, shr, exc))
-    result = mat;
+       result = mat;
 }
 
 
@@ -466,20 +456,20 @@ removeScalingAndShear (Matrix44<T> &mat, bool exc)
     Vec3<T> shr;
 
     if (! extractAndRemoveScalingAndShear (mat, scl, shr, exc))
-    return false;
-
+       return false;
+    
     return true;
 }
 
 
 template <class T>
 bool
-extractAndRemoveScalingAndShear (Matrix44<T> &mat,
-                 Vec3<T> &scl, Vec3<T> &shr, bool exc)
+extractAndRemoveScalingAndShear (Matrix44<T> &mat, 
+                                Vec3<T> &scl, Vec3<T> &shr, bool exc)
 {
     //
     // This implementation follows the technique described in the paper by
-    // Spencer W. Thomas in the Graphics Gems II article: "Decomposing a
+    // Spencer W. Thomas in the Graphics Gems II article: "Decomposing a 
     // Matrix into Simple Transformations", p. 320.
     //
 
@@ -488,34 +478,34 @@ extractAndRemoveScalingAndShear (Matrix44<T> &mat,
     row[0] = Vec3<T> (mat[0][0], mat[0][1], mat[0][2]);
     row[1] = Vec3<T> (mat[1][0], mat[1][1], mat[1][2]);
     row[2] = Vec3<T> (mat[2][0], mat[2][1], mat[2][2]);
-
+    
     T maxVal = 0;
     for (int i=0; i < 3; i++)
-    for (int j=0; j < 3; j++)
-        if (Imath::abs (row[i][j]) > maxVal)
-        maxVal = Imath::abs (row[i][j]);
+       for (int j=0; j < 3; j++)
+           if (IMATH_INTERNAL_NAMESPACE::abs (row[i][j]) > maxVal)
+               maxVal = IMATH_INTERNAL_NAMESPACE::abs (row[i][j]);
 
     //
     // We normalize the 3x3 matrix here.
     // It was noticed that this can improve numerical stability significantly,
     // especially when many of the upper 3x3 matrix's coefficients are very
-    // close to zero; we correct for this step at the end by multiplying the
-    // scaling factors by maxVal at the end (shear and rotation are not
+    // close to zero; we correct for this step at the end by multiplying the 
+    // scaling factors by maxVal at the end (shear and rotation are not 
     // affected by the normalization).
 
     if (maxVal != 0)
     {
-    for (int i=0; i < 3; i++)
-        if (! checkForZeroScaleInRow (maxVal, row[i], exc))
-        return false;
-        else
-        row[i] /= maxVal;
+       for (int i=0; i < 3; i++)
+           if (! checkForZeroScaleInRow (maxVal, row[i], exc))
+               return false;
+           else
+               row[i] /= maxVal;
     }
 
-    // Compute X scale factor.
+    // Compute X scale factor. 
     scl.x = row[0].length ();
     if (! checkForZeroScaleInRow (scl.x, row[0], exc))
-    return false;
+       return false;
 
     // Normalize first row.
     row[0] /= scl.x;
@@ -537,10 +527,10 @@ extractAndRemoveScalingAndShear (Matrix44<T> &mat,
     // Now, compute Y scale.
     scl.y = row[1].length ();
     if (! checkForZeroScaleInRow (scl.y, row[1], exc))
-    return false;
+       return false;
 
     // Normalize 2nd row and correct the XY shear factor for Y scaling.
-    row[1] /= scl.y;
+    row[1] /= scl.y; 
     shr[0] /= scl.y;
 
     // Compute XZ and YZ shears, orthogonalize 3rd row.
@@ -552,7 +542,7 @@ extractAndRemoveScalingAndShear (Matrix44<T> &mat,
     // Next, get Z scale.
     scl.z = row[2].length ();
     if (! checkForZeroScaleInRow (scl.z, row[2], exc))
-    return false;
+       return false;
 
     // Normalize 3rd row and correct the XZ and YZ shear factors for Z scaling.
     row[2] /= scl.z;
@@ -563,23 +553,23 @@ extractAndRemoveScalingAndShear (Matrix44<T> &mat,
     // Check for a coordinate system flip. If the determinant
     // is less than zero, then negate the matrix and the scaling factors.
     if (row[0].dot (row[1].cross (row[2])) < 0)
-    for (int  i=0; i < 3; i++)
-    {
-        scl[i] *= -1;
-        row[i] *= -1;
-    }
+       for (int  i=0; i < 3; i++)
+       {
+           scl[i] *= -1;
+           row[i] *= -1;
+       }
 
     // Copy over the orthonormal rows into the returned matrix.
     // The upper 3x3 matrix in mat is now a rotation matrix.
     for (int i=0; i < 3; i++)
     {
-    mat[i][0] = row[i][0];
-    mat[i][1] = row[i][1];
-    mat[i][2] = row[i][2];
+       mat[i][0] = row[i][0]; 
+       mat[i][1] = row[i][1]; 
+       mat[i][2] = row[i][2];
     }
 
-    // Correct the scaling factors for the normalization step that we
-    // performed above; shear and rotation are not affected by the
+    // Correct the scaling factors for the normalization step that we 
+    // performed above; shear and rotation are not affected by the 
     // normalization.
     scl *= maxVal;
 
@@ -603,14 +593,14 @@ extractEulerXYZ (const Matrix44<T> &mat, Vec3<T> &rot)
     j.normalize();
     k.normalize();
 
-    Matrix44<T> M (i[0], i[1], i[2], 0,
-           j[0], j[1], j[2], 0,
-           k[0], k[1], k[2], 0,
-           0,    0,    0,    1);
+    Matrix44<T> M (i[0], i[1], i[2], 0, 
+                  j[0], j[1], j[2], 0, 
+                  k[0], k[1], k[2], 0, 
+                  0,    0,    0,    1);
 
     //
     // Extract the first angle, rot.x.
-    //
+    // 
 
     rot.x = Math<T>::atan2 (M[1][2], M[2][2]);
 
@@ -650,14 +640,14 @@ extractEulerZYX (const Matrix44<T> &mat, Vec3<T> &rot)
     j.normalize();
     k.normalize();
 
-    Matrix44<T> M (i[0], i[1], i[2], 0,
-           j[0], j[1], j[2], 0,
-           k[0], k[1], k[2], 0,
-           0,    0,    0,    1);
+    Matrix44<T> M (i[0], i[1], i[2], 0, 
+                  j[0], j[1], j[2], 0, 
+                  k[0], k[1], k[2], 0, 
+                  0,    0,    0,    1);
 
     //
     // Extract the first angle, rot.x.
-    //
+    // 
 
     rot.x = -Math<T>::atan2 (M[1][0], M[0][0]);
 
@@ -704,21 +694,21 @@ extractQuat (const Matrix44<T> &mat)
      quat.v.x = (mat[1][2] - mat[2][1]) * s;
      quat.v.y = (mat[2][0] - mat[0][2]) * s;
      quat.v.z = (mat[0][1] - mat[1][0]) * s;
-  }
-  else {
+  } 
+  else {      
      // diagonal is negative
      i = 0;
-     if (mat[1][1] > mat[0][0])
+     if (mat[1][1] > mat[0][0]) 
         i=1;
-     if (mat[2][2] > mat[i][i])
+     if (mat[2][2] > mat[i][i]) 
         i=2;
-
+    
      j = nxt[i];
      k = nxt[j];
      s = Math<T>::sqrt ((mat[i][i] - (mat[j][j] + mat[k][k])) + T(1.0));
-
+      
      q[i] = s * T(0.5);
-     if (s != T(0.0))
+     if (s != T(0.0)) 
         s = T(0.5) / s;
 
      q[3] = (mat[j][k] - mat[k][j]) * s;
@@ -735,20 +725,20 @@ extractQuat (const Matrix44<T> &mat)
 }
 
 template <class T>
-bool
+bool 
 extractSHRT (const Matrix44<T> &mat,
-         Vec3<T> &s,
-         Vec3<T> &h,
-         Vec3<T> &r,
-         Vec3<T> &t,
-         bool exc /* = true */ ,
-         typename Euler<T>::Order rOrder /* = Euler<T>::XYZ */ )
+            Vec3<T> &s,
+            Vec3<T> &h,
+            Vec3<T> &r,
+            Vec3<T> &t,
+            bool exc /* = true */ ,
+            typename Euler<T>::Order rOrder /* = Euler<T>::XYZ */ )
 {
     Matrix44<T> rot;
 
     rot = mat;
     if (! extractAndRemoveScalingAndShear (rot, s, h, exc))
-    return false;
+       return false;
 
     extractEulerXYZ (rot, r);
 
@@ -758,55 +748,55 @@ extractSHRT (const Matrix44<T> &mat,
 
     if (rOrder != Euler<T>::XYZ)
     {
-    Imath::Euler<T> eXYZ (r, Imath::Euler<T>::XYZ);
-    Imath::Euler<T> e (eXYZ, rOrder);
-    r = e.toXYZVector ();
+       IMATH_INTERNAL_NAMESPACE::Euler<T> eXYZ (r, IMATH_INTERNAL_NAMESPACE::Euler<T>::XYZ);
+       IMATH_INTERNAL_NAMESPACE::Euler<T> e (eXYZ, rOrder);
+       r = e.toXYZVector ();
     }
 
     return true;
 }
 
 template <class T>
-bool
+bool 
 extractSHRT (const Matrix44<T> &mat,
-         Vec3<T> &s,
-         Vec3<T> &h,
-         Vec3<T> &r,
-         Vec3<T> &t,
-         bool exc)
+            Vec3<T> &s,
+            Vec3<T> &h,
+            Vec3<T> &r,
+            Vec3<T> &t,
+            bool exc)
 {
-    return extractSHRT(mat, s, h, r, t, exc, Imath::Euler<T>::XYZ);
+    return extractSHRT(mat, s, h, r, t, exc, IMATH_INTERNAL_NAMESPACE::Euler<T>::XYZ);
 }
 
 template <class T>
-bool
+bool 
 extractSHRT (const Matrix44<T> &mat,
-         Vec3<T> &s,
-         Vec3<T> &h,
-         Euler<T> &r,
-         Vec3<T> &t,
-         bool exc /* = true */)
+            Vec3<T> &s,
+            Vec3<T> &h,
+            Euler<T> &r,
+            Vec3<T> &t,
+            bool exc /* = true */)
 {
     return extractSHRT (mat, s, h, r, t, exc, r.order ());
 }
 
 
-template <class T>
-bool
-checkForZeroScaleInRow (const T& scl,
-            const Vec3<T> &row,
-            bool exc /* = true */ )
+template <class T> 
+bool           
+checkForZeroScaleInRow (const T& scl, 
+                       const Vec3<T> &row,
+                       bool exc /* = true */ )
 {
     for (int i = 0; i < 3; i++)
     {
-    if ((abs (scl) < 1 && abs (row[i]) >= limits<T>::max() * abs (scl)))
-    {
-        if (exc)
-        throw Imath::ZeroScaleExc ("Cannot remove zero scaling "
-                       "from matrix.");
-        else
-        return false;
-    }
+       if ((abs (scl) < 1 && abs (row[i]) >= limits<T>::max() * abs (scl)))
+       {
+           if (exc)
+               throw IMATH_INTERNAL_NAMESPACE::ZeroScaleExc ("Cannot remove zero scaling "
+                                          "from matrix.");
+           else
+               return false;
+       }
     }
 
     return true;
@@ -833,34 +823,34 @@ rotationMatrix (const Vec3<T> &from, const Vec3<T> &to)
 
 
 template <class T>
-Matrix44<T>
+Matrix44<T>    
 rotationMatrixWithUpDir (const Vec3<T> &fromDir,
-             const Vec3<T> &toDir,
-             const Vec3<T> &upDir)
+                        const Vec3<T> &toDir,
+                        const Vec3<T> &upDir)
 {
     //
-    // The goal is to obtain a rotation matrix that takes
-    // "fromDir" to "toDir".  We do this in two steps and
-    // compose the resulting rotation matrices;
+    // The goal is to obtain a rotation matrix that takes 
+    // "fromDir" to "toDir".  We do this in two steps and 
+    // compose the resulting rotation matrices; 
     //    (a) rotate "fromDir" into the z-axis
     //    (b) rotate the z-axis into "toDir"
     //
 
     // The from direction must be non-zero; but we allow zero to and up dirs.
     if (fromDir.length () == 0)
-    return Matrix44<T> ();
+       return Matrix44<T> ();
 
     else
     {
-    Matrix44<T> zAxis2FromDir( Imath::UNINITIALIZED );
-    alignZAxisWithTargetDir (zAxis2FromDir, fromDir, Vec3<T> (0, 1, 0));
+       Matrix44<T> zAxis2FromDir( IMATH_INTERNAL_NAMESPACE::UNINITIALIZED );
+       alignZAxisWithTargetDir (zAxis2FromDir, fromDir, Vec3<T> (0, 1, 0));
 
-    Matrix44<T> fromDir2zAxis  = zAxis2FromDir.transposed ();
+       Matrix44<T> fromDir2zAxis  = zAxis2FromDir.transposed ();
+       
+       Matrix44<T> zAxis2ToDir( IMATH_INTERNAL_NAMESPACE::UNINITIALIZED );
+       alignZAxisWithTargetDir (zAxis2ToDir, toDir, upDir);
 
-    Matrix44<T> zAxis2ToDir( Imath::UNINITIALIZED );
-    alignZAxisWithTargetDir (zAxis2ToDir, toDir, upDir);
-
-    return fromDir2zAxis * zAxis2ToDir;
+       return fromDir2zAxis * zAxis2ToDir;
     }
 }
 
@@ -874,61 +864,61 @@ alignZAxisWithTargetDir (Matrix44<T> &result, Vec3<T> targetDir, Vec3<T> upDir)
     //
 
     if ( targetDir.length () == 0 )
-    targetDir = Vec3<T> (0, 0, 1);
+       targetDir = Vec3<T> (0, 0, 1);
 
     //
     // Ensure that the up direction is non-zero.
     //
 
     if ( upDir.length () == 0 )
-    upDir = Vec3<T> (0, 1, 0);
+       upDir = Vec3<T> (0, 1, 0);
 
     //
-    // Check for degeneracies.  If the upDir and targetDir are parallel
+    // Check for degeneracies.  If the upDir and targetDir are parallel 
     // or opposite, then compute a new, arbitrary up direction that is
     // not parallel or opposite to the targetDir.
     //
 
     if (upDir.cross (targetDir).length () == 0)
     {
-    upDir = targetDir.cross (Vec3<T> (1, 0, 0));
-    if (upDir.length() == 0)
-        upDir = targetDir.cross(Vec3<T> (0, 0, 1));
+       upDir = targetDir.cross (Vec3<T> (1, 0, 0));
+       if (upDir.length() == 0)
+           upDir = targetDir.cross(Vec3<T> (0, 0, 1));
     }
 
     //
     // Compute the x-, y-, and z-axis vectors of the new coordinate system.
     //
 
-    Vec3<T> targetPerpDir = upDir.cross (targetDir);
+    Vec3<T> targetPerpDir = upDir.cross (targetDir);    
     Vec3<T> targetUpDir   = targetDir.cross (targetPerpDir);
-
+    
     //
     // Rotate the x-axis into targetPerpDir (row 0),
     // rotate the y-axis into targetUpDir   (row 1),
     // rotate the z-axis into targetDir     (row 2).
     //
-
+    
     Vec3<T> row[3];
     row[0] = targetPerpDir.normalized ();
     row[1] = targetUpDir  .normalized ();
     row[2] = targetDir    .normalized ();
-
+    
     result.x[0][0] = row[0][0];
     result.x[0][1] = row[0][1];
     result.x[0][2] = row[0][2];
     result.x[0][3] = (T)0;
-
     result.x[1][0] = row[1][0];
     result.x[1][1] = row[1][1];
     result.x[1][2] = row[1][2];
     result.x[1][3] = (T)0;
-
     result.x[2][0] = row[2][0];
     result.x[2][1] = row[2][1];
     result.x[2][2] = row[2][2];
     result.x[2][3] = (T)0;
-
     result.x[3][0] = (T)0;
     result.x[3][1] = (T)0;
     result.x[3][2] = (T)0;
@@ -938,7 +928,7 @@ alignZAxisWithTargetDir (Matrix44<T> &result, Vec3<T> targetDir, Vec3<T> upDir)
 
 // Compute an orthonormal direct frame from : a position, an x axis direction and a normal to the y axis
 // If the x axis and normal are perpendicular, then the normal will have the same direction as the z axis.
-// Inputs are :
+// Inputs are : 
 //     -the position of the frame
 //     -the x axis direction of the frame
 //     -a normal to the y axis of the frame
@@ -974,7 +964,7 @@ computeLocalFrame( const Vec3<T>& p,
     L[3][1] = p[1];
     L[3][2] = p[2];
     L[3][3] = 1.0;
-
+    
     return L;
 }
 
@@ -1023,13 +1013,13 @@ addOffset( const Matrix44<T>& inMat,
 template <class T>
 Matrix44<T>
 computeRSMatrix( bool               keepRotateA,
-                 bool               keepScaleA,
-                 const Matrix44<T>& A,
+                 bool               keepScaleA, 
+                 const Matrix44<T>& A, 
                  const Matrix44<T>& B)
 {
     Vec3<T> as, ah, ar, at;
     extractSHRT (A, as, ah, ar, at);
-
+    
     Vec3<T> bs, bh, br, bt;
     extractSHRT (B, bs, bh, br, bt);
 
@@ -1044,7 +1034,7 @@ computeRSMatrix( bool               keepRotateA,
     mat.translate (at);
     mat.rotate (ar);
     mat.scale (as);
-
+    
     return mat;
 }
 
@@ -1063,7 +1053,7 @@ extractScaling (const Matrix33<T> &mat, Vec2<T> &scl, bool exc)
     Matrix33<T> M (mat);
 
     if (! extractAndRemoveScalingAndShear (M, scl, shr, exc))
-    return false;
+       return false;
 
     return true;
 }
@@ -1079,10 +1069,10 @@ sansScaling (const Matrix33<T> &mat, bool exc)
     Vec2<T> tran;
 
     if (! extractSHRT (mat, scl, shr, rot, tran, exc))
-    return mat;
+       return mat;
 
     Matrix33<T> M;
-
+    
     M.translate (tran);
     M.rotate (rot);
     M.shear (shr);
@@ -1101,7 +1091,7 @@ removeScaling (Matrix33<T> &mat, bool exc)
     Vec2<T> tran;
 
     if (! extractSHRT (mat, scl, shr, rot, tran, exc))
-    return false;
+       return false;
 
     mat.makeIdentity ();
     mat.translate (tran);
@@ -1119,7 +1109,7 @@ extractScalingAndShear (const Matrix33<T> &mat, Vec2<T> &scl, T &shr, bool exc)
     Matrix33<T> M (mat);
 
     if (! extractAndRemoveScalingAndShear (M, scl, shr, exc))
-    return false;
+       return false;
 
     return true;
 }
@@ -1134,8 +1124,8 @@ sansScalingAndShear (const Matrix33<T> &mat, bool exc)
     Matrix33<T> M (mat);
 
     if (! extractAndRemoveScalingAndShear (M, scl, shr, exc))
-    return mat;
-
+       return mat;
+    
     return M;
 }
 
@@ -1148,55 +1138,55 @@ removeScalingAndShear (Matrix33<T> &mat, bool exc)
     T shr;
 
     if (! extractAndRemoveScalingAndShear (mat, scl, shr, exc))
-    return false;
-
+       return false;
+    
     return true;
 }
 
 template <class T>
 bool
-extractAndRemoveScalingAndShear (Matrix33<T> &mat,
-                 Vec2<T> &scl, T &shr, bool exc)
+extractAndRemoveScalingAndShear (Matrix33<T> &mat, 
+                                Vec2<T> &scl, T &shr, bool exc)
 {
     Vec2<T> row[2];
 
     row[0] = Vec2<T> (mat[0][0], mat[0][1]);
     row[1] = Vec2<T> (mat[1][0], mat[1][1]);
-
+    
     T maxVal = 0;
     for (int i=0; i < 2; i++)
-    for (int j=0; j < 2; j++)
-        if (Imath::abs (row[i][j]) > maxVal)
-        maxVal = Imath::abs (row[i][j]);
+       for (int j=0; j < 2; j++)
+           if (IMATH_INTERNAL_NAMESPACE::abs (row[i][j]) > maxVal)
+               maxVal = IMATH_INTERNAL_NAMESPACE::abs (row[i][j]);
 
     //
     // We normalize the 2x2 matrix here.
     // It was noticed that this can improve numerical stability significantly,
     // especially when many of the upper 2x2 matrix's coefficients are very
-    // close to zero; we correct for this step at the end by multiplying the
-    // scaling factors by maxVal at the end (shear and rotation are not
+    // close to zero; we correct for this step at the end by multiplying the 
+    // scaling factors by maxVal at the end (shear and rotation are not 
     // affected by the normalization).
 
     if (maxVal != 0)
     {
-    for (int i=0; i < 2; i++)
-        if (! checkForZeroScaleInRow (maxVal, row[i], exc))
-        return false;
-        else
-        row[i] /= maxVal;
+       for (int i=0; i < 2; i++)
+           if (! checkForZeroScaleInRow (maxVal, row[i], exc))
+               return false;
+           else
+               row[i] /= maxVal;
     }
 
-    // Compute X scale factor.
+    // Compute X scale factor. 
     scl.x = row[0].length ();
     if (! checkForZeroScaleInRow (scl.x, row[0], exc))
-    return false;
+       return false;
 
     // Normalize first row.
     row[0] /= scl.x;
 
     // An XY shear factor will shear the X coord. as the Y coord. changes.
-    // There are 2 combinations (XY, YX), although we only extract the XY
-    // shear factor because we can effect the an YX shear factor by
+    // There are 2 combinations (XY, YX), although we only extract the XY 
+    // shear factor because we can effect the an YX shear factor by 
     // shearing in XY combined with rotations and scales.
     //
     // shear matrix <   1,  YX,  0,
@@ -1210,30 +1200,30 @@ extractAndRemoveScalingAndShear (Matrix33<T> &mat,
     // Now, compute Y scale.
     scl.y = row[1].length ();
     if (! checkForZeroScaleInRow (scl.y, row[1], exc))
-    return false;
+       return false;
 
     // Normalize 2nd row and correct the XY shear factor for Y scaling.
-    row[1] /= scl.y;
+    row[1] /= scl.y; 
     shr    /= scl.y;
 
     // At this point, the upper 2x2 matrix in mat is orthonormal.
     // Check for a coordinate system flip. If the determinant
-    // is -1, then flip the rotation matrix and adjust the scale(Y)
+    // is -1, then flip the rotation matrix and adjust the scale(Y) 
     // and shear(XY) factors to compensate.
     if (row[0][0] * row[1][1] - row[0][1] * row[1][0] < 0)
     {
-    row[1][0] *= -1;
-    row[1][1] *= -1;
-    scl[1] *= -1;
-    shr *= -1;
+       row[1][0] *= -1;
+       row[1][1] *= -1;
+       scl[1] *= -1;
+       shr *= -1;
     }
 
     // Copy over the orthonormal rows into the returned matrix.
     // The upper 2x2 matrix in mat is now a rotation matrix.
     for (int i=0; i < 2; i++)
     {
-    mat[i][0] = row[i][0];
-    mat[i][1] = row[i][1];
+       mat[i][0] = row[i][0]; 
+       mat[i][1] = row[i][1]; 
     }
 
     scl *= maxVal;
@@ -1258,26 +1248,26 @@ extractEuler (const Matrix33<T> &mat, T &rot)
 
     //
     // Extract the angle, rot.
-    //
+    // 
 
     rot = - Math<T>::atan2 (j[0], i[0]);
 }
 
 
 template <class T>
-bool
+bool 
 extractSHRT (const Matrix33<T> &mat,
-         Vec2<T> &s,
-         T       &h,
-         T       &r,
-         Vec2<T> &t,
-         bool    exc)
+            Vec2<T> &s,
+            T       &h,
+            T       &r,
+            Vec2<T> &t,
+            bool    exc)
 {
     Matrix33<T> rot;
 
     rot = mat;
     if (! extractAndRemoveScalingAndShear (rot, s, h, exc))
-    return false;
+       return false;
 
     extractEuler (rot, r);
 
@@ -1288,22 +1278,22 @@ extractSHRT (const Matrix33<T> &mat,
 }
 
 
-template <class T>
-bool
-checkForZeroScaleInRow (const T& scl,
-            const Vec2<T> &row,
-            bool exc /* = true */ )
+template <class T> 
+bool           
+checkForZeroScaleInRow (const T& scl, 
+                        const Vec2<T> &row,
+                        bool exc /* = true */ )
 {
     for (int i = 0; i < 2; i++)
     {
-    if ((abs (scl) < 1 && abs (row[i]) >= limits<T>::max() * abs (scl)))
-    {
-        if (exc)
-        throw Imath::ZeroScaleExc ("Cannot remove zero scaling "
-                       "from matrix.");
-        else
-        return false;
-    }
+        if ((abs (scl) < 1 && abs (row[i]) >= limits<T>::max() * abs (scl)))
+        {
+            if (exc)
+                throw IMATH_INTERNAL_NAMESPACE::ZeroScaleExc (
+                        "Cannot remove zero scaling from matrix.");
+            else
+                return false;
+        }
     }
 
     return true;
@@ -1321,7 +1311,7 @@ outerProduct (const Vec3<T> &a, const Vec3<T> &b )
 
 
 // Computes the translation and rotation that brings the 'from' points
-// as close as possible to the 'to' points under the Frobenius norm.
+// as close as possible to the 'to' points under the Frobenius norm.  
 // To be more specific, let x be the matrix of 'from' points and y be
 // the matrix of 'to' points, we want to find the matrix A of the form
 //    [ R t ]
@@ -1330,25 +1320,25 @@ outerProduct (const Vec3<T> &a, const Vec3<T> &b )
 //     || (A*x - y)^T * W * (A*x - y) ||_F
 // If doScaling is true, then a uniform scale is allowed also.
 template <typename T>
-Imath::M44d
-procrustesRotationAndTranslation (const Imath::Vec3<T>* A,  // From these
-                                  const Imath::Vec3<T>* B,  // To these
-                                  const T* weights,
+IMATH_INTERNAL_NAMESPACE::M44d
+procrustesRotationAndTranslation (const IMATH_INTERNAL_NAMESPACE::Vec3<T>* A,  // From these
+                                  const IMATH_INTERNAL_NAMESPACE::Vec3<T>* B,  // To these
+                                  const T* weights, 
                                   const size_t numPoints,
                                   const bool doScaling = false);
 
 // Unweighted:
 template <typename T>
-Imath::M44d
-procrustesRotationAndTranslation (const Imath::Vec3<T>* A,
-                                  const Imath::Vec3<T>* B,
+IMATH_INTERNAL_NAMESPACE::M44d
+procrustesRotationAndTranslation (const IMATH_INTERNAL_NAMESPACE::Vec3<T>* A, 
+                                  const IMATH_INTERNAL_NAMESPACE::Vec3<T>* B, 
                                   const size_t numPoints,
                                   const bool doScaling = false);
 
 // Compute the SVD of a 3x3 matrix using Jacobi transformations.  This method
 // should be quite accurate (competitive with LAPACK) even for poorly
 // conditioned matrices, and because it has been written specifically for the
-// 3x3/4x4 case it is much faster than calling out to LAPACK.
+// 3x3/4x4 case it is much faster than calling out to LAPACK.  
 //
 // The SVD of a 3x3/4x4 matrix A is defined as follows:
 //     A = U * S * V^T
@@ -1357,25 +1347,25 @@ procrustesRotationAndTranslation (const Imath::Vec3<T>* A,
 // the largest to the smallest.  However, some uses of this function may
 // require that the matrix U*V^T have positive determinant; in this case, we
 // may make the smallest singular value negative to ensure that this is
-// satisfied.
+// satisfied.  
 //
 // Currently only available for single- and double-precision matrices.
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix33<T>& A,
-           Imath::Matrix33<T>& U,
-           Imath::Vec3<T>& S,
-           Imath::Matrix33<T>& V,
-           const T tol = Imath::limits<T>::epsilon(),
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix33<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec3<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix33<T>& V,
+           const T tol = IMATH_INTERNAL_NAMESPACE::limits<T>::epsilon(),
            const bool forcePositiveDeterminant = false);
 
 template <typename T>
 void
-jacobiSVD (const Imath::Matrix44<T>& A,
-           Imath::Matrix44<T>& U,
-           Imath::Vec4<T>& S,
-           Imath::Matrix44<T>& V,
-           const T tol = Imath::limits<T>::epsilon(),
+jacobiSVD (const IMATH_INTERNAL_NAMESPACE::Matrix44<T>& A,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& U,
+           IMATH_INTERNAL_NAMESPACE::Vec4<T>& S,
+           IMATH_INTERNAL_NAMESPACE::Matrix44<T>& V,
+           const T tol = IMATH_INTERNAL_NAMESPACE::limits<T>::epsilon(),
            const bool forcePositiveDeterminant = false);
 
 // Compute the eigenvalues (S) and the eigenvectors (V) of
@@ -1385,7 +1375,7 @@ jacobiSVD (const Imath::Matrix44<T>& A,
 //     A = V * S * V^T
 // where V is orthonormal and S is the diagonal matrix of eigenvalues.
 // Input matrix A must be symmetric. A is also modified during
-// the computation so that upper diagonal entries of A become zero.
+// the computation so that upper diagonal entries of A become zero. 
 //
 template <typename T>
 void
@@ -1430,6 +1420,6 @@ template <typename TM, typename TV>
 void
 minEigenVector (TM& A, TV& S);
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHMATRIXALGO_H
diff --git a/3rdparty/openexr/Imath/ImathNamespace.h b/3rdparty/openexr/Imath/ImathNamespace.h
new file mode 100644 (file)
index 0000000..c1fb993
--- /dev/null
@@ -0,0 +1,115 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+#ifndef INCLUDED_IMATHNAMESPACE_H
+#define INCLUDED_IMATHNAMESPACE_H
+
+//
+// The purpose of this file is to make it possible to specify an
+// IMATH_INTERNAL_NAMESPACE as a preprocessor definition and have all of the
+// Imath symbols defined within that namespace rather than the standard
+// Imath namespace.  Those symbols are made available to client code through
+// the IMATH_NAMESPACE in addition to the IMATH_INTERNAL_NAMESPACE.
+//
+// To ensure source code compatibility, the IMATH_NAMESPACE defaults to Imath
+// and then "using namespace IMATH_INTERNAL_NAMESPACE;" brings all of the
+// declarations from the IMATH_INTERNAL_NAMESPACE into the IMATH_NAMESPACE.
+// This means that client code can continue to use syntax like Imath::V3f,
+// but at link time it will resolve to a mangled symbol based on the
+// IMATH_INTERNAL_NAMESPACE.
+//
+// As an example, if one needed to build against a newer version of Imath and
+// have it run alongside an older version in the same application, it is now
+// possible to use an internal namespace to prevent collisions between the
+// older versions of Imath symbols and the newer ones.  To do this, the
+// following could be defined at build time:
+//
+// IMATH_INTERNAL_NAMESPACE = Imath_v2
+//
+// This means that declarations inside Imath headers look like this (after
+// the preprocessor has done its work):
+//
+// namespace Imath_v2 {
+//     ...
+//     class declarations
+//     ...
+// }
+//
+// namespace Imath {
+//     using namespace Imath_v2;
+// }
+//
+
+//
+// Open Source version of this file pulls in the IlmBaseConfig.h file
+// for the configure time options.
+//
+#include "IlmBaseConfig.h"
+
+
+#ifndef IMATH_NAMESPACE
+#define IMATH_NAMESPACE Imath
+#endif
+
+#ifndef IMATH_INTERNAL_NAMESPACE
+#define IMATH_INTERNAL_NAMESPACE IMATH_NAMESPACE
+#endif
+
+//
+// We need to be sure that we import the internal namespace into the public one.
+// To do this, we use the small bit of code below which initially defines
+// IMATH_INTERNAL_NAMESPACE (so it can be referenced) and then defines
+// IMATH_NAMESPACE and pulls the internal symbols into the public
+// namespace.
+//
+
+namespace IMATH_INTERNAL_NAMESPACE {}
+namespace IMATH_NAMESPACE {
+     using namespace IMATH_INTERNAL_NAMESPACE;
+}
+
+//
+// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
+// future extension to the namespace mechanism is possible without changing
+// project source code.
+//
+
+#define IMATH_INTERNAL_NAMESPACE_HEADER_ENTER namespace IMATH_INTERNAL_NAMESPACE {
+#define IMATH_INTERNAL_NAMESPACE_HEADER_EXIT }
+
+#define IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER namespace IMATH_INTERNAL_NAMESPACE {
+#define IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT }
+
+
+#endif /* INCLUDED_IMATHNAMESPACE_H */
index b741958..7272d67 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -54,8 +54,9 @@
 
 #include "ImathVec.h"
 #include "ImathLine.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 template <class T>
@@ -70,22 +71,22 @@ class Plane3
     Plane3(const Vec3<T> &normal, T distance);
     Plane3(const Vec3<T> &point, const Vec3<T> &normal);
     Plane3(const Vec3<T> &point1,
-       const Vec3<T> &point2,
-       const Vec3<T> &point3);
+          const Vec3<T> &point2,
+          const Vec3<T> &point3);
 
     //----------------------
     // Various set methods
     //----------------------
 
     void                        set(const Vec3<T> &normal,
-                    T distance);
+                                   T distance);
 
     void                        set(const Vec3<T> &point,
-                    const Vec3<T> &normal);
+                                   const Vec3<T> &normal);
 
     void                        set(const Vec3<T> &point1,
-                    const Vec3<T> &point2,
-                    const Vec3<T> &point3 );
+                                   const Vec3<T> &point2,
+                                   const Vec3<T> &point3 );
 
     //----------------------
     // Utilities
@@ -95,7 +96,7 @@ class Plane3
                                           Vec3<T> &intersection) const;
 
     bool                        intersectT(const Line3<T> &line,
-                       T &parameter) const;
+                                          T &parameter) const;
 
     T                          distanceTo(const Vec3<T> &) const;
 
@@ -118,8 +119,8 @@ typedef Plane3<double> Plane3d;
 
 template <class T>
 inline Plane3<T>::Plane3(const Vec3<T> &p0,
-             const Vec3<T> &p1,
-             const Vec3<T> &p2)
+                        const Vec3<T> &p1,
+                        const Vec3<T> &p2)
 {
     set(p0,p1,p2);
 }
@@ -138,8 +139,8 @@ inline Plane3<T>::Plane3(const Vec3<T> &p, const Vec3<T> &n)
 
 template <class T>
 inline void Plane3<T>::set(const Vec3<T>& point1,
-               const Vec3<T>& point2,
-               const Vec3<T>& point3)
+                          const Vec3<T>& point2,
+                          const Vec3<T>& point3)
 {
     normal = (point2 - point1) % (point3 - point1);
     normal.normalize();
@@ -205,7 +206,7 @@ template<class T>
 std::ostream &operator<< (std::ostream &o, const Plane3<T> &plane)
 {
     return o << "(" << plane.normal << ", " << plane.distance
-         << ")";
+            << ")";
 }
 
 template<class T>
@@ -224,8 +225,8 @@ Plane3<T> operator* (const Plane3<T> &plane, const Matrix44<T> &M)
 
     if (tmpLen > dir1Len)
     {
-    dir1      = tmp;
-    dir1Len   = tmpLen;
+       dir1      = tmp;
+       dir1Len   = tmpLen;
     }
 
     tmp            = Vec3<T> (0, 0, 1) % plane.normal;
@@ -233,15 +234,15 @@ Plane3<T> operator* (const Plane3<T> &plane, const Matrix44<T> &M)
 
     if (tmpLen > dir1Len)
     {
-    dir1      = tmp;
+       dir1      = tmp;
     }
 
     Vec3<T> dir2   = dir1 % plane.normal;
     Vec3<T> point  = plane.distance * plane.normal;
 
     return Plane3<T> ( point         * M,
-              (point + dir2) * M,
-              (point + dir1) * M );
+                     (point + dir2) * M,
+                     (point + dir1) * M );
 }
 
 template<class T>
@@ -251,6 +252,6 @@ Plane3<T> operator- (const Plane3<T> &plane)
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHPLANE_H
index 886b770..91e82cc 100644 (file)
@@ -2,9 +2,9 @@
 //
 // Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -39,8 +39,8 @@
 //
 //     ImathPlatform.h
 //
-//     This file contains functions and constants which aren't
-//     provided by the system libraries, compilers, or includes on
+//     This file contains functions and constants which aren't 
+//     provided by the system libraries, compilers, or includes on 
 //     certain platforms.
 //
 //----------------------------------------------------------------------------
index 99c7d83..e95e356 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 
 #include "ImathExc.h"
 #include "ImathMatrix.h"
+#include "ImathNamespace.h"
 
 #include <iostream>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
 // Disable MS VC++ warnings about conversion from double to float
@@ -136,7 +137,7 @@ class Quat
     Quat<T> &          setAxisAngle (const Vec3<T> &axis, T radians);
 
     Quat<T> &          setRotation (const Vec3<T> &fromDirection,
-                     const Vec3<T> &toDirection);
+                                    const Vec3<T> &toDirection);
 
     T                  angle () const;
     Vec3<T>            axis () const;
@@ -151,8 +152,8 @@ class Quat
   private:
 
     void               setRotationInternal (const Vec3<T> &f0,
-                         const Vec3<T> &t0,
-                         Quat<T> &q);
+                                            const Vec3<T> &t0,
+                                            Quat<T> &q);
 };
 
 
@@ -165,13 +166,13 @@ Quat<T>                   slerpShortestArc
 
 
 template<class T>
-Quat<T>                        squad (const Quat<T> &q1, const Quat<T> &q2,
-                   const Quat<T> &qa, const Quat<T> &qb, T t);
+Quat<T>                        squad (const Quat<T> &q1, const Quat<T> &q2, 
+                              const Quat<T> &qa, const Quat<T> &qb, T t);
 
 template<class T>
-void                   intermediate (const Quat<T> &q0, const Quat<T> &q1,
-                      const Quat<T> &q2, const Quat<T> &q3,
-                      Quat<T> &qa, Quat<T> &qb);
+void                   intermediate (const Quat<T> &q0, const Quat<T> &q1, 
+                                     const Quat<T> &q2, const Quat<T> &q3,
+                                     Quat<T> &qa, Quat<T> &qb);
 
 template<class T>
 Matrix33<T>            operator * (const Matrix33<T> &M, const Quat<T> &q);
@@ -391,13 +392,13 @@ Quat<T>::normalize ()
 {
     if (T l = length())
     {
-    r /= l;
-    v /= l;
+       r /= l;
+       v /= l;
     }
     else
     {
-    r = 1;
-    v = Vec3<T> (0);
+       r = 1;
+       v = Vec3<T> (0);
     }
 
     return *this;
@@ -409,7 +410,7 @@ inline Quat<T>
 Quat<T>::normalized () const
 {
     if (T l = length())
-    return Quat (r / l, v / l);
+       return Quat (r / l, v / l);
 
     return Quat();
 }
@@ -463,7 +464,7 @@ Quat<T>::rotateVector(const Vec3<T>& original) const
 
 
 template<class T>
-inline T
+inline T 
 Quat<T>::euclideanInnerProduct (const Quat<T> &q) const
 {
     return r * q.r + v.x * q.v.x + v.y * q.v.y + v.z * q.v.z;
@@ -516,7 +517,7 @@ slerp (const Quat<T> &q1, const Quat<T> &q2, T t)
     T s = 1 - t;
 
     Quat<T> q = sinx_over_x (s * a) / sinx_over_x (a) * s * q1 +
-            sinx_over_x (t * a) / sinx_over_x (a) * t * q2;
+               sinx_over_x (t * a) / sinx_over_x (a) * t * q2;
 
     return q.normalized();
 }
@@ -543,7 +544,7 @@ template<class T>
 Quat<T>
 spline (const Quat<T> &q0, const Quat<T> &q1,
         const Quat<T> &q2, const Quat<T> &q3,
-    T t)
+       T t)
 {
     //
     // Spherical Cubic Spline Interpolation -
@@ -555,17 +556,17 @@ spline (const Quat<T> &q0, const Quat<T> &q1,
     // Given a set of quaternion keys: q0, q1, q2, q3,
     // this routine does the interpolation between
     // q1 and q2 by constructing two intermediate
-    // quaternions: qa and qb. The qa and qb are
-    // computed by the intermediate function to
+    // quaternions: qa and qb. The qa and qb are 
+    // computed by the intermediate function to 
     // guarantee the continuity of tangents across
     // adjacent cubic segments. The qa represents in-tangent
     // for q1 and the qb represents the out-tangent for q2.
-    //
-    // The q1 q2 is the cubic segment being interpolated.
-    // The q0 is from the previous adjacent segment and q3 is
+    // 
+    // The q1 q2 is the cubic segment being interpolated. 
+    // The q0 is from the previous adjacent segment and q3 is 
     // from the next adjacent segment. The q0 and q3 are used
     // in computing qa and qb.
-    //
+    // 
 
     Quat<T> qa = intermediate (q0, q1, q2);
     Quat<T> qb = intermediate (q1, q2, q3);
@@ -585,11 +586,11 @@ squad (const Quat<T> &q1, const Quat<T> &qa,
     // Spherical Quadrangle Interpolation -
     // from Advanced Animation and Rendering
     // Techniques by Watt and Watt, Page 366:
-    // It constructs a spherical cubic interpolation as
-    // a series of three spherical linear interpolations
-    // of a quadrangle of unit quaternions.
-    //
-
+    // It constructs a spherical cubic interpolation as 
+    // a series of three spherical linear interpolations 
+    // of a quadrangle of unit quaternions. 
+    //     
+  
     Quat<T> r1 = slerp (q1, q2, t);
     Quat<T> r2 = slerp (qa, qb, t);
     Quat<T> result = slerp (r1, r2, 2 * t * (1 - t));
@@ -605,10 +606,10 @@ intermediate (const Quat<T> &q0, const Quat<T> &q1, const Quat<T> &q2)
     //
     // From advanced Animation and Rendering
     // Techniques by Watt and Watt, Page 366:
-    // computing the inner quadrangle
+    // computing the inner quadrangle 
     // points (qa and qb) to guarantee tangent
     // continuity.
-    //
+    // 
 
     Quat<T> q1inv = q1.inverse();
     Quat<T> c1 = q1inv * q2;
@@ -625,22 +626,22 @@ inline Quat<T>
 Quat<T>::log () const
 {
     //
-    // For unit quaternion, from Advanced Animation and
+    // For unit quaternion, from Advanced Animation and 
     // Rendering Techniques by Watt and Watt, Page 366:
     //
 
     T theta = Math<T>::acos (std::min (r, (T) 1.0));
 
     if (theta == 0)
-    return Quat<T> (0, v);
-
+       return Quat<T> (0, v);
+    
     T sintheta = Math<T>::sin (theta);
-
+    
     T k;
     if (abs (sintheta) < 1 && abs (theta) >= limits<T>::max() * abs (sintheta))
-    k = 1;
+       k = 1;
     else
-    k = theta / sintheta;
+       k = theta / sintheta;
 
     return Quat<T> ((T) 0, v.x * k, v.y * k, v.z * k);
 }
@@ -658,12 +659,12 @@ Quat<T>::exp () const
 
     T theta = v.length();
     T sintheta = Math<T>::sin (theta);
-
+    
     T k;
     if (abs (theta) < 1 && abs (sintheta) >= limits<T>::max() * abs (theta))
-    k = 1;
+       k = 1;
     else
-    k = sintheta / theta;
+       k = sintheta / theta;
 
     T costheta = Math<T>::cos (theta);
 
@@ -722,50 +723,50 @@ Quat<T>::setRotation (const Vec3<T> &from, const Vec3<T> &to)
 
     if ((f0 ^ t0) >= 0)
     {
-    //
-    // The rotation angle is less than or equal to pi/2.
-    //
+       //
+       // The rotation angle is less than or equal to pi/2.
+       //
 
-    setRotationInternal (f0, t0, *this);
+       setRotationInternal (f0, t0, *this);
     }
     else
     {
-    //
-    // The angle is greater than pi/2.  After computing h0,
-    // which is halfway between f0 and t0, we rotate first
-    // from f0 to h0, then from h0 to t0.
-    //
-
-    Vec3<T> h0 = (f0 + t0).normalized();
-
-    if ((h0 ^ h0) != 0)
-    {
-        setRotationInternal (f0, h0, *this);
-
-        Quat<T> q;
-        setRotationInternal (h0, t0, q);
-
-        *this *= q;
-    }
-    else
-    {
-        //
-        // f0 and t0 point in exactly opposite directions.
-        // Pick an arbitrary axis that is orthogonal to f0,
-        // and rotate by pi.
-        //
-
-        r = T (0);
-
-        Vec3<T> f02 = f0 * f0;
-
-        if (f02.x <= f02.y && f02.x <= f02.z)
-        v = (f0 % Vec3<T> (1, 0, 0)).normalized();
-        else if (f02.y <= f02.z)
-        v = (f0 % Vec3<T> (0, 1, 0)).normalized();
-        else
-        v = (f0 % Vec3<T> (0, 0, 1)).normalized();
-    }
+       //
+       // The angle is greater than pi/2.  After computing h0,
+       // which is halfway between f0 and t0, we rotate first
+       // from f0 to h0, then from h0 to t0.
+       //
+
+       Vec3<T> h0 = (f0 + t0).normalized();
+
+       if ((h0 ^ h0) != 0)
+       {
+           setRotationInternal (f0, h0, *this);
+
+           Quat<T> q;
+           setRotationInternal (h0, t0, q);
+
+           *this *= q;
+       }
+       else
+       {
+           //
+           // f0 and t0 point in exactly opposite directions.
+           // Pick an arbitrary axis that is orthogonal to f0,
+           // and rotate by pi.
+           //
+
+           r = T (0);
+
+           Vec3<T> f02 = f0 * f0;
+
+           if (f02.x <= f02.y && f02.x <= f02.z)
+               v = (f0 % Vec3<T> (1, 0, 0)).normalized();
+           else if (f02.y <= f02.z)
+               v = (f0 % Vec3<T> (0, 1, 0)).normalized();
+           else
+               v = (f0 % Vec3<T> (0, 0, 1)).normalized();
+       }
     }
 
     return *this;
@@ -809,16 +810,16 @@ Matrix33<T>
 Quat<T>::toMatrix33() const
 {
     return Matrix33<T> (1 - 2 * (v.y * v.y + v.z * v.z),
-                2 * (v.x * v.y + v.z * r),
-                2 * (v.z * v.x - v.y * r),
+                           2 * (v.x * v.y + v.z * r),
+                           2 * (v.z * v.x - v.y * r),
 
-                2 * (v.x * v.y - v.z * r),
-                1 - 2 * (v.z * v.z + v.x * v.x),
-                2 * (v.y * v.z + v.x * r),
+                           2 * (v.x * v.y - v.z * r),
+                       1 - 2 * (v.z * v.z + v.x * v.x),
+                           2 * (v.y * v.z + v.x * r),
 
-                2 * (v.z * v.x + v.y * r),
-                2 * (v.y * v.z - v.x * r),
-                1 - 2 * (v.y * v.y + v.x * v.x));
+                           2 * (v.z * v.x + v.y * r),
+                           2 * (v.y * v.z - v.x * r),
+                       1 - 2 * (v.y * v.y + v.x * v.x));
 }
 
 template<class T>
@@ -826,21 +827,21 @@ Matrix44<T>
 Quat<T>::toMatrix44() const
 {
     return Matrix44<T> (1 - 2 * (v.y * v.y + v.z * v.z),
-                2 * (v.x * v.y + v.z * r),
-                2 * (v.z * v.x - v.y * r),
-                0,
-                2 * (v.x * v.y - v.z * r),
-                1 - 2 * (v.z * v.z + v.x * v.x),
-                2 * (v.y * v.z + v.x * r),
-                0,
-                2 * (v.z * v.x + v.y * r),
-                2 * (v.y * v.z - v.x * r),
-                1 - 2 * (v.y * v.y + v.x * v.x),
-                0,
-                0,
-                0,
-                0,
-                1);
+                           2 * (v.x * v.y + v.z * r),
+                           2 * (v.z * v.x - v.y * r),
+                           0,
+                           2 * (v.x * v.y - v.z * r),
+                       1 - 2 * (v.z * v.z + v.x * v.x),
+                           2 * (v.y * v.z + v.x * r),
+                           0,
+                           2 * (v.z * v.x + v.y * r),
+                           2 * (v.y * v.z - v.x * r),
+                       1 - 2 * (v.y * v.y + v.x * v.x),
+                           0,
+                           0,
+                           0,
+                           0,
+                           1);
 }
 
 
@@ -865,10 +866,10 @@ std::ostream &
 operator << (std::ostream &o, const Quat<T> &q)
 {
     return o << "(" << q.r
-         << " " << q.v.x
-         << " " << q.v.y
-         << " " << q.v.z
-         << ")";
+            << " " << q.v.x
+            << " " << q.v.y
+            << " " << q.v.z
+            << ")";
 }
 
 
@@ -877,7 +878,7 @@ inline Quat<T>
 operator * (const Quat<T> &q1, const Quat<T> &q2)
 {
     return Quat<T> (q1.r * q2.r - (q1.v ^ q2.v),
-            q1.r * q2.v + q1.v * q2.r + q1.v % q2.v);
+                   q1.r * q2.v + q1.v * q2.r + q1.v % q2.v);
 }
 
 
@@ -958,6 +959,6 @@ operator * (const Vec3<T> &v, const Quat<T> &q)
 #pragma warning(default:4244)
 #endif
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHQUAT_H
index 23a0e17..cf3d600 100644 (file)
@@ -1,11 +1,10 @@
-
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -17,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -43,7 +42,7 @@
 #include "ImathRandom.h"
 #include "ImathInt64.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 namespace {
 
 //
@@ -61,7 +60,7 @@ rand48Next (unsigned short state[3])
     // sequence,
     //
     //   x[n+1] = (a * x[n] + c) % m,
-    //
+    // 
     // where a and c are as specified below, and m == (1 << 48)
     //
 
@@ -74,8 +73,8 @@ rand48Next (unsigned short state[3])
     //
 
     Int64 x = (Int64 (state[2]) << 32) |
-          (Int64 (state[1]) << 16) |
-           Int64 (state[0]);
+             (Int64 (state[1]) << 16) |
+              Int64 (state[0]);
 
     //
     // Compute x[n+1], except for the "modulo m" part.
@@ -104,7 +103,7 @@ erand48 (unsigned short state[3])
 {
     //
     // Generate double-precision floating-point values between 0.0 and 1.0:
-    //
+    // 
     // The exponent is set to 0x3ff, which indicates a value greater
     // than or equal to 1.0, and less than 2.0.  The 48 most significant
     // bits of the significand (mantissa) are filled with pseudo-random
@@ -115,17 +114,17 @@ erand48 (unsigned short state[3])
     // between 1.0 and 1.99999999999999978.  Subtracting 1.0 from those
     // values produces numbers between 0.0 and 0.99999999999999978, that
     // is, between 0.0 and 1.0-DBL_EPSILON.
-    //
+    // 
 
     rand48Next (state);
 
     union {double d; Int64 i;} u;
 
     u.i = (Int64 (0x3ff)    << 52) |   // sign and exponent
-      (Int64 (state[2]) << 36) |       // significand
-      (Int64 (state[1]) << 20) |
-      (Int64 (state[0]) <<  4) |
-      (Int64 (state[2]) >> 12);
+         (Int64 (state[2]) << 36) |    // significand
+         (Int64 (state[1]) << 20) |
+         (Int64 (state[0]) <<  4) |
+         (Int64 (state[2]) >> 12);
 
     return u.d - 1;
 }
@@ -134,7 +133,7 @@ erand48 (unsigned short state[3])
 double
 drand48 ()
 {
-    return Imath::erand48 (staticState);
+    return IMATH_INTERNAL_NAMESPACE::erand48 (staticState);
 }
 
 
@@ -143,19 +142,19 @@ nrand48 (unsigned short state[3])
 {
     //
     // Generate uniformly distributed integers between 0 and 0x7fffffff.
-    //
+    // 
 
     rand48Next (state);
 
     return ((long int) (state[2]) << 15) |
-       ((long int) (state[1]) >>  1);
+          ((long int) (state[1]) >>  1);
 }
 
 
 long int
 lrand48 ()
 {
-    return Imath::nrand48 (staticState);
+    return IMATH_INTERNAL_NAMESPACE::nrand48 (staticState);
 }
 
 
@@ -173,7 +172,7 @@ Rand32::nextf ()
 {
     //
     // Generate single-precision floating-point values between 0.0 and 1.0:
-    //
+    // 
     // The exponent is set to 0x7f, which indicates a value greater than
     // or equal to 1.0, and less than 2.0.  The 23 bits of the significand
     // (mantissa) are filled with pseudo-random bits generated by
@@ -182,7 +181,7 @@ Rand32::nextf ()
     // point values between 1.0 and 1.99999988.  Subtracting 1.0 from
     // those values produces numbers between 0.0 and 0.99999988, that is,
     // between 0.0 and 1.0-FLT_EPSILON.
-    //
+    // 
 
     next ();
 
@@ -192,4 +191,4 @@ Rand32::nextf ()
     return u.f - 1;
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
index 8a4dc14..4f0db13 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //-----------------------------------------------------------------------------
 
+#include "ImathNamespace.h"
+#include "ImathExport.h"
+
 #include <stdlib.h>
 #include <math.h>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //-----------------------------------------------
 // Fast random-number generator that generates
@@ -67,7 +70,7 @@ namespace Imath {
 // length of 2^32.
 //-----------------------------------------------
 
-class Rand32
+class IMATH_EXPORT Rand32
 {
   public:
 
@@ -76,7 +79,7 @@ class Rand32
     //------------
 
     Rand32 (unsigned long int seed = 0);
-
+    
 
     //--------------------------------
     // Re-initialize with a given seed
@@ -136,7 +139,7 @@ class Rand48
     //------------
 
     Rand48 (unsigned long int seed = 0);
-
+    
 
     //--------------------------------
     // Re-initialize with a given seed
@@ -185,7 +188,7 @@ class Rand48
 //------------------------------------------------------------
 
 template <class Vec, class Rand>
-Vec
+Vec            
 solidSphereRand (Rand &rand);
 
 
@@ -195,7 +198,7 @@ solidSphereRand (Rand &rand);
 //-------------------------------------------------------------
 
 template <class Vec, class Rand>
-Vec
+Vec            
 hollowSphereRand (Rand &rand);
 
 
@@ -224,11 +227,11 @@ gaussSphereRand (Rand &rand);
 // erand48(), nrand48() and friends
 //---------------------------------
 
-double         erand48 (unsigned short state[3]);
-double         drand48 ();
-long int       nrand48 (unsigned short state[3]);
-long int       lrand48 ();
-void           srand48 (long int seed);
+IMATH_EXPORT double     erand48 (unsigned short state[3]);
+IMATH_EXPORT double     drand48 ();
+IMATH_EXPORT long int   nrand48 (unsigned short state[3]);
+IMATH_EXPORT long int   lrand48 ();
+IMATH_EXPORT void       srand48 (long int seed);
 
 
 //---------------
@@ -289,11 +292,11 @@ Rand48::init (unsigned long int seed)
 
     _state[0] = (unsigned short int) (seed & 0xFFFF);
     _state[1] = (unsigned short int) ((seed >> 16) & 0xFFFF);
-    _state[2] = (unsigned short int) (seed & 0xFFFF);
+    _state[2] = (unsigned short int) (seed & 0xFFFF);   
 }
 
 
-inline
+inline 
 Rand48::Rand48 (unsigned long int seed)
 {
     init (seed);
@@ -303,21 +306,21 @@ Rand48::Rand48 (unsigned long int seed)
 inline bool
 Rand48::nextb ()
 {
-    return Imath::nrand48 (_state) & 1;
+    return nrand48 (_state) & 1;
 }
 
 
 inline long int
 Rand48::nexti ()
 {
-    return Imath::nrand48 (_state);
+    return nrand48 (_state);
 }
 
 
 inline double
 Rand48::nextf ()
 {
-    return Imath::erand48 (_state);
+    return erand48 (_state);
 }
 
 
@@ -337,8 +340,8 @@ solidSphereRand (Rand &rand)
 
     do
     {
-    for (unsigned int i = 0; i < Vec::dimensions(); i++)
-        v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
+       for (unsigned int i = 0; i < Vec::dimensions(); i++)
+           v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
     }
     while (v.length2() > 1);
 
@@ -355,10 +358,10 @@ hollowSphereRand (Rand &rand)
 
     do
     {
-    for (unsigned int i = 0; i < Vec::dimensions(); i++)
-        v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
+       for (unsigned int i = 0; i < Vec::dimensions(); i++)
+           v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
 
-    length = v.length();
+       length = v.length();
     }
     while (length > 1 || length == 0);
 
@@ -373,12 +376,12 @@ gaussRand (Rand &rand)
     float x;           // Note: to avoid numerical problems with very small
     float y;           // numbers, we make these variables singe-precision
     float length2;     // floats, but later we call the double-precision log()
-            // and sqrt() functions instead of logf() and sqrtf().
+                       // and sqrt() functions instead of logf() and sqrtf().
     do
     {
-    x = float (rand.nextf (-1, 1));
-    y = float (rand.nextf (-1, 1));
-    length2 = x * x + y * y;
+       x = float (rand.nextf (-1, 1));
+       y = float (rand.nextf (-1, 1));
+       length2 = x * x + y * y;
     }
     while (length2 >= 1 || length2 == 0);
 
@@ -393,6 +396,6 @@ gaussSphereRand (Rand &rand)
     return hollowSphereRand <Vec> (rand) * gaussRand (rand);
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHRANDOM_H
index df3f390..036b7f7 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 //
 //---------------------------------------------------------------------
 
-#include <ImathMath.h>
+#include "ImathMath.h"
+#include "ImathNamespace.h"
 #include <complex>
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 //--------------------------------------------------------------------------
 // Find the real solutions of a linear, quadratic or cubic equation:
@@ -97,16 +98,16 @@ solveLinear (T a, T b, T &x)
 {
     if (a != 0)
     {
-    x = -b / a;
-    return 1;
+       x = -b / a;
+       return 1;
     }
     else if (b != 0)
     {
-    return 0;
+       return 0;
     }
     else
     {
-    return -1;
+       return -1;
     }
 }
 
@@ -117,30 +118,30 @@ solveQuadratic (T a, T b, T c, T x[2])
 {
     if (a == 0)
     {
-    return solveLinear (b, c, x[0]);
-    }
-    else
-    {
-    T D = b * b - 4 * a * c;
-
-    if (D > 0)
-    {
-        T s = Math<T>::sqrt (D);
-        T q = -(b + (b > 0 ? 1 : -1) * s) / T(2);
-
-        x[0] = q / a;
-        x[1] = c / q;
-        return 2;
-    }
-    if (D == 0)
-    {
-        x[0] = -b / (2 * a);
-        return 1;
+       return solveLinear (b, c, x[0]);
     }
     else
     {
-        return 0;
-    }
+       T D = b * b - 4 * a * c;
+
+       if (D > 0)
+       {
+           T s = Math<T>::sqrt (D);
+           T q = -(b + (b > 0 ? 1 : -1) * s) / T(2);
+
+           x[0] = q / a;
+           x[1] = c / q;
+           return 2;
+       }
+       if (D == 0)
+       {
+           x[0] = -b / (2 * a);
+           return 1;
+       }
+       else
+       {
+           return 0;
+       }
     }
 }
 
@@ -157,44 +158,44 @@ solveNormalizedCubic (T r, T s, T t, T x[3])
 
     if (D == 0 && p3 == 0)
     {
-    x[0] = -r / 3;
-    x[1] = -r / 3;
-    x[2] = -r / 3;
-    return 1;
+       x[0] = -r / 3;
+       x[1] = -r / 3;
+       x[2] = -r / 3;
+       return 1;
     }
 
     std::complex<T> u = std::pow (-q / 2 + std::sqrt (std::complex<T> (D)),
-                  T (1) / T (3));
+                                 T (1) / T (3));
 
     std::complex<T> v = -p / (T (3) * u);
 
     const T sqrt3 = T (1.73205080756887729352744634150587); // enough digits
-                                // for long double
+                                                           // for long double
     std::complex<T> y0 (u + v);
 
     std::complex<T> y1 (-(u + v) / T (2) +
-             (u - v) / T (2) * std::complex<T> (0, sqrt3));
+                        (u - v) / T (2) * std::complex<T> (0, sqrt3));
 
     std::complex<T> y2 (-(u + v) / T (2) -
-             (u - v) / T (2) * std::complex<T> (0, sqrt3));
+                        (u - v) / T (2) * std::complex<T> (0, sqrt3));
 
     if (D > 0)
     {
-    x[0] = y0.real() - r / 3;
-    return 1;
+       x[0] = y0.real() - r / 3;
+       return 1;
     }
     else if (D == 0)
     {
-    x[0] = y0.real() - r / 3;
-    x[1] = y1.real() - r / 3;
-    return 2;
+       x[0] = y0.real() - r / 3;
+       x[1] = y1.real() - r / 3;
+       return 2;
     }
     else
     {
-    x[0] = y0.real() - r / 3;
-    x[1] = y1.real() - r / 3;
-    x[2] = y2.real() - r / 3;
-    return 3;
+       x[0] = y0.real() - r / 3;
+       x[1] = y1.real() - r / 3;
+       x[2] = y2.real() - r / 3;
+       return 3;
     }
 }
 
@@ -205,15 +206,14 @@ solveCubic (T a, T b, T c, T d, T x[3])
 {
     if (a == 0)
     {
-    return solveQuadratic (b, c, d, x);
+       return solveQuadratic (b, c, d, x);
     }
     else
     {
-    return solveNormalizedCubic (b / a, c / a, d / a, x);
+       return solveNormalizedCubic (b / a, c / a, d / a, x);
     }
 }
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} // namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHROOTS_H
diff --git a/3rdparty/openexr/Imath/ImathShear.cpp b/3rdparty/openexr/Imath/ImathShear.cpp
new file mode 100644 (file)
index 0000000..2c0ba2a
--- /dev/null
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic 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 BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+
+
+//----------------------------------------------------------------------------
+//
+//     Specializations of the Shear6<T> template.
+//
+//----------------------------------------------------------------------------
+
+#include "ImathShear.h"
+
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
+
+
+
+// empty
+
+
+
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
index 132ab1e..b6f7b9a 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 #include "ImathLimits.h"
 #include "ImathMath.h"
 #include "ImathVec.h"
-
+#include "ImathNamespace.h"
 #include <iostream>
 
 
-namespace Imath {
-
-
-
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T> class Shear6
 {
@@ -78,9 +75,9 @@ template <class T> class Shear6
     Shear6 (T XY, T XZ, T YZ);    // (XY XZ YZ 0 0 0)
     Shear6 (const Vec3<T> &v);     // (v.x v.y v.z 0 0 0)
     template <class S>             // (v.x v.y v.z 0 0 0)
-    Shear6 (const Vec3<S> &v);
+       Shear6 (const Vec3<S> &v);
     Shear6 (T XY, T XZ, T YZ,      // (XY XZ YZ YX ZX ZY)
-        T YX, T ZX, T ZY);
+           T YX, T ZX, T ZY);  
 
 
     //---------------------------------
@@ -91,8 +88,8 @@ template <class T> class Shear6
     template <class S> Shear6 (const Shear6<S> &h);
 
     const Shear6 &     operator = (const Shear6 &h);
-    template <class S>
-    const Shear6 &     operator = (const Vec3<S> &v);
+    template <class S> 
+       const Shear6 &  operator = (const Vec3<S> &v);
 
 
     //----------------------
@@ -106,8 +103,8 @@ template <class T> class Shear6
     void               setValue (const Shear6<S> &h);
 
     template <class S>
-    void               getValue (S &XY, S &XZ, S &YZ,
-                  S &YX, S &ZX, S &ZY) const;
+    void               getValue (S &XY, S &XZ, S &YZ, 
+                                 S &YX, S &ZX, S &ZY) const;
 
     template <class S>
     void               getValue (Shear6<S> &h) const;
@@ -443,8 +440,8 @@ template <class S>
 inline bool
 Shear6<T>::operator == (const Shear6<S> &h) const
 {
-    return xy == h.xy  &&  xz == h.xz  &&  yz == h.yz  &&
-       yx == h.yx  &&  zx == h.zx  &&  zy == h.zy;
+    return xy == h.xy  &&  xz == h.xz  &&  yz == h.yz  &&  
+          yx == h.yx  &&  zx == h.zx  &&  zy == h.zy;
 }
 
 template <class T>
@@ -453,7 +450,7 @@ inline bool
 Shear6<T>::operator != (const Shear6<S> &h) const
 {
     return xy != h.xy  ||  xz != h.xz  ||  yz != h.yz  ||
-       yx != h.yx  ||  zx != h.zx  ||  zy != h.zy;
+          yx != h.yx  ||  zx != h.zx  ||  zy != h.zy;
 }
 
 template <class T>
@@ -461,8 +458,8 @@ bool
 Shear6<T>::equalWithAbsError (const Shear6<T> &h, T e) const
 {
     for (int i = 0; i < 6; i++)
-    if (!Imath::equalWithAbsError ((*this)[i], h[i], e))
-        return false;
+       if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], h[i], e))
+           return false;
 
     return true;
 }
@@ -472,8 +469,8 @@ bool
 Shear6<T>::equalWithRelError (const Shear6<T> &h, T e) const
 {
     for (int i = 0; i < 6; i++)
-    if (!Imath::equalWithRelError ((*this)[i], h[i], e))
-        return false;
+       if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], h[i], e))
+           return false;
 
     return true;
 }
@@ -497,7 +494,7 @@ inline Shear6<T>
 Shear6<T>::operator + (const Shear6 &h) const
 {
     return Shear6 (xy + h.xy, xz + h.xz, yz + h.yz,
-           yx + h.yx, zx + h.zx, zy + h.zy);
+                  yx + h.yx, zx + h.zx, zy + h.zy);
 }
 
 template <class T>
@@ -518,7 +515,7 @@ inline Shear6<T>
 Shear6<T>::operator - (const Shear6 &h) const
 {
     return Shear6 (xy - h.xy, xz - h.xz, yz - h.yz,
-           yx - h.yx, zx - h.zx, zy - h.zy);
+                  yx - h.yx, zx - h.zx, zy - h.zy);
 }
 
 template <class T>
@@ -571,8 +568,8 @@ template <class T>
 inline Shear6<T>
 Shear6<T>::operator * (const Shear6 &h) const
 {
-    return Shear6 (xy * h.xy, xz * h.xz, yz * h.yz,
-           yx * h.yx, zx * h.zx, zy * h.zy);
+    return Shear6 (xy * h.xy, xz * h.xz, yz * h.yz, 
+                  yx * h.yx, zx * h.zx, zy * h.zy);
 }
 
 template <class T>
@@ -580,7 +577,7 @@ inline Shear6<T>
 Shear6<T>::operator * (T a) const
 {
     return Shear6 (xy * a, xz * a, yz * a,
-           yx * a, zx * a, zy * a);
+                  yx * a, zx * a, zy * a);
 }
 
 template <class T>
@@ -614,7 +611,7 @@ inline Shear6<T>
 Shear6<T>::operator / (const Shear6 &h) const
 {
     return Shear6 (xy / h.xy, xz / h.xz, yz / h.yz,
-           yx / h.yx, zx / h.zx, zy / h.zy);
+                  yx / h.yx, zx / h.zx, zy / h.zy);
 }
 
 template <class T>
@@ -622,7 +619,7 @@ inline Shear6<T>
 Shear6<T>::operator / (T a) const
 {
     return Shear6 (xy / a, xz / a, yz / a,
-           yx / a, zx / a, zy / a);
+                  yx / a, zx / a, zy / a);
 }
 
 
@@ -634,10 +631,10 @@ template <class T>
 std::ostream &
 operator << (std::ostream &s, const Shear6<T> &h)
 {
-    return s << '('
-         << h.xy << ' ' << h.xz << ' ' << h.yz
-         << h.yx << ' ' << h.zx << ' ' << h.zy
-         << ')';
+    return s << '(' 
+            << h.xy << ' ' << h.xz << ' ' << h.yz 
+            << h.yx << ' ' << h.zx << ' ' << h.zy 
+            << ')';
 }
 
 
@@ -650,10 +647,10 @@ inline Shear6<T>
 operator * (S a, const Shear6<T> &h)
 {
     return Shear6<T> (a * h.xy, a * h.xz, a * h.yz,
-              a * h.yx, a * h.zx, a * h.zy);
+                     a * h.yx, a * h.zx, a * h.zy);
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHSHEAR_H
index 83645eb..e8f36df 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -46,8 +46,9 @@
 #include "ImathVec.h"
 #include "ImathBox.h"
 #include "ImathLine.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T>
 class Sphere3
@@ -129,26 +130,26 @@ bool Sphere3<T>::intersectT(const Line3<T> &line, T &t) const
 
     if (discr < 0.0)
     {
-    // line and Sphere3 do not intersect
+       // line and Sphere3 do not intersect
 
-    doesIntersect = false;
+       doesIntersect = false;
     }
     else
     {
-    // t0: (-B - sqrt(B^2 - 4AC)) / 2A  (A = 1)
+       // t0: (-B - sqrt(B^2 - 4AC)) / 2A  (A = 1)
 
-    T sqroot = Math<T>::sqrt(discr);
-    t = (-B - sqroot) * T(0.5);
+       T sqroot = Math<T>::sqrt(discr);
+       t = (-B - sqroot) * T(0.5);
 
-    if (t < 0.0)
-    {
-        // no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A  (A = 1)
+       if (t < 0.0)
+       {
+           // no intersection, try t1: (-B + sqrt(B^2 - 4AC)) / 2A  (A = 1)
 
-        t = (-B + sqroot) * T(0.5);
-    }
+           t = (-B + sqroot) * T(0.5);
+       }
 
-    if (t < 0.0)
-        doesIntersect = false;
+       if (t < 0.0)
+           doesIntersect = false;
     }
 
     return doesIntersect;
@@ -162,16 +163,15 @@ bool Sphere3<T>::intersect(const Line3<T> &line, Vec3<T> &intersection) const
 
     if (intersectT (line, t))
     {
-    intersection = line(t);
-    return true;
+       intersection = line(t);
+       return true;
     }
     else
     {
-    return false;
+       return false;
     }
 }
 
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-} //namespace Imath
-
-#endif
+#endif // INCLUDED_IMATHSPHERE_H
index a853e0c..37edc97 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -41,6 +41,7 @@
 //----------------------------------------------------------------------------
 
 #include "ImathVec.h"
+#include "ImathExport.h"
 
 #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
 // suppress exception specification warnings
@@ -48,7 +49,7 @@
 #endif
 
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
 
 namespace
 {
@@ -126,7 +127,8 @@ normalizeOrThrow(Vec4<T> &v)
 
 // Vec2<short>
 
-template <>
+template <> 
+IMATH_EXPORT
 short
 Vec2<short>::length () const
 {
@@ -136,6 +138,7 @@ Vec2<short>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<short> &
 Vec2<short>::normalize ()
 {
@@ -144,8 +147,9 @@ Vec2<short>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<short> &
-Vec2<short>::normalizeExc () throw (Iex::MathExc)
+Vec2<short>::normalizeExc ()
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -155,6 +159,7 @@ Vec2<short>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<short> &
 Vec2<short>::normalizeNonNull ()
 {
@@ -163,6 +168,7 @@ Vec2<short>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec2<short>
 Vec2<short>::normalized () const
 {
@@ -172,8 +178,9 @@ Vec2<short>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec2<short>
-Vec2<short>::normalizedExc () const throw (Iex::MathExc)
+Vec2<short>::normalizedExc () const
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -184,6 +191,7 @@ Vec2<short>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec2<short>
 Vec2<short>::normalizedNonNull () const
 {
@@ -195,7 +203,8 @@ Vec2<short>::normalizedNonNull () const
 
 // Vec2<int>
 
-template <>
+template <> 
+IMATH_EXPORT
 int
 Vec2<int>::length () const
 {
@@ -205,6 +214,7 @@ Vec2<int>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<int> &
 Vec2<int>::normalize ()
 {
@@ -213,8 +223,9 @@ Vec2<int>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<int> &
-Vec2<int>::normalizeExc () throw (Iex::MathExc)
+Vec2<int>::normalizeExc ()
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -224,6 +235,7 @@ Vec2<int>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec2<int> &
 Vec2<int>::normalizeNonNull ()
 {
@@ -232,6 +244,7 @@ Vec2<int>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec2<int>
 Vec2<int>::normalized () const
 {
@@ -241,8 +254,9 @@ Vec2<int>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec2<int>
-Vec2<int>::normalizedExc () const throw (Iex::MathExc)
+Vec2<int>::normalizedExc () const
 {
     if ((x == 0) && (y == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -253,6 +267,7 @@ Vec2<int>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec2<int>
 Vec2<int>::normalizedNonNull () const
 {
@@ -264,7 +279,8 @@ Vec2<int>::normalizedNonNull () const
 
 // Vec3<short>
 
-template <>
+template <> 
+IMATH_EXPORT
 short
 Vec3<short>::length () const
 {
@@ -274,6 +290,7 @@ Vec3<short>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<short> &
 Vec3<short>::normalize ()
 {
@@ -282,8 +299,9 @@ Vec3<short>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<short> &
-Vec3<short>::normalizeExc () throw (Iex::MathExc)
+Vec3<short>::normalizeExc ()
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -293,6 +311,7 @@ Vec3<short>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<short> &
 Vec3<short>::normalizeNonNull ()
 {
@@ -301,6 +320,7 @@ Vec3<short>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec3<short>
 Vec3<short>::normalized () const
 {
@@ -310,8 +330,9 @@ Vec3<short>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec3<short>
-Vec3<short>::normalizedExc () const throw (Iex::MathExc)
+Vec3<short>::normalizedExc () const
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -322,6 +343,7 @@ Vec3<short>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec3<short>
 Vec3<short>::normalizedNonNull () const
 {
@@ -333,7 +355,8 @@ Vec3<short>::normalizedNonNull () const
 
 // Vec3<int>
 
-template <>
+template <> 
+IMATH_EXPORT
 int
 Vec3<int>::length () const
 {
@@ -343,6 +366,7 @@ Vec3<int>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<int> &
 Vec3<int>::normalize ()
 {
@@ -351,8 +375,9 @@ Vec3<int>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<int> &
-Vec3<int>::normalizeExc () throw (Iex::MathExc)
+Vec3<int>::normalizeExc ()
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -362,6 +387,7 @@ Vec3<int>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec3<int> &
 Vec3<int>::normalizeNonNull ()
 {
@@ -370,6 +396,7 @@ Vec3<int>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec3<int>
 Vec3<int>::normalized () const
 {
@@ -379,8 +406,9 @@ Vec3<int>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec3<int>
-Vec3<int>::normalizedExc () const throw (Iex::MathExc)
+Vec3<int>::normalizedExc () const
 {
     if ((x == 0) && (y == 0) && (z == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -391,6 +419,7 @@ Vec3<int>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec3<int>
 Vec3<int>::normalizedNonNull () const
 {
@@ -402,7 +431,8 @@ Vec3<int>::normalizedNonNull () const
 
 // Vec4<short>
 
-template <>
+template <> 
+IMATH_EXPORT
 short
 Vec4<short>::length () const
 {
@@ -412,6 +442,7 @@ Vec4<short>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<short> &
 Vec4<short>::normalize ()
 {
@@ -420,8 +451,9 @@ Vec4<short>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<short> &
-Vec4<short>::normalizeExc () throw (Iex::MathExc)
+Vec4<short>::normalizeExc ()
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -431,6 +463,7 @@ Vec4<short>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<short> &
 Vec4<short>::normalizeNonNull ()
 {
@@ -439,6 +472,7 @@ Vec4<short>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec4<short>
 Vec4<short>::normalized () const
 {
@@ -448,8 +482,9 @@ Vec4<short>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec4<short>
-Vec4<short>::normalizedExc () const throw (Iex::MathExc)
+Vec4<short>::normalizedExc () const
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -460,6 +495,7 @@ Vec4<short>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec4<short>
 Vec4<short>::normalizedNonNull () const
 {
@@ -471,7 +507,8 @@ Vec4<short>::normalizedNonNull () const
 
 // Vec4<int>
 
-template <>
+template <> 
+IMATH_EXPORT
 int
 Vec4<int>::length () const
 {
@@ -481,6 +518,7 @@ Vec4<int>::length () const
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<int> &
 Vec4<int>::normalize ()
 {
@@ -489,8 +527,9 @@ Vec4<int>::normalize ()
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<int> &
-Vec4<int>::normalizeExc () throw (Iex::MathExc)
+Vec4<int>::normalizeExc ()
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -500,6 +539,7 @@ Vec4<int>::normalizeExc () throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 const Vec4<int> &
 Vec4<int>::normalizeNonNull ()
 {
@@ -508,6 +548,7 @@ Vec4<int>::normalizeNonNull ()
 }
 
 template <>
+IMATH_EXPORT
 Vec4<int>
 Vec4<int>::normalized () const
 {
@@ -517,8 +558,9 @@ Vec4<int>::normalized () const
 }
 
 template <>
+IMATH_EXPORT
 Vec4<int>
-Vec4<int>::normalizedExc () const throw (Iex::MathExc)
+Vec4<int>::normalizedExc () const
 {
     if ((x == 0) && (y == 0) && (z == 0) && (w == 0))
         throw NullVecExc ("Cannot normalize null vector.");
@@ -529,6 +571,7 @@ Vec4<int>::normalizedExc () const throw (Iex::MathExc)
 }
 
 template <>
+IMATH_EXPORT
 Vec4<int>
 Vec4<int>::normalizedNonNull () const
 {
@@ -537,4 +580,4 @@ Vec4<int>::normalizedNonNull () const
     return v;
 }
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT
index d8c044f..6f4e82a 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -46,6 +46,7 @@
 #include "ImathExc.h"
 #include "ImathLimits.h"
 #include "ImathMath.h"
+#include "ImathNamespace.h"
 
 #include <iostream>
 
@@ -56,7 +57,7 @@
 #endif
 
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 template <class T> class Vec2;
 template <class T> class Vec3;
@@ -117,7 +118,7 @@ template <class T> class Vec2
     T *                        getValue ();
     const T *          getValue () const;
 
-
+    
     //---------
     // Equality
     //---------
@@ -224,11 +225,11 @@ template <class T> class Vec2
     T                  length2 () const;
 
     const Vec2 &       normalize ();           // modifies *this
-    const Vec2 &       normalizeExc () throw (Iex::MathExc);
+    const Vec2 &       normalizeExc ();
     const Vec2 &       normalizeNonNull ();
 
     Vec2<T>            normalized () const;    // does not modify *this
-    Vec2<T>            normalizedExc () const throw (Iex::MathExc);
+    Vec2<T>            normalizedExc () const;
     Vec2<T>            normalizedNonNull () const;
 
 
@@ -251,7 +252,7 @@ template <class T> class Vec2
 
     //--------------------------------------------------------------
     // Base type -- in templates, which accept a parameter, V, which
-    // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
+    // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 
     // refer to T as V::BaseType
     //--------------------------------------------------------------
 
@@ -436,11 +437,11 @@ template <class T> class Vec3
     T                  length2 () const;
 
     const Vec3 &       normalize ();           // modifies *this
-    const Vec3 &       normalizeExc () throw (Iex::MathExc);
+    const Vec3 &       normalizeExc ();
     const Vec3 &       normalizeNonNull ();
 
     Vec3<T>            normalized () const;    // does not modify *this
-    Vec3<T>            normalizedExc () const throw (Iex::MathExc);
+    Vec3<T>            normalizedExc () const;
     Vec3<T>            normalizedNonNull () const;
 
 
@@ -463,7 +464,7 @@ template <class T> class Vec3
 
     //--------------------------------------------------------------
     // Base type -- in templates, which accept a parameter, V, which
-    // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
+    // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 
     // refer to T as V::BaseType
     //--------------------------------------------------------------
 
@@ -484,7 +485,7 @@ template <class T> class Vec4
     // Access to elements
     //-------------------
 
-    T               x, y, z, w;
+    T               x, y, z, w; 
 
     T &             operator [] (int i);
     const T &       operator [] (int i) const;
@@ -618,11 +619,11 @@ template <class T> class Vec4
     T               length2 () const;
 
     const Vec4 &    normalize ();           // modifies *this
-    const Vec4 &    normalizeExc () throw (Iex::MathExc);
+    const Vec4 &    normalizeExc ();
     const Vec4 &    normalizeNonNull ();
 
     Vec4<T>         normalized () const;       // does not modify *this
-    Vec4<T>         normalizedExc () const throw (Iex::MathExc);
+    Vec4<T>         normalizedExc () const;
     Vec4<T>         normalizedNonNull () const;
 
 
@@ -645,7 +646,7 @@ template <class T> class Vec4
 
     //--------------------------------------------------------------
     // Base type -- in templates, which accept a parameter, V, which
-    // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can
+    // could be either a Vec2<T>, a Vec3<T>, or a Vec4<T> you can 
     // refer to T as V::BaseType
     //--------------------------------------------------------------
 
@@ -710,7 +711,7 @@ template <> const Vec2<short> &
 Vec2<short>::normalize ();
 
 template <> const Vec2<short> &
-Vec2<short>::normalizeExc () throw (Iex::MathExc);
+Vec2<short>::normalizeExc ();
 
 template <> const Vec2<short> &
 Vec2<short>::normalizeNonNull ();
@@ -719,7 +720,7 @@ template <> Vec2<short>
 Vec2<short>::normalized () const;
 
 template <> Vec2<short>
-Vec2<short>::normalizedExc () const throw (Iex::MathExc);
+Vec2<short>::normalizedExc () const;
 
 template <> Vec2<short>
 Vec2<short>::normalizedNonNull () const;
@@ -734,7 +735,7 @@ template <> const Vec2<int> &
 Vec2<int>::normalize ();
 
 template <> const Vec2<int> &
-Vec2<int>::normalizeExc () throw (Iex::MathExc);
+Vec2<int>::normalizeExc ();
 
 template <> const Vec2<int> &
 Vec2<int>::normalizeNonNull ();
@@ -743,7 +744,7 @@ template <> Vec2<int>
 Vec2<int>::normalized () const;
 
 template <> Vec2<int>
-Vec2<int>::normalizedExc () const throw (Iex::MathExc);
+Vec2<int>::normalizedExc () const;
 
 template <> Vec2<int>
 Vec2<int>::normalizedNonNull () const;
@@ -758,7 +759,7 @@ template <> const Vec3<short> &
 Vec3<short>::normalize ();
 
 template <> const Vec3<short> &
-Vec3<short>::normalizeExc () throw (Iex::MathExc);
+Vec3<short>::normalizeExc ();
 
 template <> const Vec3<short> &
 Vec3<short>::normalizeNonNull ();
@@ -767,7 +768,7 @@ template <> Vec3<short>
 Vec3<short>::normalized () const;
 
 template <> Vec3<short>
-Vec3<short>::normalizedExc () const throw (Iex::MathExc);
+Vec3<short>::normalizedExc () const;
 
 template <> Vec3<short>
 Vec3<short>::normalizedNonNull () const;
@@ -782,7 +783,7 @@ template <> const Vec3<int> &
 Vec3<int>::normalize ();
 
 template <> const Vec3<int> &
-Vec3<int>::normalizeExc () throw (Iex::MathExc);
+Vec3<int>::normalizeExc ();
 
 template <> const Vec3<int> &
 Vec3<int>::normalizeNonNull ();
@@ -791,7 +792,7 @@ template <> Vec3<int>
 Vec3<int>::normalized () const;
 
 template <> Vec3<int>
-Vec3<int>::normalizedExc () const throw (Iex::MathExc);
+Vec3<int>::normalizedExc () const;
 
 template <> Vec3<int>
 Vec3<int>::normalizedNonNull () const;
@@ -805,7 +806,7 @@ template <> const Vec4<short> &
 Vec4<short>::normalize ();
 
 template <> const Vec4<short> &
-Vec4<short>::normalizeExc () throw (Iex::MathExc);
+Vec4<short>::normalizeExc ();
 
 template <> const Vec4<short> &
 Vec4<short>::normalizeNonNull ();
@@ -814,7 +815,7 @@ template <> Vec4<short>
 Vec4<short>::normalized () const;
 
 template <> Vec4<short>
-Vec4<short>::normalizedExc () const throw (Iex::MathExc);
+Vec4<short>::normalizedExc () const;
 
 template <> Vec4<short>
 Vec4<short>::normalizedNonNull () const;
@@ -829,7 +830,7 @@ template <> const Vec4<int> &
 Vec4<int>::normalize ();
 
 template <> const Vec4<int> &
-Vec4<int>::normalizeExc () throw (Iex::MathExc);
+Vec4<int>::normalizeExc ();
 
 template <> const Vec4<int> &
 Vec4<int>::normalizeNonNull ();
@@ -838,7 +839,7 @@ template <> Vec4<int>
 Vec4<int>::normalized () const;
 
 template <> Vec4<int>
-Vec4<int>::normalizedExc () const throw (Iex::MathExc);
+Vec4<int>::normalizedExc () const;
 
 template <> Vec4<int>
 Vec4<int>::normalizedNonNull () const;
@@ -981,8 +982,8 @@ bool
 Vec2<T>::equalWithAbsError (const Vec2<T> &v, T e) const
 {
     for (int i = 0; i < 2; i++)
-    if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
-        return false;
+       if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
+           return false;
 
     return true;
 }
@@ -992,8 +993,8 @@ bool
 Vec2<T>::equalWithRelError (const Vec2<T> &v, T e) const
 {
     for (int i = 0; i < 2; i++)
-    if (!Imath::equalWithRelError ((*this)[i], v[i], e))
-        return false;
+       if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
+           return false;
 
     return true;
 }
@@ -1145,14 +1146,14 @@ Vec2<T>::lengthTiny () const
 {
     T absX = (x >= T (0))? x: -x;
     T absY = (y >= T (0))? y: -y;
-
+    
     T max = absX;
 
     if (max < absY)
-    max = absY;
+       max = absY;
 
     if (max == T (0))
-    return T (0);
+       return T (0);
 
     //
     // Do not replace the divisions by max with multiplications by 1/max.
@@ -1173,7 +1174,7 @@ Vec2<T>::length () const
     T length2 = dot (*this);
 
     if (length2 < T (2) * limits<T>::smallest())
-    return lengthTiny();
+       return lengthTiny();
 
     return Math<T>::sqrt (length2);
 }
@@ -1199,8 +1200,8 @@ Vec2<T>::normalize ()
         // produce results less than or equal to 1.
         //
 
-    x /= l;
-    y /= l;
+       x /= l;
+       y /= l;
     }
 
     return *this;
@@ -1208,12 +1209,12 @@ Vec2<T>::normalize ()
 
 template <class T>
 const Vec2<T> &
-Vec2<T>::normalizeExc () throw (Iex::MathExc)
+Vec2<T>::normalizeExc ()
 {
     T l = length();
 
     if (l == T (0))
-    throw NullVecExc ("Cannot normalize null vector.");
+       throw NullVecExc ("Cannot normalize null vector.");
 
     x /= l;
     y /= l;
@@ -1238,19 +1239,19 @@ Vec2<T>::normalized () const
     T l = length();
 
     if (l == T (0))
-    return Vec2 (T (0));
+       return Vec2 (T (0));
 
     return Vec2 (x / l, y / l);
 }
 
 template <class T>
 Vec2<T>
-Vec2<T>::normalizedExc () const throw (Iex::MathExc)
+Vec2<T>::normalizedExc () const
 {
     T l = length();
 
     if (l == T (0))
-    throw NullVecExc ("Cannot normalize null vector.");
+       throw NullVecExc ("Cannot normalize null vector.");
 
     return Vec2 (x / l, y / l);
 }
@@ -1359,7 +1360,7 @@ Vec3<T>::Vec3 (const Vec4<S> &v, InfException)
     if (absW < 1)
     {
         T m = baseTypeMax() * absW;
-
+        
         if (vx <= -m || vx >= m || vy <= -m || vy >= m || vz <= -m || vz >= m)
             throw InfPointExc ("Cannot normalize point at infinity.");
     }
@@ -1444,8 +1445,8 @@ bool
 Vec3<T>::equalWithAbsError (const Vec3<T> &v, T e) const
 {
     for (int i = 0; i < 3; i++)
-    if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
-        return false;
+       if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
+           return false;
 
     return true;
 }
@@ -1455,8 +1456,8 @@ bool
 Vec3<T>::equalWithRelError (const Vec3<T> &v, T e) const
 {
     for (int i = 0; i < 3; i++)
-    if (!Imath::equalWithRelError ((*this)[i], v[i], e))
-        return false;
+       if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
+           return false;
 
     return true;
 }
@@ -1480,8 +1481,8 @@ inline Vec3<T>
 Vec3<T>::cross (const Vec3 &v) const
 {
     return Vec3 (y * v.z - z * v.y,
-         z * v.x - x * v.z,
-         x * v.y - y * v.x);
+                z * v.x - x * v.z,
+                x * v.y - y * v.x);
 }
 
 template <class T>
@@ -1502,8 +1503,8 @@ inline Vec3<T>
 Vec3<T>::operator % (const Vec3 &v) const
 {
     return Vec3 (y * v.z - z * v.y,
-         z * v.x - x * v.z,
-         x * v.y - y * v.x);
+                z * v.x - x * v.z,
+                x * v.y - y * v.x);
 }
 
 template <class T>
@@ -1632,17 +1633,17 @@ Vec3<T>::lengthTiny () const
     T absX = (x >= T (0))? x: -x;
     T absY = (y >= T (0))? y: -y;
     T absZ = (z >= T (0))? z: -z;
-
+    
     T max = absX;
 
     if (max < absY)
-    max = absY;
+       max = absY;
 
     if (max < absZ)
-    max = absZ;
+       max = absZ;
 
     if (max == T (0))
-    return T (0);
+       return T (0);
 
     //
     // Do not replace the divisions by max with multiplications by 1/max.
@@ -1664,7 +1665,7 @@ Vec3<T>::length () const
     T length2 = dot (*this);
 
     if (length2 < T (2) * limits<T>::smallest())
-    return lengthTiny();
+       return lengthTiny();
 
     return Math<T>::sqrt (length2);
 }
@@ -1690,9 +1691,9 @@ Vec3<T>::normalize ()
         // produce results less than or equal to 1.
         //
 
-    x /= l;
-    y /= l;
-    z /= l;
+       x /= l;
+       y /= l;
+       z /= l;
     }
 
     return *this;
@@ -1700,12 +1701,12 @@ Vec3<T>::normalize ()
 
 template <class T>
 const Vec3<T> &
-Vec3<T>::normalizeExc () throw (Iex::MathExc)
+Vec3<T>::normalizeExc ()
 {
     T l = length();
 
     if (l == T (0))
-    throw NullVecExc ("Cannot normalize null vector.");
+       throw NullVecExc ("Cannot normalize null vector.");
 
     x /= l;
     y /= l;
@@ -1732,19 +1733,19 @@ Vec3<T>::normalized () const
     T l = length();
 
     if (l == T (0))
-    return Vec3 (T (0));
+       return Vec3 (T (0));
 
     return Vec3 (x / l, y / l, z / l);
 }
 
 template <class T>
 Vec3<T>
-Vec3<T>::normalizedExc () const throw (Iex::MathExc)
+Vec3<T>::normalizedExc () const
 {
     T l = length();
 
     if (l == T (0))
-    throw NullVecExc ("Cannot normalize null vector.");
+       throw NullVecExc ("Cannot normalize null vector.");
 
     return Vec3 (x / l, y / l, z / l);
 }
@@ -1865,7 +1866,7 @@ bool
 Vec4<T>::equalWithAbsError (const Vec4<T> &v, T e) const
 {
     for (int i = 0; i < 4; i++)
-        if (!Imath::equalWithAbsError ((*this)[i], v[i], e))
+        if (!IMATH_INTERNAL_NAMESPACE::equalWithAbsError ((*this)[i], v[i], e))
             return false;
 
     return true;
@@ -1876,7 +1877,7 @@ bool
 Vec4<T>::equalWithRelError (const Vec4<T> &v, T e) const
 {
     for (int i = 0; i < 4; i++)
-        if (!Imath::equalWithRelError ((*this)[i], v[i], e))
+        if (!IMATH_INTERNAL_NAMESPACE::equalWithRelError ((*this)[i], v[i], e))
             return false;
 
     return true;
@@ -2031,7 +2032,7 @@ Vec4<T>::lengthTiny () const
     T absY = (y >= T (0))? y: -y;
     T absZ = (z >= T (0))? z: -z;
     T absW = (w >= T (0))? w: -w;
-
+    
     T max = absX;
 
     if (max < absY)
@@ -2105,7 +2106,7 @@ Vec4<T>::normalize ()
 
 template <class T>
 const Vec4<T> &
-Vec4<T>::normalizeExc () throw (Iex::MathExc)
+Vec4<T>::normalizeExc ()
 {
     T l = length();
 
@@ -2146,7 +2147,7 @@ Vec4<T>::normalized () const
 
 template <class T>
 Vec4<T>
-Vec4<T>::normalizedExc () const throw (Iex::MathExc)
+Vec4<T>::normalizedExc () const
 {
     T l = length();
 
@@ -2221,6 +2222,6 @@ operator * (T a, const Vec4<T> &v)
 #pragma warning(pop)
 #endif
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHVEC_H
index 9b92d3f..28bab6b 100644 (file)
@@ -1,10 +1,10 @@
 ///////////////////////////////////////////////////////////////////////////
 //
-// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
 // Digital Ltd. LLC
-//
+// 
 // All rights reserved.
-//
+// 
 // Redistribution and use in source and binary forms, with or without
 // modification, are permitted provided that the following conditions are
 // met:
@@ -16,8 +16,8 @@
 // distribution.
 // *       Neither the name of Industrial Light & Magic nor the names of
 // its contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
+// from this software without specific prior written permission. 
+// 
 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
@@ -49,8 +49,9 @@
 
 #include "ImathVec.h"
 #include "ImathLimits.h"
+#include "ImathNamespace.h"
 
-namespace Imath {
+IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
 
 
 //-----------------------------------------------------------------
@@ -83,7 +84,7 @@ template <class Vec> Vec        reflect (const Vec &s, const Vec &t);
 
 template <class Vec> Vec        closestVertex (const Vec &v0,
                                                const Vec &v1,
-                                               const Vec &v2,
+                                               const Vec &v2, 
                                                const Vec &p);
 
 //---------------
@@ -116,7 +117,7 @@ template <class Vec>
 Vec
 closestVertex(const Vec &v0,
               const Vec &v1,
-              const Vec &v2,
+              const Vec &v2, 
               const Vec &p)
 {
     Vec nearest = v0;
@@ -141,6 +142,6 @@ closestVertex(const Vec &v0,
 }
 
 
-} // namespace Imath
+IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
 
-#endif
+#endif // INCLUDED_IMATHVECALGO_H
index 0a6b592..33b2cc9 100644 (file)
@@ -5,14 +5,14 @@
 // used by any OpenEXR library or application code.
 //
 
-#undef HAVE_LINUX_PROCFS
+#cmakedefine OPENEXR_IMF_HAVE_LINUX_PROCFS
 
 //
 // Define and set to 1 if the target system is a Darwin-based system
 // (e.g., OS X).
 //
 
-#undef HAVE_DARWIN
+#cmakedefine OPENEXR_IMF_HAVE_DARWIN
 
 //
 // Define and set to 1 if the target system has a complete <iomanip>
 // formatter.
 //
 
-#undef HAVE_COMPLETE_IOMANIP
+#cmakedefine OPENEXR_IMF_HAVE_COMPLETE_IOMANIP
 
 //
 // Define and set to 1 if the target system has support for large
 // stack sizes.
 //
 
-#undef HAVE_LARGE_STACK
+#cmakedefine OPENEXR_IMF_HAVE_LARGE_STACK
+
+//
+// Define if we can support GCC style inline asm with AVX instructions
+//
+
+#cmakedefine OPENEXR_IMF_HAVE_GCC_INLINE_ASM_AVX
+
+//
+// Define if we can use sysconf(_SC_NPROCESSORS_ONLN) to get CPU count
+//
+
+#cmakedefine OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN
+
+//
+// Current internal library namepace name
+//
+#define OPENEXR_IMF_INTERNAL_NAMESPACE_CUSTOM @OPENEXR_IMF_INTERNAL_NAMESPACE_CUSTOM@
+#define OPENEXR_IMF_INTERNAL_NAMESPACE @OPENEXR_IMF_INTERNAL_NAMESPACE@
+
+//
+// Current public user namepace name
+//
+
+#define OPENEXR_IMF_NAMESPACE_CUSTOM @OPENEXR_IMF_NAMESPACE_CUSTOM@
+#define OPENEXR_IMF_NAMESPACE @OPENEXR_IMF_NAMESPACE@
 
 //
 // Version string for runtime access
 //
-#define OPENEXR_VERSION_STRING "1.7.1"
-#define OPENEXR_PACKAGE_STRING "OpenEXR 1.7.1"
+
+#define OPENEXR_VERSION_STRING @OPENEXR_VERSION_STRING@
+#define OPENEXR_PACKAGE_STRING @OPENEXR_PACKAGE_STRING@
+
+#define OPENEXR_VERSION_MAJOR @OPENEXR_VERSION_MAJOR@
+#define OPENEXR_VERSION_MINOR @OPENEXR_VERSION_MINOR@
+#define OPENEXR_VERSION_PATCH @OPENEXR_VERSION_PATCH@
+
+// Version as a single hex number, e.g. 0x01000300 == 1.0.3
+#define OPENEXR_VERSION_HEX ((OPENEXR_VERSION_MAJOR << 24) | \
+                             (OPENEXR_VERSION_MINOR << 16) | \
+                             (OPENEXR_VERSION_PATCH <<  8))
+
diff --git a/3rdparty/openexr/fix_msvc2013_errors.patch b/3rdparty/openexr/fix_msvc2013_errors.patch
deleted file mode 100644 (file)
index 0ce106f..0000000
+++ /dev/null
@@ -1,72 +0,0 @@
-diff --git a/3rdparty/openexr/IlmImf/ImfAcesFile.cpp b/3rdparty/openexr/IlmImf/ImfAcesFile.cpp
-index de4bf83..9418b9d 100644
---- a/3rdparty/openexr/IlmImf/ImfAcesFile.cpp
-+++ b/3rdparty/openexr/IlmImf/ImfAcesFile.cpp
-@@ -42,6 +42,7 @@
- #include <ImfRgbaFile.h>
- #include <ImfStandardAttributes.h>
- #include <Iex.h>
-+#include <algorithm> // for std::max()
- using namespace std;
- using namespace Imath;
-diff --git a/3rdparty/openexr/IlmImf/ImfOutputFile.cpp b/3rdparty/openexr/IlmImf/ImfOutputFile.cpp
-index 8831ec9..e69b92b 100644
---- a/3rdparty/openexr/IlmImf/ImfOutputFile.cpp
-+++ b/3rdparty/openexr/IlmImf/ImfOutputFile.cpp
-@@ -58,6 +58,7 @@
- #include <vector>
- #include <fstream>
- #include <assert.h>
-+#include <algorithm> // for std::max()
- namespace Imf {
-diff --git a/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp b/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp
-index f7a12a3..5d8b522 100644
---- a/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp
-+++ b/3rdparty/openexr/IlmImf/ImfScanLineInputFile.cpp
-@@ -56,6 +56,7 @@
- #include <string>
- #include <vector>
- #include <assert.h>
-+#include <algorithm> // for std::max()
- namespace Imf {
-diff --git a/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp b/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp
-index 57f52f1..9588e78 100644
---- a/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp
-+++ b/3rdparty/openexr/IlmImf/ImfTiledMisc.cpp
-@@ -43,6 +43,7 @@
- #include "Iex.h"
- #include <ImfMisc.h>
- #include <ImfChannelList.h>
-+#include <algorithm> // for std::max()
- namespace Imf {
-diff --git a/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp b/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp
-index 0882106..0bc3cb3 100644
---- a/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp
-+++ b/3rdparty/openexr/IlmImf/ImfTiledOutputFile.cpp
-@@ -63,6 +63,7 @@
- #include <fstream>
- #include <assert.h>
- #include <map>
-+#include <algorithm> // for std::max()
- namespace Imf {
-diff --git a/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp b/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp
-index f0d2ed6..7ddc649 100644
---- a/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp
-+++ b/3rdparty/openexr/Imath/ImathMatrixAlgo.cpp
-@@ -44,6 +44,7 @@
- #include "ImathMatrixAlgo.h"
- #include <cmath>
-+#include <algorithm> // for std::max()
- #if defined(OPENEXR_DLL)
-     #define EXPORT_CONST __declspec(dllexport)
index eb46b30..9f051d0 100644 (file)
@@ -294,8 +294,8 @@ OCV_OPTION(WITH_JPEG "Include JPEG support" ON
 OCV_OPTION(WITH_WEBP "Include WebP support" ON
   VISIBLE_IF NOT WINRT
   VERIFY HAVE_WEBP)
-OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" ON
-  VISIBLE_IF NOT IOS AND NOT WINRT
+OCV_OPTION(WITH_OPENEXR "Include ILM support via OpenEXR" BUILD_OPENEXR OR NOT CMAKE_CROSSCOMPILING
+  VISIBLE_IF NOT APPLE_FRAMEWORK AND NOT WINRT
   VERIFY HAVE_OPENEXR)
 OCV_OPTION(WITH_OPENGL "Include OpenGL support" OFF
   VISIBLE_IF NOT ANDROID AND NOT WINRT
@@ -1381,7 +1381,11 @@ if(WITH_JASPER OR HAVE_JASPER)
 endif()
 
 if(WITH_OPENEXR OR HAVE_OPENEXR)
-  status("    OpenEXR:" OPENEXR_FOUND THEN "${OPENEXR_LIBRARIES} (ver ${OPENEXR_VERSION})" ELSE "build (ver ${OPENEXR_VERSION})")
+  if(HAVE_OPENEXR)
+    status("    OpenEXR:" OPENEXR_FOUND THEN "${OPENEXR_LIBRARIES} (ver ${OPENEXR_VERSION})" ELSE "build (ver ${OPENEXR_VERSION})")
+  else()
+    status("    OpenEXR:" "NO")
+  endif()
 endif()
 
 if(WITH_GDAL OR HAVE_GDAL)
index 9f18e2b..fcf716b 100644 (file)
@@ -211,21 +211,22 @@ endif()
 
 # --- OpenEXR (optional) ---
 if(WITH_OPENEXR)
-  if(BUILD_OPENEXR)
-    ocv_clear_vars(OPENEXR_FOUND)
-  else()
+  ocv_clear_vars(HAVE_OPENEXR)
+  if(NOT BUILD_OPENEXR)
     include("${OpenCV_SOURCE_DIR}/cmake/OpenCVFindOpenEXR.cmake")
   endif()
 
-  if(NOT OPENEXR_FOUND)
+  if(OPENEXR_FOUND)
+    set(HAVE_OPENEXR YES)
+  else()
     ocv_clear_vars(OPENEXR_INCLUDE_PATHS OPENEXR_LIBRARIES OPENEXR_ILMIMF_LIBRARY OPENEXR_VERSION)
 
     set(OPENEXR_LIBRARIES IlmImf)
-    set(OPENEXR_ILMIMF_LIBRARY IlmImf)
     add_subdirectory("${OpenCV_SOURCE_DIR}/3rdparty/openexr")
+    if(OPENEXR_VERSION)  # check via TARGET doesn't work
+      set(HAVE_OPENEXR YES)
+    endif()
   endif()
-
-  set(HAVE_OPENEXR YES)
 endif()
 
 # --- GDAL (optional) ---