Disabled external gits

This commit is contained in:
2022-04-07 18:46:57 +02:00
parent 88cb3426ad
commit 15e7120d6d
5316 changed files with 4563444 additions and 6 deletions

45
cs440-acg/ext/openexr/.gitignore vendored Normal file
View File

@@ -0,0 +1,45 @@
Makefile.in
autom4te.cache
aclocal.m4
config.guess
config.sub
configure
depcomp
install-sh
ltmain.sh
missing
.deps
*.o
*.lo
*.deps
*.libs
*.Plo
*.Po
*.la
*.so
*.dylib
.DS_Store
*.project
*.cproject
CMakeFiles
*.cmake
Makefile
*.a
/IlmBase/Half/eLut
/IlmBase/Half/eLut.h
/IlmBase/Half/toFloat
/IlmBase/Half/toFloat.h
/OpenEXR/IlmImf/b44ExpLogTable.h
/OpenEXR/IlmImf/dwaLookups.h
*.filters
*.vcxproj
*.dir
*.sln
Release
Debug
x64
build
.ninja_deps
.ninja_log
build.ninja
rules.ninja

3
cs440-acg/ext/openexr/.gitmodules vendored Normal file
View File

@@ -0,0 +1,3 @@
[submodule "zlib"]
path = zlib
url = https://github.com/mitsuba-renderer/zlib

View File

@@ -0,0 +1,43 @@
cmake_minimum_required (VERSION 3.13..3.18)
project(openexr)
SET (OPENEXR_INSTALL_HEADER_DEST "include/OpenEXR" CACHE STRING "")
SET (OPENEXR_INSTALL_LIB_DEST "lib" CACHE STRING "")
# Set a default build configuration (Release)
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Release' as none was specified.")
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
"MinSizeRel" "RelWithDebInfo")
endif()
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-switch -Wno-tautological-compare -Wno-deprecated-register")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-result -Wno-deprecated")
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4275 /wd4267 /wd4244 /wd4477 /wd4996 /wd4800 /wd4334 /wd4251 /wd4305 /wd4302 /wd4311 /wd4018")
endif()
if (WIN32 AND NOT TARGET zlib)
# Build zlib (only on Windows)
set(ZLIB_BUILD_STATIC_LIBS OFF CACHE BOOL " " FORCE)
set(ZLIB_BUILD_SHARED_LIBS ON CACHE BOOL " " FORCE)
add_subdirectory(zlib)
set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zlib;${CMAKE_CURRENT_BINARY_DIR}/zlib" CACHE PATH " " FORCE)
set(ZLIB_LIBRARIES zlib CACHE FILEPATH " " FORCE)
else()
endif()
add_subdirectory(IlmBase)
include_directories(
IlmBase/Iex
IlmBase/Imath
IlmBase/IlmThread
IlmBase/Half
${CMAKE_CURRENT_BINARY_DIR}/IlmBase/config
)
add_subdirectory(OpenEXR)

View File

@@ -0,0 +1,7 @@
Developers:
-----------
Christopher Horvath <encino@pixar.com>

View File

@@ -0,0 +1,60 @@
##-*****************************************************************************
## Copyright (c) 2012, Pixar. All rights reserved. *
## *
## This license governs use of the accompanying software. If you *
## use the software, you accept this license. If you do not accept *
## the license, do not use the software. *
## *
## 1. Definitions *
## The terms "reproduce," "reproduction," "derivative works," and *
## "distribution" have the same meaning here as under U.S. *
## copyright law. A "contribution" is the original software, or *
## any additions or changes to the software. *
## A "contributor" is any person or entity that distributes its *
## contribution under this license. *
## "Licensed patents" are a contributor's patent claims that read *
## directly on its contribution. *
## *
## 2. Grant of Rights *
## (A) Copyright Grant- Subject to the terms of this license, *
## including the license conditions and limitations in section 3, *
## each contributor grants you a non-exclusive, worldwide, *
## royalty-free copyright license to reproduce its contribution, *
## prepare derivative works of its contribution, and distribute *
## its contribution or any derivative works that you create. *
## (B) Patent Grant- Subject to the terms of this license, *
## including the license conditions and limitations in section 3, *
## each contributor grants you a non-exclusive, worldwide, *
## royalty-free license under its licensed patents to make, have *
## made, use, sell, offer for sale, import, and/or otherwise *
## dispose of its contribution in the software or derivative works *
## of the contribution in the software. *
## *
## 3. Conditions and Limitations *
## (A) No Trademark License- This license does not grant you *
## rights to use any contributor's name, logo, or trademarks. *
## (B) If you bring a patent claim against any contributor over *
## patents that you claim are infringed by the software, your *
## patent license from such contributor to the software ends *
## automatically. *
## (C) If you distribute any portion of the software, you must *
## retain all copyright, patent, trademark, and attribution *
## notices that are present in the software. *
## (D) If you distribute any portion of the software in source *
## code form, you may do so only under this license by including a *
## complete copy of this license with your distribution. If you *
## distribute any portion of the software in compiled or object *
## code form, you may only do so under a license that complies *
## with this license. *
## (E) The software is licensed "as-is." You bear the risk of *
## using it. The contributors give no express warranties, *
## guarantees or conditions. You may have additional consumer *
## rights under your local laws which this license cannot change. *
## To the extent permitted under your local laws, the contributors *
## exclude the implied warranties of merchantability, fitness for *
## a particular purpose and non-infringement. *
##-*****************************************************************************
##-*****************************************************************************
## Written by Pixar, 2011-2012.
##-*****************************************************************************

View File

@@ -0,0 +1,13 @@
Version 1.0.0:
* Initial release of this code.
Version 1.0.1:
* Fixed misinterpretation of values read from "deepopacity" dtex files.
The data stored is actually transmission, or 1.0-opacity, which means
that "deepopacity" dtex values actually monotonically decrease from 1
to 0. We have updated the comments and documentation to reflect this
and have fixed the PxOneChanDeepOpacity file to convert the data
as it is read out of the file.

View File

@@ -0,0 +1,611 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar, 2011-2012.
//-*****************************************************************************
#include "PxDeepUtils.h"
#include "PxDeepOutPixel.h"
#include "PxDeepOutRow.h"
#include "PxBaseDeepHelper.h"
#include "PxOneChanDeepOpacity.h"
#include "PxOneChanDeepAlpha.h"
#include "PxFourChanDeepRgba.h"
#include <dtex.h>
#include <ImfDeepScanLineOutputFile.h>
#include <ImfPartType.h>
#include <ImfChannelList.h>
#include <ImfStandardAttributes.h>
#include <ImfHeader.h>
#include <ImathVec.h>
#include <ImathBox.h>
#include <ImathMatrix.h>
#include <half.h>
#include <assert.h>
#include <iostream>
#include <vector>
#include <utility>
#include <algorithm>
#include <math.h>
#include <float.h>
//-*****************************************************************************
// DTEX CONVERTER EXPLANATION!
//-*****************************************************************************
// There are six possible code paths through converting the dtex data. They are:
// DeepOpacity, Continuous
// DeepOpacity, Discrete
// DeepAlpha, Continuous
// DeepAlpha, Discrete
// DeepRGBA, Continuous
// DeepRGBA, Discrete
// The newer dtex usages allow for other combinations of channels, but we
// are temporarily just supporting these six paths for sake of simplicity.
// We will eventually support arbitrary outputs and multiple views.
//
// We had an earlier version of this code which condensed these six code
// pathways into a single function, with templated functors to provide
// specific differing behavior for each of the different possibilities, and
// while it may have been slightly less code, the resulting loops were very hard
// to read and understand. Because each of the different pathways
// has some specific kernel of knowledge necessary to make it work, we
// chose instead to break each one out separately, to clearly expose the
// behavior in each case.
//
// The terminology for Density, Visibility, DeepOpacity, DepthRanges,
// along with explanations of the constants are provided in
// PxDeepUtils.h
//
// Our DeepOutPixel helper class is in PxDeepOutPixel.h
//
// Our DeepOutRow helper class is in PxDeepOutRow.h
//
// The Base Helper class, which loops over rows, and then pixels of those
// rows, is in PxBaseDeepHelper.h
//
// The DeepOpacity subclasses (discrete/continuous) of BaseDeepHelper are in
// PxOneChanDeepOpacity.h
//
// The DeepAlpha subclasses (discrete/continuous) of BaseDeepHelper are in
// PxOneChanDeepAlpha.h
//
// The DeepRgba subclasses (discrete/continuous) of BaseDeepHelper are in
// PxFourChanDeepAlpha.h
//
//-*****************************************************************************
namespace PxDeep {
//-*****************************************************************************
template <typename RGBA_T>
void ConvertDtexFile( const std::string& i_fileName,
const std::string& i_outFileName,
const Parameters& i_params )
{
int dtexOpenError = DTEX_NOERR;
DtexFile* dtexFile = NULL;
DtexCache* dtexCache = NULL;
if ( i_fileName.length() )
{
// We probably don't need 10000 tiles in the cache, but it's
// fine for now.
dtexCache = DtexCreateCache( 10000, NULL );
dtexOpenError = DtexOpenFile( i_fileName.c_str(),
"rb", dtexCache, &dtexFile );
}
if ( !dtexFile )
{
if ( i_fileName.length() == 0 )
{
PXDU_THROW( "no filename specified" );
}
else if ( dtexOpenError != DTEX_NOERR )
{
PXDU_THROW( "error (" << dtexOpenError
<< " opening file: " << i_fileName );
}
else
{
PXDU_THROW( "missing file: " << i_fileName );
}
}
// Just handling the first image in the Dtex file for now.
DtexImage* image;
DtexGetImageByIndex( dtexFile, 0, &image );
float NP[16];
DtexNP( image, NP );
float Nl[16];
DtexNl( image, Nl );
int numDtexChans = DtexNumChan( image );
if ( numDtexChans != 1 &&
numDtexChans != 3 &&
numDtexChans != 4 )
{
DtexClose( dtexFile );
PXDU_THROW( "ERROR: only 1, 3 or 4 channel dtex files are supported.\n"
<< "Dtex file " << i_fileName
<< " contains " << numDtexChans << " channels.\n"
<< "In the case of 3 channels, the data is assumed to be\n"
<< "3-channel opacity, and for now, at least, only the\n"
<< "first channel is used, rather than all three.\n" );
}
int w = DtexWidth( image );
int h = DtexHeight( image );
// Extract the parameters so we can conditionally modify them.
Parameters params = i_params;
// If we're reading anything more than 1 channel,
// we can't (for now) assume it's a deepOpacity signal,
// so we turn off the deepOpacity flag.
// We also make sure RGB is turned on when RGB data is present.
if ( numDtexChans == 4 )
{
params.deepOpacity = false;
params.doRGB = true;
}
// If we're discrete, we don't necessarily need to output deepBack.
// However, from a pipeline point of view it is often preferable to have
// all the channels actually in existence, even if they're redundant.
// Nonetheless, if
if ( !params.discrete )
{
params.doDeepBack = true;
}
// Determine the output size
int outWidth = w;
int outHeight = h;
if ( params.sideways )
{
outWidth = h;
outHeight = w;
}
// Create the windows.
Imath::Box2i dataWindow( Imath::V2i( 0, 0 ),
Imath::V2i( outWidth-1, outHeight-1 ) );
Imath::Box2i displayWindow = dataWindow;
// Create the header.
Imf::Header header( displayWindow,
dataWindow,
1,
Imath::V2f( 0.0f, 0.0f ),
1,
Imf::INCREASING_Y,
Imf::ZIPS_COMPRESSION );
// Add Np/Nl to the header.
Imath::M44f NPm( NP[0], NP[1], NP[2], NP[3],
NP[4], NP[5], NP[6], NP[7],
NP[8], NP[9], NP[10], NP[11],
NP[12], NP[13], NP[14], NP[15] );
addWorldToNDC( header, NPm );
Imath::M44f Nlm( Nl[0], Nl[1], Nl[2], Nl[3],
Nl[4], Nl[5], Nl[6], Nl[7],
Nl[8], Nl[9], Nl[10], Nl[11],
Nl[12], Nl[13], Nl[14], Nl[15] );
addWorldToCamera( header, Nlm );
// Add channels to the header.
// RGB
if ( params.doRGB )
{
header.channels().insert( "R",
Imf::Channel( ImfPixelType<RGBA_T>() ) );
header.channels().insert( "G",
Imf::Channel( ImfPixelType<RGBA_T>() ) );
header.channels().insert( "B",
Imf::Channel( ImfPixelType<RGBA_T>() ) );
}
// A
header.channels().insert( "A",
Imf::Channel( ImfPixelType<RGBA_T>() ) );
// Deep Front (z)
header.channels().insert( "Z",
Imf::Channel( Imf::FLOAT ) );
// Deep Back
if ( params.doDeepBack )
{
header.channels().insert( "ZBack",
Imf::Channel( Imf::FLOAT ) );
}
// Tell header to be deep!
header.setType( Imf::DEEPSCANLINE );
// Create output file, and fill it up!
{
Imf::DeepScanLineOutputFile outputFile( i_outFileName.c_str(),
header );
// Process deep pixels.
if ( numDtexChans < 4 )
{
if ( params.discrete )
{
if ( params.deepOpacity )
{
OneChanDeepOpacityDiscrete<RGBA_T> op( dtexFile,
numDtexChans,
params );
op.processDeepBox( outputFile, dataWindow );
}
else
{
OneChanDeepAlphaDiscrete<RGBA_T> op( dtexFile,
numDtexChans,
params );
op.processDeepBox( outputFile, dataWindow );
}
}
else
{
if ( params.deepOpacity )
{
OneChanDeepOpacityContinuous<RGBA_T> op( dtexFile,
numDtexChans,
params );
op.processDeepBox( outputFile, dataWindow );
}
else
{
OneChanDeepAlphaContinuous<RGBA_T> op( dtexFile,
numDtexChans,
params );
op.processDeepBox( outputFile, dataWindow );
}
}
}
else
{
if ( params.discrete )
{
FourChanDeepRgbaDiscrete<RGBA_T> op( dtexFile,
numDtexChans,
params );
op.processDeepBox( outputFile, dataWindow );
}
else
{
FourChanDeepRgbaContinuous<RGBA_T> op( dtexFile,
numDtexChans,
params );
op.processDeepBox( outputFile, dataWindow );
}
}
} // Output file has gone out of scope, and should be closed!
std::cout << "Wrote file: " << i_outFileName << std::endl;
// Close it up!
if ( dtexFile )
{
DtexClose( dtexFile );
}
if ( dtexCache )
{
DtexDestroyCache( dtexCache );
}
}
} // End namespace PxDeep
//-*****************************************************************************
// Print Usage.
void PrintUsage( const std::string& i_cmd, std::ostream& ostr )
{
ostr << "DtexToExr: USAGE: "
<< i_cmd
<< std::endl << std::endl
<< "\t <inFileName.dtex>"
<< std::endl << std::endl
<< "\t <outFileName.exr>"
<< std::endl << std::endl
<< "\t --deepOpacity (DEFAULT) "
<< "\n\t\t (corresponds to output channels \'deepopacity\')"
<< std::endl << std::endl
<< "\t --deepAlpha "
<< "\n\t\t (corresponds to output channels \'a\' or \'rgba\')"
<< std::endl << std::endl
<< "\t --discrete (DEFAULT) "
<< "\n\t\t (corresponds to \'volumeinterpretation discrete\')"
<< std::endl << std::endl
<< "\t --continuous "
<< "\n\t\t (corresponds to \'volumeinterpretation continuous\')"
<< std::endl << std::endl
<< "\t --full "
<< "\n\t\t (use full 32-bit precision for non-depth (RGBA) data)"
<< std::endl << std::endl
<< "\t --half (DEFAULT) "
<< "\n\t\t (use half 16-bit precision for non-depth (RGBA) data)"
<< std::endl << std::endl
<< "\t --multRgb "
<< "\n\t\t (multiply RGB data by Alpha, "
<< "implying that source data is unpremultiplied)"
<< std::endl << std::endl
<< "\t --sideways [true|false]"
<< "\n\t\t (rotate image 90 deg clockwise)"
<< std::endl << std::endl
<< "\t --compressionError <float> (DEFAULT: 0.0f) "
<< "\n\t\t (compress dtex data before converting to deep exr)"
<< std::endl << std::endl
<< "\t --keepZeroAlpha "
<< "\n\t\t (don\'t discard samples with zero alpha)"
<< std::endl << std::endl
<< "\t --discardZeroAlpha (DEFAULT) "
<< "\n\t\t (discard samples with zero alpha)"
<< std::endl << std::endl
<< "\t -h,--h,--help "
<< "\n\t\t (print this message and exit)"
<< std::endl << std::endl;
}
//-*****************************************************************************
inline bool GoodFileName( const std::string& i_fileName )
{
return !( ( i_fileName.length() == 0 ||
i_fileName == "" ||
i_fileName[0] == '-' ) );
}
//-*****************************************************************************
// Argument parsing. So inelegant, but libarg is not widely supported, and
// boost::program_options is, well, boost. Also - not particularly awesome.
void ParseArguments( int argc, char* argv[],
bool& o_full,
std::string& o_dtexFileName,
std::string& o_exrFileName,
PxDeep::Parameters& o_params )
{
if ( argc < 3 )
{
PrintUsage( argv[0], std::cerr );
exit( -1 );
}
// Make our params match what the usage string says by default.
o_full = false;
o_dtexFileName = "";
o_exrFileName = "";
o_params.deepOpacity = true;
o_params.discrete = true;
o_params.multiplyColorByAlpha = false;
o_params.sideways = false;
o_params.discardZeroAlphaSamples = true;
o_params.doDeepBack = true;
o_params.doRGB = false;
o_params.compressionError = 0.0f;
// Eat up the args!
for ( int argi = 1; argi < argc; ++argi )
{
std::string arg = argv[argi];
if ( arg == "-h" || arg == "-help" || arg == "--help" )
{
PrintUsage( argv[0], std::cerr );
exit( -1 );
}
else if ( argi == 1 )
{
if ( !GoodFileName( arg ) )
{
PrintUsage( argv[0], std::cerr );
PXDU_THROW( "Bad file name: " << arg );
}
o_dtexFileName = arg;
}
else if ( argi == 2 )
{
if ( !GoodFileName( arg ) )
{
PrintUsage( argv[0], std::cerr );
PXDU_THROW( "Bad file name: " << arg );
}
o_exrFileName = arg;
}
else if ( arg == "--deepOpacity" )
{
o_params.deepOpacity = true;
}
else if ( arg == "--deepAlpha" )
{
o_params.deepOpacity = false;
}
else if ( arg == "--discrete" )
{
o_params.discrete = true;
}
else if ( arg == "--continuous" )
{
o_params.discrete = false;
}
else if ( arg == "--full" )
{
o_full = true;
}
else if ( arg == "--half" )
{
o_full = false;
}
else if ( arg == "--multRgb" )
{
o_params.multiplyColorByAlpha = true;
}
else if ( arg == "--sideways" )
{
if ( argi <= argc-1 )
{
std::cout << argv[argi+1] << std::endl;
if ( strcmp(argv[argi+1], "true") == 0 )
{
o_params.sideways = true;
++argi;
}
else if ( strcmp(argv[argi+1], "false") == 0 )
{
o_params.sideways = false;
++argi;
}
else if ( argv[argi+1][0] == '-' )
{
// found another arg. sideways has no parameter, which means sideways is on.
o_params.sideways = true;
}
else
{
// sideways must be followed by "true", "false", another arg, or nothing.
PXDU_THROW( "Invalid parameter for --sideways: " << argv[argi+1] );
}
}
else
{
o_params.sideways = true;
}
}
else if ( arg == "--compressionError" )
{
if ( argi >= argc-1 )
{
PrintUsage( argv[0], std::cerr );
PXDU_THROW( "Unspecified compression error." );
}
o_params.compressionError = atof( argv[argi+1] );
++argi;
}
else if ( arg == "--keepZeroAlpha" )
{
o_params.discardZeroAlphaSamples = false;
}
else if ( arg == "--discardZeroAlpha" )
{
o_params.discardZeroAlphaSamples = true;
}
else
{
PrintUsage( argv[0], std::cerr );
PXDU_THROW( "Unknown command line argument: " << arg );
}
}
}
//-*****************************************************************************
// MAIN FUNCTION
//-*****************************************************************************
int main( int argc, char *argv[] )
{
try
{
PxDeep::Parameters params;
std::string dtexFileName;
std::string exrFileName;
bool full;
ParseArguments( argc, argv, full,
dtexFileName, exrFileName,
params );
if ( full )
{
PxDeep::ConvertDtexFile<float>( dtexFileName,
exrFileName,
params );
}
else
{
PxDeep::ConvertDtexFile<half>( dtexFileName,
exrFileName,
params );
}
}
catch ( std::exception& exc )
{
std::cerr << "ERROR EXCEPTION: " << exc.what() << std::endl;
exit( -1 );
}
catch ( ... )
{
std::cerr << "UNKNOWN EXCEPTION." << std::endl;
exit( -1 );
}
return 0;
}

View File

@@ -0,0 +1,365 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005,
2006, 2007, 2008, 2009 Free Software Foundation, Inc.
Copying and distribution of this file, with or without modification,
are permitted in any medium without royalty provided the copyright
notice and this notice are preserved. This file is offered as-is,
without warranty of any kind.
Basic Installation
==================
Briefly, the shell commands `./configure; make; make install' should
configure, build, and install this package. The following
more-detailed instructions are generic; see the `README' file for
instructions specific to this package. Some packages provide this
`INSTALL' file but do not implement all of the features documented
below. The lack of an optional feature in a given package is not
necessarily a bug. More recommendations for GNU packages can be found
in *note Makefile Conventions: (standards)Makefile Conventions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. Caching is
disabled by default to prevent problems with accidental use of stale
cache files.
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You need `configure.ac' if
you want to change it or regenerate `configure' using a newer version
of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system.
Running `configure' might take a while. While running, it prints
some messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package, generally using the just-built uninstalled binaries.
4. Type `make install' to install the programs and any data files and
documentation. When installing into a prefix owned by root, it is
recommended that the package be configured and built as a regular
user, and only the `make install' phase executed with root
privileges.
5. Optionally, type `make installcheck' to repeat any self-tests, but
this time using the binaries in their final installed location.
This target does not install anything. Running this target as a
regular user, particularly if the prior `make install' required
root privileges, verifies that the installation completed
correctly.
6. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
7. Often, you can also type `make uninstall' to remove the installed
files again. In practice, not all packages have tested that
uninstallation works correctly, even though it is required by the
GNU Coding Standards.
8. Some packages, particularly those that use Automake, provide `make
distcheck', which can by used by developers to test that all other
targets like `make install' and `make uninstall' work correctly.
This target is generally not run by end users.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. Run `./configure --help'
for details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c99 CFLAGS=-g LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you can use GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. This
is known as a "VPATH" build.
With a non-GNU `make', it is safer to compile the package for one
architecture at a time in the source code directory. After you have
installed the package for one architecture, use `make distclean' before
reconfiguring for another architecture.
On MacOS X 10.5 and later systems, you can create libraries and
executables that work on multiple system types--known as "fat" or
"universal" binaries--by specifying multiple `-arch' options to the
compiler but only a single `-arch' option to the preprocessor. Like
this:
./configure CC="gcc -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CXX="g++ -arch i386 -arch x86_64 -arch ppc -arch ppc64" \
CPP="gcc -E" CXXCPP="g++ -E"
This is not guaranteed to produce working output in all cases, you
may have to build one architecture at a time and combine the results
using the `lipo' tool if you have problems.
Installation Names
==================
By default, `make install' installs the package's commands under
`/usr/local/bin', include files under `/usr/local/include', etc. You
can specify an installation prefix other than `/usr/local' by giving
`configure' the option `--prefix=PREFIX', where PREFIX must be an
absolute file name.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
pass the option `--exec-prefix=PREFIX' to `configure', the package uses
PREFIX as the prefix for installing programs and libraries.
Documentation and other data files still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them. In general, the
default for these options is expressed in terms of `${prefix}', so that
specifying just `--prefix' will affect all of the other directory
specifications that were not explicitly provided.
The most portable way to affect installation locations is to pass the
correct locations to `configure'; however, many packages provide one or
both of the following shortcuts of passing variable assignments to the
`make install' command line to change installation locations without
having to reconfigure or recompile.
The first method involves providing an override variable for each
affected directory. For example, `make install
prefix=/alternate/directory' will choose an alternate location for all
directory configuration variables that were expressed in terms of
`${prefix}'. Any directories that were specified during `configure',
but not in terms of `${prefix}', must each be overridden at install
time for the entire installation to be relocated. The approach of
makefile variable overrides for each directory variable is required by
the GNU Coding Standards, and ideally causes no recompilation.
However, some platforms have known limitations with the semantics of
shared libraries that end up requiring recompilation when using this
method, particularly noticeable in packages that use GNU Libtool.
The second method involves providing the `DESTDIR' variable. For
example, `make install DESTDIR=/alternate/directory' will prepend
`/alternate/directory' before all installation names. The approach of
`DESTDIR' overrides is not required by the GNU Coding Standards, and
does not work on platforms that have drive letters. On the other hand,
it does better at avoiding recompilation issues, and works well even
when some directory options were not specified in terms of `${prefix}'
at `configure' time.
Optional Features
=================
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Some packages offer the ability to configure how verbose the
execution of `make' will be. For these packages, running `./configure
--enable-silent-rules' sets the default to minimal output, which can be
overridden with `make V=1'; while running `./configure
--disable-silent-rules' sets the default to verbose, which can be
overridden with `make V=0'.
Particular systems
==================
On HP-UX, the default C compiler is not ANSI C compatible. If GNU
CC is not installed, it is recommended to use the following options in
order to use an ANSI C compiler:
./configure CC="cc -Ae -D_XOPEN_SOURCE=500"
and if that doesn't work, install pre-built binaries of GCC for HP-UX.
On OSF/1 a.k.a. Tru64, some versions of the default C compiler cannot
parse its `<wchar.h>' header file. The option `-nodtk' can be used as
a workaround. If GNU CC is not installed, it is therefore recommended
to try
./configure CC="cc"
and if that doesn't work, try
./configure CC="cc -nodtk"
On Solaris, don't put `/usr/ucb' early in your `PATH'. This
directory contains several dysfunctional programs; working variants of
these programs are available in `/usr/bin'. So, if you need `/usr/ucb'
in your `PATH', put it _after_ `/usr/bin'.
On Haiku, software installed for all users goes in `/boot/common',
not `/usr/local'. It is recommended to use the following options:
./configure --prefix=/boot/common
Specifying the System Type
==========================
There may be some features `configure' cannot figure out
automatically, but needs to determine by the type of machine the package
will run on. Usually, assuming the package is built to be run on the
_same_ architectures, `configure' can figure that out, but if it prints
a message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS
KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the option `--target=TYPE' to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
causes the specified `gcc' to be used as the C compiler (unless it is
overridden in the site shell script).
Unfortunately, this technique does not work for `CONFIG_SHELL' due to
an Autoconf bug. Until the bug is fixed you can use this workaround:
CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash
`configure' Invocation
======================
`configure' recognizes the following options to control how it
operates.
`--help'
`-h'
Print a summary of all of the options to `configure', and exit.
`--help=short'
`--help=recursive'
Print a summary of the options unique to this package's
`configure', and exit. The `short' variant lists options used
only in the top level, while the `recursive' variant lists options
also present in any nested packages.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--prefix=DIR'
Use DIR as the installation prefix. *note Installation Names::
for more details, including other options available for fine-tuning
the installation locations.
`--no-create'
`-n'
Run the configure checks, but stop before creating any output
files.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

View File

@@ -0,0 +1,18 @@
## Process this file with automake to produce Makefile.in
# tell autoconf to include the m4 macros in the /m4 directory
# (an alternative to the acinclude.m4 mechanism)
ACLOCAL_AMFLAGS = -I m4
bin_PROGRAMS = DtexToExr
INCLUDES = @OPENEXR_CXXFLAGS@ @PRMANSDK_CXXFLAGS@
LDADD = @OPENEXR_LDFLAGS@ @OPENEXR_LIBS@ @PRMANSDK_LDFLAGS@ @PRMANSDK_LIBS@ -lz
DtexToExr_SOURCES = PxDeepUtils.cpp DtexToExr.cpp

View File

@@ -0,0 +1,115 @@
##-*****************************************************************************
## Copyright (c) 2012, Pixar. All rights reserved. *
## *
## This license governs use of the accompanying software. If you *
## use the software, you accept this license. If you do not accept *
## the license, do not use the software. *
## *
## 1. Definitions *
## The terms "reproduce," "reproduction," "derivative works," and *
## "distribution" have the same meaning here as under U.S. *
## copyright law. A "contribution" is the original software, or *
## any additions or changes to the software. *
## A "contributor" is any person or entity that distributes its *
## contribution under this license. *
## "Licensed patents" are a contributor's patent claims that read *
## directly on its contribution. *
## *
## 2. Grant of Rights *
## (A) Copyright Grant- Subject to the terms of this license, *
## including the license conditions and limitations in section 3, *
## each contributor grants you a non-exclusive, worldwide, *
## royalty-free copyright license to reproduce its contribution, *
## prepare derivative works of its contribution, and distribute *
## its contribution or any derivative works that you create. *
## (B) Patent Grant- Subject to the terms of this license, *
## including the license conditions and limitations in section 3, *
## each contributor grants you a non-exclusive, worldwide, *
## royalty-free license under its licensed patents to make, have *
## made, use, sell, offer for sale, import, and/or otherwise *
## dispose of its contribution in the software or derivative works *
## of the contribution in the software. *
## *
## 3. Conditions and Limitations *
## (A) No Trademark License- This license does not grant you *
## rights to use any contributor's name, logo, or trademarks. *
## (B) If you bring a patent claim against any contributor over *
## patents that you claim are infringed by the software, your *
## patent license from such contributor to the software ends *
## automatically. *
## (C) If you distribute any portion of the software, you must *
## retain all copyright, patent, trademark, and attribution *
## notices that are present in the software. *
## (D) If you distribute any portion of the software in source *
## code form, you may do so only under this license by including a *
## complete copy of this license with your distribution. If you *
## distribute any portion of the software in compiled or object *
## code form, you may only do so under a license that complies *
## with this license. *
## (E) The software is licensed "as-is." You bear the risk of *
## using it. The contributors give no express warranties, *
## guarantees or conditions. You may have additional consumer *
## rights under your local laws which this license cannot change. *
## To the extent permitted under your local laws, the contributors *
## exclude the implied warranties of merchantability, fitness for *
## a particular purpose and non-infringement. *
##-*****************************************************************************
##-*****************************************************************************
## Written by Pixar, 2011-2012.
##-*****************************************************************************
BUILDTMP = obj
IPATH = -I${DTEXTOEXR_PREFIX}/include/OpenEXR \
-I${DTEXTOEXR_RMANROOT}/include/prmansdk-160 \
-I${DTEXTOEXR_RMANROOT}/include
LPATH = -L${DTEXTOEXR_PREFIX}/lib \
-L${DTEXTOEXR_RMANROOT}/lib/prmansdk-160 \
-L${DTEXTOEXR_RMANROOT}/lib \
-Wl,-rpath ${DTEXTOEXR_PREFIX}/lib \
-Wl,-rpath ${DTEXTOEXR_RMANROOT}/lib/prmansdk-160 \
-Wl,-rpath ${DTEXTOEXR_RMANROOT}/lib
LIBS = -lIlmImf -lImath -lIlmThread -lIex -lHalf \
-lprman \
-lpthread -lm
CXX = /usr/bin/g++
LN = /usr/bin/g++
CFLAGS = -g
HFILES = PxBaseDeepHelper.h \
PxDeepOutPixel.h \
PxDeepOutRow.h \
PxDeepUtils.h \
PxFourChanDeepRgba.h \
PxOneChanDeepAlpha.h \
PxOneChanDeepOpacity.h
OFILES = ${BUILDTMP}/PxDeepUtils.o \
${BUILDTMP}/DtexToExr.o
all: ${BUILDTMP}/DtexToExr
${BUILDTMP}/PxDeepUtils.o: PxDeepUtils.h PxDeepUtils.cpp
mkdir -p ${BUILDTMP}
${CXX} PxDeepUtils.cpp -c -o ${BUILDTMP}/PxDeepUtils.o ${CFLAGS} ${IPATH}
${BUILDTMP}/DtexToExr.o: DtexToExr.cpp ${HFILES}
mkdir -p ${BUILDTMP}
${CXX} DtexToExr.cpp -c -o ${BUILDTMP}/DtexToExr.o ${CFLAGS} ${IPATH}
${BUILDTMP}/DtexToExr: ${OFILES}
mkdir -p ${BUILDTMP}
${LN} ${OFILES} -o ${BUILDTMP}/DtexToExr ${CFLAGS} ${IPATH} ${LPATH} ${LIBS}
install: ${BUILDTMP}/DtexToExr
/bin/cp -f ${BUILDTMP}/DtexToExr ${DTEXTOEXR_PREFIX}/bin/DtexToExr
clean:
/bin/rm ${OFILES}
/bin/rm ${BUILDTMP}/DtexToExr

View File

@@ -0,0 +1,2 @@
Version 1.0.0
- initial release

View File

@@ -0,0 +1,330 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar Animation Studios, 2011-2012.
//-*****************************************************************************
#ifndef _PxDeepBaseHelper_h_
#define _PxDeepBaseHelper_h_
#include "PxDeepUtils.h"
#include "PxDeepOutPixel.h"
#include "PxDeepOutRow.h"
#include <dtex.h>
#include <ImfDeepScanLineOutputFile.h>
#include <ImfPartType.h>
#include <ImfChannelList.h>
#include <ImathVec.h>
#include <ImathBox.h>
namespace PxDeep {
//-*****************************************************************************
// PARAMETERS STRUCT
//-*****************************************************************************
// This allows us to keep function signatures from changing around too much
// as the parameter set grows & changes, which it always does.
struct Parameters
{
Parameters()
: deepOpacity( true )
, discrete( true )
, multiplyColorByAlpha( false )
, sideways( false )
, discardZeroAlphaSamples( true )
, doDeepBack( true )
, doRGB( true )
, compressionError( 0.0f ) {}
bool deepOpacity;
bool discrete;
bool multiplyColorByAlpha;
bool sideways;
bool discardZeroAlphaSamples;
bool doDeepBack;
bool doRGB;
float compressionError;
};
//-*****************************************************************************
// BASE DEEP HELPER CLASS
//-*****************************************************************************
// The intention of this templated base class is to provide consistent
// storage vectors for spans and deep pixels across multiple pixel reads,
// so we don't slow down constantly creating and destroying std::vectors.
// This class has a "processDeepBox" function which does the work.
template <typename RGBA_T, typename DERIVED, typename SPAN>
class BaseDeepHelper
{
public:
typedef DERIVED sub_type;
typedef SPAN span_type;
BaseDeepHelper( DtexFile* i_dtexFile,
int i_numDtexChans,
const Parameters& i_params )
: m_dtexFile( i_dtexFile )
, m_numDtexChans( i_numDtexChans )
, m_params( i_params )
{
m_image = NULL;
DtexGetImageByIndex( m_dtexFile, 0, &m_image );
m_fileWidth = DtexWidth( m_image );
m_fileHeight = DtexHeight( m_image );
m_pixel = DtexMakePixel( m_numDtexChans );
m_rawPixel = DtexMakePixel( m_numDtexChans );
}
~BaseDeepHelper()
{
DtexDestroyPixel( m_pixel );
DtexDestroyPixel( m_rawPixel );
}
void processDeepBox( Imf::DeepScanLineOutputFile& o_file,
const Imath::Box2i& i_box );
protected:
DtexFile* m_dtexFile;
int m_numDtexChans;
Parameters m_params;
DtexImage* m_image;
int m_fileWidth;
int m_fileHeight;
DtexPixel* m_pixel;
DtexPixel* m_rawPixel;
std::vector<span_type> m_spans;
DeepOutPixel<RGBA_T> m_deepOutPixel;
};
//-*****************************************************************************
//-*****************************************************************************
// SPAN CLASSES
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
// These span objects are used by the helper classes below to keep track
// of the information read out of the DTEX file, so it can be processed.
// They have an ordering operator which sorts them by depth and then index.
// We use double precision for 'viz', for reasons described in the 'VIZ'
// section of the explanatory comments in the PxDeepUtils library.
struct Span
{
Span() : in( 0.0f ), out( 0.0f ), viz( 0.0 ), index( 0 ) {}
float in;
float out;
double viz;
int index;
void clear()
{
in = 0.0f;
out = 0.0f;
viz = 0.0;
index = 0;
}
bool operator<( const Span& i_other ) const
{
if ( in < i_other.in )
{
return true;
}
else if ( in == i_other.in )
{
return index < i_other.index;
}
else
{
return false;
}
}
};
//-*****************************************************************************
// Because the RGB values here are unpremultiplied, we use double precision
// to avoid precision loss when going (RGB/A)*A.
struct SpanRgba : public Span
{
SpanRgba() : Span() { rgb[0] = 0.0; rgb[1] = 0.0; rgb[2] = 0.0; }
double rgb[3];
void clear()
{
Span::clear();
rgb[0] = 0.0;
rgb[1] = 0.0;
rgb[2] = 0.0;
}
};
//-*****************************************************************************
// As above, we use double precision for viz.
struct SpanOpac : public Span
{
SpanOpac() : Span(), deepViz( 0.0 ) {}
double deepViz;
void clear()
{
Span::clear();
deepViz = 0.0;
}
};
//-*****************************************************************************
// The box processing simply loops over the rows, compresses each pixel, then
// converts from dtex representation to deep exr representation, and finally
// writes the rows to the file.
template <typename RGBA_T, typename DERIVED, typename SPAN>
void BaseDeepHelper<RGBA_T,DERIVED,SPAN>::processDeepBox
(
Imf::DeepScanLineOutputFile& o_file,
const Imath::Box2i& i_box )
{
int width = ( i_box.max.x - i_box.min.x ) + 1;
DeepOutRow<RGBA_T> outRow( width, m_params.doDeepBack, m_params.doRGB );
for ( int y = i_box.max.y; y >= i_box.min.y; --y )
{
outRow.clear();
for ( int x = i_box.min.x; x <= i_box.max.x; ++x )
{
if ( m_params.sideways )
{
DtexGetPixel( m_image, m_fileWidth - 1 - y,
m_fileHeight - 1 - x, m_rawPixel );
}
else
{
DtexGetPixel( m_image, x,
m_fileHeight - 1 - y, m_rawPixel );
}
// Get the number of input points.
int numPointsIn = DtexPixelGetNumPoints( m_rawPixel );
if ( numPointsIn < 0 )
{
PXDU_THROW( "Negative num points returned at dtex pixel: "
<< x << ", " << y );
}
// Compress the pixel.
if ( numPointsIn > 1 && m_params.compressionError > 0.0f )
{
DtexCompressPixel( m_rawPixel, m_pixel,
m_params.compressionError );
DtexFinishPixel( m_pixel );
}
else
{
DtexCopyPixel( m_pixel, m_rawPixel );
DtexFinishPixel( m_pixel );
}
// Get num points of compressed pixel.
int numPts = DtexPixelGetNumPoints( m_pixel );
// If no samples here, continue on.
if ( numPts < 1 )
{
outRow.addHole( x - i_box.min.x );
continue;
}
m_deepOutPixel.clear();
m_deepOutPixel.reserve( numPts * m_numDtexChans );
// Process the deep pixels.
DERIVED* derivedThis = static_cast<DERIVED*>( this );
derivedThis->processDeepPixel( numPts );
// Add the pixel to the row.
outRow.addPixel( x - i_box.min.x, m_deepOutPixel );
}
// Create the frame buffer.
// I'm not sure if this can be reused from row to row.
Imf::DeepFrameBuffer frameBuffer;
// Set the deep out row into the framebuffer.
outRow.setFrameBuffer( frameBuffer );
// Write row.
o_file.setFrameBuffer( frameBuffer );
o_file.writePixels( 1 );
}
}
} // End namespace PxDeep
#endif

View File

@@ -0,0 +1,166 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar Animation Studios, 2011-2012.
//-*****************************************************************************
#ifndef _PxDeepOutPixel_h_
#define _PxDeepOutPixel_h_
#include "PxDeepUtils.h"
namespace PxDeep {
//-*****************************************************************************
//-*****************************************************************************
// DEEP OUT PIXEL
//-*****************************************************************************
//-*****************************************************************************
// While constructing a deep out pixel from a dtex pixel, we reuse some
// temporary storage.
template <typename RGBA_T>
struct DeepOutPixel
{
size_t size() const
{
return deepFront.size();
}
void clear()
{
deepFront.clear();
deepBack.clear();
red.clear();
green.clear();
blue.clear();
alpha.clear();
}
void reserve( size_t N )
{
deepFront.reserve( N );
deepBack.reserve( N );
red.reserve( N );
green.reserve( N );
blue.reserve( N );
alpha.reserve( N );
}
void push_back( float i_depth,
RGBA_T i_alpha )
{
deepFront.push_back( i_depth );
deepBack.push_back( i_depth );
red.push_back( 0.0f );
green.push_back( 0.0f );
blue.push_back( 0.0f );
alpha.push_back( i_alpha );
}
void push_back( float i_deepFront,
float i_deepBack,
RGBA_T i_alpha )
{
deepFront.push_back( i_deepFront );
deepBack.push_back( i_deepBack );
red.push_back( 0.0f );
green.push_back( 0.0f );
blue.push_back( 0.0f );
alpha.push_back( i_alpha );
}
void push_back( float i_depth,
RGBA_T i_red,
RGBA_T i_green,
RGBA_T i_blue,
RGBA_T i_alpha )
{
deepFront.push_back( i_depth );
deepBack.push_back( i_depth );
red.push_back( i_red );
green.push_back( i_green );
blue.push_back( i_blue );
alpha.push_back( i_alpha );
}
void push_back( float i_deepFront,
float i_deepBack,
RGBA_T i_red,
RGBA_T i_green,
RGBA_T i_blue,
RGBA_T i_alpha )
{
deepFront.push_back( i_deepFront );
deepBack.push_back( i_deepBack );
red.push_back( i_red );
green.push_back( i_green );
blue.push_back( i_blue );
alpha.push_back( i_alpha );
}
std::vector<float> deepFront;
std::vector<float> deepBack;
std::vector<RGBA_T> red;
std::vector<RGBA_T> green;
std::vector<RGBA_T> blue;
std::vector<RGBA_T> alpha;
};
}
#endif

View File

@@ -0,0 +1,299 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar Animation Studios, 2011-2012.
//-*****************************************************************************
#ifndef _PxDeepOutRow_h_
#define _PxDeepOutRow_h_
#include "PxDeepUtils.h"
#include "PxDeepOutPixel.h"
#include <ImfDeepScanLineOutputFile.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfPartType.h>
#include <ImfChannelList.h>
namespace PxDeep {
//-*****************************************************************************
//-*****************************************************************************
// DEEP OUT ROW
//-*****************************************************************************
//-*****************************************************************************
template <typename RGBA_T>
class DeepOutRow
{
public:
DeepOutRow( int i_width, bool i_doDeepBack, bool i_doRGB );
void clear();
void addHole( int i_x )
{
m_sampleCounts[i_x] = 0;
}
void addPixel( int i_x, const DeepOutPixel<RGBA_T>& i_pixel );
void setFrameBuffer( Imf::DeepFrameBuffer& o_frameBuffer );
protected:
// Width of the row.
int m_width;
// Whether or not to bother with deep back
bool m_doDeepBack;
// Whether or not to bother with RGB
bool m_doRGB;
// Scanline sample buffers.
std::vector<uint> m_sampleCounts;
// The pointers to data at each pixel
std::vector<float*> m_deepFrontPtrs;
std::vector<float*> m_deepBackPtrs;
std::vector<RGBA_T*> m_redPtrs;
std::vector<RGBA_T*> m_greenPtrs;
std::vector<RGBA_T*> m_bluePtrs;
std::vector<RGBA_T*> m_alphaPtrs;
// The data itself.
std::vector<float> m_deepFrontSamples;
std::vector<float> m_deepBackSamples;
std::vector<RGBA_T> m_redSamples;
std::vector<RGBA_T> m_greenSamples;
std::vector<RGBA_T> m_blueSamples;
std::vector<RGBA_T> m_alphaSamples;
};
//-*****************************************************************************
template <typename T>
inline void VecAppend( T& i_dst, const T& i_src )
{
i_dst.insert( i_dst.end(), i_src.begin(), i_src.end() );
}
//-*****************************************************************************
template <typename RGBA_T>
DeepOutRow<RGBA_T>::DeepOutRow( int i_width, bool i_doDeepBack, bool i_doRGB )
: m_width( i_width )
, m_doDeepBack( i_doDeepBack )
, m_doRGB( i_doRGB )
{
m_sampleCounts.resize( ( size_t )m_width );
m_deepFrontPtrs.resize( ( size_t )m_width );
if ( m_doDeepBack )
{
m_deepBackPtrs.resize( ( size_t )m_width );
}
if ( m_doRGB )
{
m_redPtrs.resize( ( size_t )m_width );
m_greenPtrs.resize( ( size_t )m_width );
m_bluePtrs.resize( ( size_t )m_width );
}
m_alphaPtrs.resize( ( size_t )m_width );
}
//-*****************************************************************************
template <typename RGBA_T>
void DeepOutRow<RGBA_T>::clear()
{
std::fill( m_sampleCounts.begin(),
m_sampleCounts.end(),
( uint )0 );
m_deepFrontSamples.clear();
m_deepBackSamples.clear();
m_redSamples.clear();
m_greenSamples.clear();
m_blueSamples.clear();
m_alphaSamples.clear();
}
//-*****************************************************************************
template <typename RGBA_T>
void DeepOutRow<RGBA_T>::addPixel( int i_x,
const DeepOutPixel<RGBA_T>& i_pixel )
{
int npoints = i_pixel.size();
m_sampleCounts[i_x] = npoints;
if ( npoints > 0 )
{
VecAppend( m_deepFrontSamples, i_pixel.deepFront );
if ( m_doDeepBack )
{
VecAppend( m_deepBackSamples, i_pixel.deepBack );
}
if ( m_doRGB )
{
VecAppend( m_redSamples, i_pixel.red );
VecAppend( m_greenSamples, i_pixel.green );
VecAppend( m_blueSamples, i_pixel.blue );
}
VecAppend( m_alphaSamples, i_pixel.alpha );
}
}
//-*****************************************************************************
template <typename RGBA_T>
void DeepOutRow<RGBA_T>::setFrameBuffer( Imf::DeepFrameBuffer& o_frameBuffer )
{
// Set up the pointers.
float *deepFrontLastPtr = m_deepFrontSamples.data();
float *deepBackLastPtr = m_deepBackSamples.data();
RGBA_T *redLastPtr = m_redSamples.data();
RGBA_T *greenLastPtr = m_greenSamples.data();
RGBA_T *blueLastPtr = m_blueSamples.data();
RGBA_T *alphaLastPtr = m_alphaSamples.data();
for ( int x = 0; x < m_width; ++x )
{
m_deepFrontPtrs[x] = deepFrontLastPtr;
if ( m_doDeepBack )
{
m_deepBackPtrs[x] = deepBackLastPtr;
}
if ( m_doRGB )
{
m_redPtrs[x] = redLastPtr;
m_greenPtrs[x] = greenLastPtr;
m_bluePtrs[x] = blueLastPtr;
}
m_alphaPtrs[x] = alphaLastPtr;
int c = m_sampleCounts[x];
deepFrontLastPtr += c;
deepBackLastPtr += c;
redLastPtr += c;
greenLastPtr += c;
blueLastPtr += c;
alphaLastPtr += c;
}
// Sample counts
o_frameBuffer.insertSampleCountSlice(
Imf::Slice( Imf::UINT,
( char * )m_sampleCounts.data(),
sizeof( uint ), // x stride
0 ) ); // y stride
// RGB
if ( m_doRGB )
{
o_frameBuffer.insert(
"R",
Imf::DeepSlice( ImfPixelType<RGBA_T>(),
( char * )m_redPtrs.data(),
sizeof( RGBA_T* ), // xstride
0, // ystride
sizeof( RGBA_T ) ) ); // sample stride
o_frameBuffer.insert(
"G",
Imf::DeepSlice( ImfPixelType<RGBA_T>(),
( char * )m_greenPtrs.data(),
sizeof( RGBA_T* ), // xstride
0, // ystride
sizeof( RGBA_T ) ) ); // sample stride
o_frameBuffer.insert(
"B",
Imf::DeepSlice( ImfPixelType<RGBA_T>(),
( char * )m_bluePtrs.data(),
sizeof( RGBA_T* ), // xstride
0, // ystride
sizeof( RGBA_T ) ) ); // sample stride
}
// ALPHA
o_frameBuffer.insert(
"A",
Imf::DeepSlice( ImfPixelType<RGBA_T>(),
( char * )m_alphaPtrs.data(),
sizeof( RGBA_T* ), // xstride
0, // ystride
sizeof( RGBA_T ) ) ); // sample stride
// DEEP FRONT
o_frameBuffer.insert(
"Z",
Imf::DeepSlice( Imf::FLOAT,
( char * )m_deepFrontPtrs.data(),
sizeof( float* ), // xstride
0, // ystride
sizeof( float ) ) ); // sample stride
// DEEP BACK
if ( m_doDeepBack )
{
o_frameBuffer.insert(
"ZBack",
Imf::DeepSlice( Imf::FLOAT,
( char * )m_deepBackPtrs.data(),
sizeof( float* ), // xstride
0, // ystride
sizeof( float ) ) ); // sample stride
}
}
} // End namespace PxDeep
#endif

View File

@@ -0,0 +1,199 @@
//-*****************************************************************************
// Copyright (C) Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar Animation Studios, 2011-2012.
//-*****************************************************************************
#include "PxDeepUtils.h"
namespace PxDeep {
//-*****************************************************************************
// Density/Viz/DZ calculations are always performed in double precision.
// We try to leave them alone as much as possible, but the logarithm can get
// weird for very very small numbers. The "isfinite" call basically rules
// out NaN and Infinity results, though it doesn't bother with subnormal
// numbers, since the error case we're worried about is log being too big.
// viz = exp( -dz * density )
// log( viz ) = -dz * density
// density = -log( viz ) / dz
double DensityFromVizDz( double i_viz, double i_dz )
{
assert( i_viz >= 0.0 );
assert( i_viz <= 1.0 );
assert( i_dz >= 0.0 );
if ( i_viz >= 1.0 )
{
// There's no attenuation at all, so there's no density!
return 0.0;
}
else if ( i_viz <= 0.0 )
{
// There's total attenuation, so we use our max density.
return PXDU_DENSITY_OF_VIZ_0;
}
else if ( i_dz <= 0.0 )
{
// There's no depth, and viz is greater than zero,
// so we assume the density is as high as possible
return PXDU_DENSITY_OF_VIZ_0;
}
else
{
double d = -log( i_viz ) / i_dz;
if ( !isfinite( d ) )
{
return PXDU_DENSITY_OF_VIZ_0;
}
else
{
return d;
}
}
}
//-*****************************************************************************
// We can often treat "density times dz" as a single quantity without
// separating it.
// viz = exp( -densityTimesDz )
// log( viz ) = -densityTimesDz
// densityTimesDz = -log( viz )
double DensityTimesDzFromViz( double i_viz )
{
assert( i_viz >= 0.0 );
assert( i_viz <= 1.0 );
if ( i_viz >= 1.0 )
{
// There's no attenuation at all, so there's no density!
return 0.0;
}
else if ( i_viz <= 0.0 )
{
// There's total attenuation, so we use our max density.
return PXDU_DENSITY_OF_VIZ_0 * PXDU_DZ_OF_VIZ_0;
}
else
{
double d = -log( i_viz );
if ( !isfinite( d ) )
{
return PXDU_DENSITY_OF_VIZ_0 * PXDU_DZ_OF_VIZ_0;
}
else
{
return d;
}
}
}
//-*****************************************************************************
// viz = exp( -dz * density )
// log( viz ) = -dz * density
// dz = -log( viz ) / density
// Note that this is basically the same as the computation above.
double DzFromVizDensity( double i_viz, double i_density )
{
assert( i_viz >= 0.0 );
assert( i_viz <= 1.0 );
assert( i_density >= 0.0 );
if ( i_viz >= 1.0 )
{
// There's no attenuation, so there's no depth.
return 0.0;
}
else if ( i_viz <= 0.0 )
{
// There's total attenuation, so we use the smallest depth
// for our max density.
return PXDU_DZ_OF_VIZ_0;
}
else if ( i_density <= 0.0 )
{
// Hmmm. There's no density, but there is some attenuation,
// which basically implies an infinite depth.
// We'll use the minimum density.
// This whole part is hacky at best.
double dz = -log( i_viz ) / PXDU_MIN_NON_ZERO_DENSITY;
if ( !isfinite( dz ) )
{
return PXDU_MAX_DZ;
}
else
{
return dz;
}
}
else
{
double dz = -log( i_viz ) / i_density;
if ( !isfinite( dz ) )
{
return PXDU_MAX_DZ;
}
else
{
return dz;
}
}
}
} // End namespace PxDeep

View File

@@ -0,0 +1,507 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar Animation Studios, 2011-2012.
//-*****************************************************************************
#ifndef _PxDeepUtils_h_
#define _PxDeepUtils_h_
#include <ImfNamespace.h>
#include <ImfPixelType.h>
#include <ImfPartType.h>
#include <ImathFun.h>
#include <ImathVec.h>
#include <ImathBox.h>
#include <ImathMatrix.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <iostream>
#include <exception>
#include <stdexcept>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <dtex.h>
#include <half.h>
#include <math.h>
#include <float.h>
#include <cmath>
#include <sys/types.h>
using std::isfinite;
namespace PxDeep {
//-*****************************************************************************
// The large block of comments below explains our working terminology and
// the justification of our limits & magic numbers. In a few places, the
// use of centimeters as a spatial unit does affect the absolute position of
// various minima and maxima, but in normal usage those should be well outside
// working ranges.
//-*****************************************************************************
//-*****************************************************************************
// DENSITY
//-*****************************************************************************
// "Density" refers to the the optical density which, when integrated
// through a line, produces an alpha. The relationship between alpha, density,
// and line segment of a given length "dz" is as follows:
//
// alpha = 1.0 - exp( -dz * density )
//
// We use a minimum non-zero density in some places in our code, which
// represents the density of dry air at atmospheric pressure. Though
// different wavelengths of light are attenuated differently, the average
// attenuation is 10^-5 per meter. To make it very minimal,
// we'll work with 1/10th that density (tiny tiny). Since our facility
// works in centimeters, this works out to (using & rearranging the
// equation above)
//
// 10^-6 = 1.0 - exp( -100.0 * MIN_NON_ZERO_DENSITY )
// exp( -100.0 * MIN_NON_ZERO_DENSITY ) = 1.0 - 10^-6
// -100.0 * MIN_NON_ZERO_DENSITY = log( 1.0 - 10^-6 )
// MIN_NON_ZERO_DENSITY = log( 1.0 - 10^-6 ) / -100.0
// MIN_NON_ZERO_DENSITY = 1.0000050000290891e-08
//
// We use double precision for density and dz calculations.
//
//-*****************************************************************************
// VISIBILITY (or 'VIZ', or 'TRANSMISSION')
//-*****************************************************************************
// Throughout the code below, we transform "alpha" into its inverse, which is
// transmissivity, or visibility, or for short, 'viz'. The relationship between
// alpha and viz is simple:
//
// alpha = 1.0 - viz, or viz = 1.0 - alpha.
//
// Similarly, the relationship between viz and density & dz is simple:
//
// viz = exp( -dz * density )
// log( viz ) = -dz * density
//
// Viz is easier to work with than alpha, because to accumulate a total
// visibility of many adjacent samples, the relationship is just, for the
// set of sample viz's: {viz0, viz1, viz2, ..., vizN-1}
//
// totalViz = viz0 * viz1 * viz2 * ... * vizN-1
//
// It's interesting to note that for any given set of spans, their accumulated
// visibility is the same regardless of what order they're accumulated in,
// since A*B == B*A.
//
// When using viz, we use double precision because the operation
// 1.0f - ( 1.0f - a ) loses precision, and we want as little of that as
// possible!
//
//-*****************************************************************************
// DEPTH RANGES
//-*****************************************************************************
// Because we need to be able to arithmetically manipulate depths, we place
// a range on the valid depth values. Positive Infinity is a valid depth value
// to be stored in a DTEX file, but in order to make everything else work, we
// set the maximum depth to near (but not at) FLT_MAX, 10^30. Similarly, we
// set the minimum depth to just slightly greater than zero, 10^-4. This
// could potentially clip effects being deep composited with very small
// distances and units of meters.
//
//-*****************************************************************************
// DEEP OPACITY
//-*****************************************************************************
// "Deep Opacity" refers to a depth function in which the sample at each point
// represents the total accumulated opacity at that depth. This represents
// the way that deep shadows would have been produced by renderman with the
// Display Driver Line: "deepshad" "deepopacity", except that the files actually
// store the inverse (1.0-opacity) at each point. It is important to note
// that for any given Dtex deepopacity sample, the value represents the
// accumulation of visibility on the NEAR side of the sample - up to and
// including the sample's depth, but no further in depth. Deep Opacity
// functions are monotonically decreasing in depth, and are always
// between 0 and 1.
//
// A complication arises when the 0'th continuous deep opacity sample has a
// non-zero deep opacity, because we don't have enough information to infer
// where the continuous span that ends at the 0th sample begins in depth. We
// solve the problem by interrogating the entire deep pixel for the maximum
// density of all its spans (see above), and then solving for what dz
// would produce the given accumulated alpha for that max density. The
// near point of the initial span is then 'dz' units in front of the 0th
// sample depth.
//
// We sometimes use 'deepViz' to in the code below to refer to 1.0 - deepOpacity
//
//-*****************************************************************************
// DEEP ALPHA
//-*****************************************************************************
// "Deep Alpha" refers to a depth function in which the sample at each point
// represents the non-accumulated alpha of that single sample. When interpreting
// the depth function as continuous instead of discrete, Deep Alpha represents
// the alpha of the FAR side of the sample - from the depth of the sample
// up to, but not including, the depth of the next sample.
//
// A complication arises when the last continuous deep alpha sample has a
// non-zero deep alpha, because we don't have enough information to infer
// where the continuous span that begins at the last sample ends in depth. We
// solve this problem analagously to how we solve the DeepOpacity problem.
// We get the maximum density along the entire deep pixel and extrapolate to
// determine an end depth.
//
//-*****************************************************************************
// DEEP RGBA
//-*****************************************************************************
// Deep RGBA is exactly the same as Deep Alpha, for both discrete and
// continuous cases, with the additional R,G, and B channels carried along.
// The RGB can be read as premultiplied by alpha, or not. The output deep
// pixel expects RGB to be premultiplied by alpha.
// The use of premultiplied alpha makes it possible to entangle emitted and
// reflected light - basically "glows", when premultiplied R,G,B are non-zero
// but alpha is zero. However, in order for us to collapse coindicent samples,
// we need to temporarily store RGB unpremultiplied. We simply don't affect
// the samples that have zero alpha, and don't remultiply samples that have
// zero alpha. There's no way for uncombined samples that had non-zero alpha
// to produce a combined sample with zero alpha, so any sample that has
// zero alpha at the end of all the combining was entirely composed of zero
// alpha samples to begin with. SO, if the alpha is zero, we don't
// multiply by it!
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
// UTILITY CONSTANTS AND FUNCTIONS
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
// Explained above in the "Density" section of the comments.
// We set this value to one tenth the attenuation of light in dry air
// at atmospheric pressure.
// 10^-6 = 1.0 - exp( -100.0 * MIN_NON_ZERO_DENSITY )
// exp( -100.0 * MIN_NON_ZERO_DENSITY ) = 1.0 - 10^-6
// -100.0 * MIN_NON_ZERO_DENSITY = log( 1.0 - 10^-6 )
// MIN_NON_ZERO_DENSITY = log( 1.0 - 10^-6 ) / -100.0
// MIN_NON_ZERO_DENSITY = 1.0000050000290891e-08
// static const double MIN_NON_ZERO_DENSITY = log( 1.0 - 1.0e-6 ) / -100.0;
#define PXDU_MIN_NON_ZERO_DENSITY 1.0000050000290891e-08L
//-*****************************************************************************
// The change in depth which produces maximum alpha for maximum density.
// We want this to be small without risking subnormality.
// static const double DZ_OF_ALPHA_1 = 0.001;
// static const double DZ_OF_VIZ_0 = 0.001;
#define PXDU_DZ_OF_ALPHA_1 0.001
#define PXDU_DZ_OF_VIZ_0 0.001
//-*****************************************************************************
// We set the max density of alpha 1 to the density which would produce
// an alpha of 0.99999 in a distance of 0.001 centimeters (DZ_OF_ALPHA_1)
//
// 0.99999 = 1.0 - exp( -0.001 * MAX_DENSITY )
// exp( -0.001 * MAX_DENSITY ) = 1.0 - 0.99999
// -0.001 * MAX_DENSITY = log( 1.0 - 0.99999 )
// MAX_DENSITY = log( 1.0 - 0.99999 ) / -0.001
// MAX_DENSITY = 11512.925464974779
// static const double DENSITY_OF_ALPHA_1 = log( 1.0 - 0.99999 ) / -0.001;
// static const double DENSITY_OF_VIZ_0 = DENSITY_OF_ALPHA_1;
#define PXDU_DENSITY_OF_ALPHA_1 11512.92546497478
#define PXDU_DENSITY_OF_VIZ_0 11512.92546497478
//-*****************************************************************************
// Just in case we need it. These are the constants used above.
#define PXDU_MAX_NON_OPAQUE_ALPHA 0.99999
#define PXDU_MIN_NON_OPAQUE_VIZ 0.00001
#define PXDU_MIN_NON_TRANSPARENT_ALPHA 0.00001
#define PXDU_MAX_NON_TRANSPARENT_VIZ 0.99999
//-*****************************************************************************
// Explained above in the "Depth" section of the comments.
// static const double MIN_DEEP_DEPTH = 1.0e-4;
// static const double MAX_DEEP_DEPTH = 1.0e30;
#define PXDU_MIN_DEEP_DEPTH 1.0e-4
#define PXDU_MAX_DEEP_DEPTH 1.0e30
//-*****************************************************************************
// A maximum depth change (dz)
// static const double MAX_DZ = double( MAX_DEEP_DEPTH ) -
// double( MIN_DEEP_DEPTH );
#define PXDU_MAX_DZ 1.0e30
//-*****************************************************************************
// IEEE 754 floats can be incremented to the "next" positive float
// in this manner, for positive float inputs.
inline float IncrementPositiveFloat( float i_a, int32_t i_inc=1 )
{
typedef union
{
int32_t i;
float f;
} intfloat;
intfloat a;
a.f = i_a;
a.i += i_inc;
return a.f;
}
//-*****************************************************************************
// IEEE 754 floats can be decremented to the "previous" positive float
// in this manner, for positive float inputs.
inline float DecrementPositiveFloat( float i_a, int32_t i_inc=1 )
{
typedef union
{
int32_t i;
float f;
} intfloat;
intfloat a;
a.f = i_a;
a.i -= i_inc;
return a.f;
}
//-*****************************************************************************
// From: man isinf
// isinf(x) returns 1 if x is positive infinity, and -1 if x is nega-
// tive infinity.
template <typename T>
inline bool IsInfinity( T i_f )
{
return ( isinf( i_f ) == 1 );
}
//-*****************************************************************************
// A zero-nan functon, which actually zeros inf as well.
template <typename T>
inline T ZeroNAN( T i_f )
{
if ( !isfinite( i_f ) ) { return ( T )0; }
else { return i_f; }
}
//-*****************************************************************************
template <typename T>
inline T ClampDepth( T i_depth )
{
if ( IsInfinity( i_depth ) )
{
return PXDU_MAX_DEEP_DEPTH;
}
else
{
return Imath::clamp( i_depth,
( T )PXDU_MIN_DEEP_DEPTH,
( T )PXDU_MAX_DEEP_DEPTH );
}
}
//-*****************************************************************************
template <typename T>
inline T ClampDz( T i_dz )
{
return Imath::clamp( ZeroNAN( i_dz ), ( T )0, ( T )PXDU_MAX_DZ );
}
//-*****************************************************************************
template <typename T>
inline T ClampNonZeroDz( T i_dz )
{
return Imath::clamp( ZeroNAN( i_dz ),
( T )PXDU_DZ_OF_ALPHA_1,
( T )PXDU_MAX_DZ );
}
//-*****************************************************************************
template <typename T>
inline T ClampAlpha( T i_alpha )
{
return Imath::clamp( ZeroNAN( i_alpha ), ( T )0, ( T )1 );
}
//-*****************************************************************************
// "plausible" in this case means not completely transparent, nor
// completely opaque.
template <typename T>
inline T ClampPlausibleAlpha( T i_alpha )
{
return Imath::clamp( ZeroNAN( i_alpha ),
( T )PXDU_MIN_NON_TRANSPARENT_ALPHA,
( T )PXDU_MAX_NON_OPAQUE_ALPHA );
}
//-*****************************************************************************
template <typename T>
inline double ClampViz( T i_viz )
{
return Imath::clamp( ZeroNAN( i_viz ), ( T )0, ( T )1 );
}
//-*****************************************************************************
// "plausible" in this case means not completely transparent, nor
// completely opaque.
template <typename T>
inline T ClampPlausibleViz( T i_viz )
{
return Imath::clamp( ZeroNAN( i_viz ),
( T )PXDU_MIN_NON_OPAQUE_VIZ,
( T )PXDU_MAX_NON_TRANSPARENT_VIZ );
}
//-*****************************************************************************
// Plausible density is clamped between min non-zero density
// and density of alpha 1.
template <typename T>
inline T ClampPlausibleDensity( T i_density )
{
return Imath::clamp( ZeroNAN( i_density ),
( T )PXDU_MIN_NON_ZERO_DENSITY,
( T )PXDU_DENSITY_OF_ALPHA_1 );
}
//-*****************************************************************************
// Density/Viz/DZ calculations are always performed in double precision.
// We try to leave them alone as much as possible, but the logarithm can get
// weird for very very small numbers. The "isfinite" call basically rules
// out NaN and Infinity results, though it doesn't bother with subnormal
// numbers, since the error case we're worried about is log being too big.
// viz = exp( -dz * density )
// log( viz ) = -dz * density
// density = -log( viz ) / dz
double DensityFromVizDz( double i_viz, double i_dz );
//-*****************************************************************************
// We can often treat "density times dz" as a single quantity without
// separating it.
// viz = exp( -densityTimesDz )
// log( viz ) = -densityTimesDz
// densityTimesDz = -log( viz )
double DensityTimesDzFromViz( double i_viz );
//-*****************************************************************************
// Plausible density defined above.
inline double PlausibleDensityFromVizDz( double i_viz, double i_dz )
{
return ClampPlausibleDensity( DensityFromVizDz( i_viz, i_dz ) );
}
//-*****************************************************************************
// viz = exp( -dz * density )
// log( viz ) = -dz * density
// dz = -log( viz ) / density
// Note that this is basically the same as the computation above.
double DzFromVizDensity( double i_viz, double i_density );
//-*****************************************************************************
// viz = exp( -dz * density ) // valid for all finite numbers.
// negative densities or dz's will give greater than 1 viz's, which will
// get clamped!
inline double VizFromDensityDz( double i_density, double i_dz )
{
return ClampViz( exp( -ZeroNAN( i_density * i_dz ) ) );
}
//-*****************************************************************************
// same as above.
inline double VizFromDensityTimesDz( double i_densityTimesDz )
{
return ClampViz( exp( -ZeroNAN( i_densityTimesDz ) ) );
}
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
// IMF SPECIFIC STUFF
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
//-*****************************************************************************
template <typename T>
Imf::PixelType ImfPixelType();
template <>
inline Imf::PixelType ImfPixelType<half>() { return Imf::HALF; }
template <>
inline Imf::PixelType ImfPixelType<float>() { return Imf::FLOAT; }
template <>
inline Imf::PixelType ImfPixelType<uint>() { return Imf::UINT; }
//-*****************************************************************************
// Handy exception macro.
#define PXDU_THROW( TEXT ) \
do \
{ \
std::stringstream sstr; \
sstr << TEXT; \
std::runtime_error exc( sstr.str() ); \
throw( exc ); \
} \
while( 0 )
} // End namespace PxDeep
#endif

View File

@@ -0,0 +1,511 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar, 2011-2012.
//-*****************************************************************************
#ifndef _PxFourChanDeepRgba_h_
#define _PxFourChanDeepRgba_h_
#include "PxDeepUtils.h"
#include "PxBaseDeepHelper.h"
namespace PxDeep {
//-*****************************************************************************
// FOUR CHANNEL DEEP RGBA CONTINUOUS
//-*****************************************************************************
template <typename RGBA_T>
class FourChanDeepRgbaContinuous
: public BaseDeepHelper<RGBA_T,
FourChanDeepRgbaContinuous<RGBA_T>,SpanRgba>
{
public:
typedef BaseDeepHelper<RGBA_T,
FourChanDeepRgbaContinuous<RGBA_T>,SpanRgba>
super_type;
typedef FourChanDeepRgbaContinuous<RGBA_T> this_type;
typedef typename super_type::span_type span_type;
FourChanDeepRgbaContinuous( DtexFile* i_dtexFile,
int i_numDtexChans,
const Parameters& i_params )
: BaseDeepHelper<RGBA_T,
FourChanDeepRgbaContinuous<RGBA_T>,SpanRgba>
( i_dtexFile,
i_numDtexChans,
i_params ) {}
void processDeepPixel( int i_numPts );
};
//-*****************************************************************************
// FOUR CHANNEL DEEP RGBA DISCRETE
//-*****************************************************************************
template <typename RGBA_T>
class FourChanDeepRgbaDiscrete
: public BaseDeepHelper<RGBA_T,
FourChanDeepRgbaDiscrete<RGBA_T>,SpanRgba>
{
public:
typedef BaseDeepHelper<RGBA_T,
FourChanDeepRgbaDiscrete<RGBA_T>,SpanRgba>
super_type;
typedef FourChanDeepRgbaDiscrete<RGBA_T> this_type;
typedef typename super_type::span_type span_type;
FourChanDeepRgbaDiscrete( DtexFile* i_dtexFile,
int i_numDtexChans,
const Parameters& i_params )
: BaseDeepHelper<RGBA_T,
FourChanDeepRgbaDiscrete<RGBA_T>,SpanRgba>
( i_dtexFile,
i_numDtexChans,
i_params ) {}
void processDeepPixel( int i_numPts );
};
//-*****************************************************************************
template <typename RGBA_T>
void FourChanDeepRgbaContinuous<RGBA_T>::processDeepPixel( int i_numPts )
{
assert( i_numPts > 0 );
// Loop over all the dtex points and get their deepAlphas
// and their depths. Enforce the case that deepAlpha
// is always between 0 and 1.
(this->m_spans).resize( ( size_t )i_numPts );
for ( int j = 0; j < i_numPts; ++j )
{
float z;
float pts[4];
DtexPixelGetPoint( (this->m_pixel), j, &z, ( float * )pts );
z = ClampDepth( z );
double red = ZeroNAN( pts[0] );
double green = ZeroNAN( pts[1] );
double blue = ZeroNAN( pts[2] );
double alpha = ClampAlpha( pts[3] );
span_type& spanJ = (this->m_spans)[j];
spanJ.clear();
spanJ.in = z;
spanJ.out = z;
spanJ.viz = ClampViz( 1.0 - alpha );
spanJ.index = j;
// Only unpremult if the data is assumed to be premultiplied,
// which is when the params say DON'T multiply color by alpha.
if ( alpha > 0.0 && !(this->m_params).multiplyColorByAlpha )
{
spanJ.rgb[0] = red / alpha;
spanJ.rgb[1] = green / alpha;
spanJ.rgb[2] = blue / alpha;
}
else
{
spanJ.rgb[0] = red;
spanJ.rgb[1] = green;
spanJ.rgb[2] = blue;
}
}
// Sort the spans.
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
// Combine identical depths.
double maxDensity = PXDU_MIN_NON_ZERO_DENSITY;
{
int activeBegin = 0;
int activeEnd = 0;
float interestingDepth = 0.0f;
int numRemoved = 0;
while ( activeBegin < i_numPts )
{
span_type& spanActiveBegin = (this->m_spans)[activeBegin];
float nextInterestingDepth = spanActiveBegin.in;
assert( nextInterestingDepth > interestingDepth );
activeEnd = i_numPts;
for ( int a = activeBegin + 1; a < i_numPts; ++a )
{
span_type& spanNext = (this->m_spans)[a];
assert( spanNext.in > interestingDepth );
assert( spanNext.in >= nextInterestingDepth );
if ( spanNext.in > nextInterestingDepth )
{
// This span is not active in this round,
// set activeEnd and get out.
activeEnd = a;
break;
}
else
{
// This span has an identical depth to
// the previous one, so we must combine their
// alphas and eliminate the depth.
// We simply add their unpremultiplied color.
spanActiveBegin.viz *= spanNext.viz;
spanActiveBegin.rgb[0] += spanNext.rgb[0];
spanActiveBegin.rgb[1] += spanNext.rgb[1];
spanActiveBegin.rgb[2] += spanNext.rgb[2];
spanNext.in = FLT_MAX;
spanNext.out = FLT_MAX;
++numRemoved;
}
}
spanActiveBegin.viz = ClampViz( spanActiveBegin.viz );
// Accumulate density from here to the next point.
if ( activeEnd < i_numPts )
{
span_type& spanNext = (this->m_spans)[activeEnd];
double dz = spanNext.in - spanActiveBegin.in;
assert( spanNext.in > spanActiveBegin.in );
assert( dz > 0.0 );
double density = DensityFromVizDz( spanActiveBegin.viz,
dz );
maxDensity = std::max( maxDensity, density );
}
activeBegin = activeEnd;
interestingDepth = nextInterestingDepth;
}
// If any removed, re-sort the list and remove the end
// points.
if ( numRemoved > 0 )
{
assert( numRemoved < i_numPts );
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
i_numPts -= numRemoved;
(this->m_spans).resize( i_numPts );
}
}
// Handle the single point case.
if ( i_numPts == 1 )
{
span_type& span0 = (this->m_spans)[0];
if ( (this->m_params).discardZeroAlphaSamples &&
span0.viz >= 1.0 )
{
// Nothing!
return;
}
span0.out = ClampDepth(
IncrementPositiveFloat( span0.in ) );
double alpha = ClampAlpha( 1.0 - span0.viz );
// If the alpha is zero, and we're still here, it means
// that the spans are either completely transparent and
// the user has elected to keep them anyway, in which case
// no multiplication by alpha is needed, or alternatively,
// they're "glow" spans which have zero alpha but non-zero
// color. Those glow spans were not unpremultiplied above,
// and therefore do not need to be premultiplied here.
// SO! If alpha is zero, we don't premultiply.
if ( alpha > 0.0 )
{
span0.rgb[0] *= alpha;
span0.rgb[1] *= alpha;
span0.rgb[2] *= alpha;
}
(this->m_deepOutPixel).push_back( span0.in,
span0.out,
span0.rgb[0],
span0.rgb[1],
span0.rgb[2],
alpha );
return;
}
// Put the spans back out.
// If the last point has a non-zero alpha, extrapolate the
// maximum density to create an end point.
for ( int j = 0; j < i_numPts; ++j )
{
span_type& spanJ = (this->m_spans)[j];
if ( (this->m_params).discardZeroAlphaSamples &&
spanJ.viz >= 1.0 )
{
// This span is transparent, ignore it.
continue;
}
if ( j < i_numPts-1 )
{
spanJ.out = (this->m_spans)[j+1].in;
}
else
{
// This is the last point.
// If it has non-zero alpha, it needs depth,
// which we use the max density for.
if ( spanJ.viz >= 1.0 )
{
// Don't need to worry about this last span!
// It is at the end of the continuous span, and
// is completely transparent.
continue;
}
double dz = DzFromVizDensity( spanJ.viz, maxDensity );
spanJ.out = ClampDepth( spanJ.in + dz );
if ( spanJ.out <= spanJ.in )
{
spanJ.out =
ClampDepth( IncrementPositiveFloat( spanJ.in ) );
}
}
double alpha = ClampAlpha( 1.0 - spanJ.viz );
// If the alpha is zero, and we're still here, it means
// that the spans are either completely transparent and
// the user has elected to keep them anyway, in which case
// no multiplication by alpha is needed, or alternatively,
// they're "glow" spans which have zero alpha but non-zero
// color. Those glow spans were not unpremultiplied above,
// and therefore do not need to be premultiplied here.
// SO! If alpha is zero, we don't premultiply.
if ( alpha > 0.0 )
{
spanJ.rgb[0] *= alpha;
spanJ.rgb[1] *= alpha;
spanJ.rgb[2] *= alpha;
}
// Set the channels!
(this->m_deepOutPixel).push_back( spanJ.in,
spanJ.out,
spanJ.rgb[0],
spanJ.rgb[1],
spanJ.rgb[2],
alpha );
}
}
//-*****************************************************************************
template <typename RGBA_T>
void FourChanDeepRgbaDiscrete<RGBA_T>::processDeepPixel( int i_numPts )
{
assert( i_numPts > 0 );
// Loop over all the dtex points and get their deepAlphas
// and their depths. Enforce the case that deepAlpha
// is always between 0 and 1.
(this->m_spans).resize( ( size_t )i_numPts );
for ( int j = 0; j < i_numPts; ++j )
{
float z;
float pts[4];
DtexPixelGetPoint( (this->m_pixel), j, &z, ( float * )pts );
z = ClampDepth( z );
double red = ZeroNAN( pts[0] );
double green = ZeroNAN( pts[1] );
double blue = ZeroNAN( pts[2] );
double alpha = ClampAlpha( pts[3] );
span_type& spanJ = (this->m_spans)[j];
spanJ.clear();
spanJ.in = z;
spanJ.out = z;
spanJ.viz = ClampViz( 1.0 - alpha );
spanJ.index = j;
// Only unpremult if the data is assumed to be premultiplied,
// which is when the params say DON'T multiply color by alpha.
if ( alpha > 0.0 && !(this->m_params).multiplyColorByAlpha )
{
spanJ.rgb[0] = red / alpha;
spanJ.rgb[1] = green / alpha;
spanJ.rgb[2] = blue / alpha;
}
else
{
spanJ.rgb[0] = red;
spanJ.rgb[1] = green;
spanJ.rgb[2] = blue;
}
}
// Sort the spans.
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
// Combine identical depths.
{
int activeBegin = 0;
int activeEnd = 0;
float interestingDepth = 0.0f;
int numRemoved = 0;
while ( activeBegin < i_numPts )
{
span_type& spanActiveBegin = (this->m_spans)[activeBegin];
float nextInterestingDepth = spanActiveBegin.in;
assert( nextInterestingDepth > interestingDepth );
activeEnd = i_numPts;
for ( int a = activeBegin + 1; a < i_numPts; ++a )
{
span_type& spanNext = (this->m_spans)[a];
assert( spanNext.in > interestingDepth );
assert( spanNext.in >= nextInterestingDepth );
if ( spanNext.in > nextInterestingDepth )
{
// This span is not active in this round,
// set activeEnd and get out.
activeEnd = a;
break;
}
else
{
// This span has an identical depth to
// the previous one, so we must combine their
// alphas and eliminate the depth.
// We simply add their unpremultiplied color.
spanActiveBegin.viz *= spanNext.viz;
spanActiveBegin.rgb[0] += spanNext.rgb[0];
spanActiveBegin.rgb[1] += spanNext.rgb[1];
spanActiveBegin.rgb[2] += spanNext.rgb[2];
spanNext.in = FLT_MAX;
spanNext.out = FLT_MAX;
++numRemoved;
}
}
spanActiveBegin.viz = ClampViz( spanActiveBegin.viz );
activeBegin = activeEnd;
interestingDepth = nextInterestingDepth;
}
// If any removed, re-sort the list and remove the end
// points.
if ( numRemoved > 0 )
{
assert( numRemoved < i_numPts );
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
i_numPts -= numRemoved;
(this->m_spans).resize( i_numPts );
}
}
// Put the spans back out.
// If the last point has a non-zero alpha, extrapolate the
// maximum density to create an end point.
for ( int j = 0; j < i_numPts; ++j )
{
span_type& spanJ = (this->m_spans)[j];
if ( (this->m_params).discardZeroAlphaSamples &&
spanJ.viz >= 1.0 )
{
// This span is transparent, ignore it.
continue;
}
double alpha = ClampAlpha( 1.0 - spanJ.viz );
// If the alpha is zero, and we're still here, it means
// that the spans are either completely transparent and
// the user has elected to keep them anyway, in which case
// no multiplication by alpha is needed, or alternatively,
// they're "glow" spans which have zero alpha but non-zero
// color. Those glow spans were not unpremultiplied above,
// and therefore do not need to be premultiplied here.
// SO! If alpha is zero, we don't premultiply.
if ( alpha > 0.0 )
{
spanJ.rgb[0] *= alpha;
spanJ.rgb[1] *= alpha;
spanJ.rgb[2] *= alpha;
}
// Set the channels!
(this->m_deepOutPixel).push_back( spanJ.in,
spanJ.rgb[0],
spanJ.rgb[1],
spanJ.rgb[2],
alpha );
}
}
} // End namespace PxDeep
#endif

View File

@@ -0,0 +1,410 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar, 2011-2012.
//-*****************************************************************************
#ifndef _PxOneChanDeepAlpha_h_
#define _PxOneChanDeepAlpha_h_
#include "PxDeepUtils.h"
#include "PxBaseDeepHelper.h"
namespace PxDeep {
//-*****************************************************************************
// ONE CHANNEL DEEP ALPHA CONTINUOUS
//-*****************************************************************************
template <typename RGBA_T>
class OneChanDeepAlphaContinuous
: public BaseDeepHelper<RGBA_T,
OneChanDeepAlphaContinuous<RGBA_T>,Span>
{
public:
typedef BaseDeepHelper<RGBA_T,
OneChanDeepAlphaContinuous<RGBA_T>,Span>
super_type;
typedef OneChanDeepAlphaContinuous<RGBA_T> this_type;
typedef typename super_type::span_type span_type;
OneChanDeepAlphaContinuous( DtexFile* i_dtexFile,
int i_numDtexChans,
const Parameters& i_params )
: BaseDeepHelper<RGBA_T,
OneChanDeepAlphaContinuous<RGBA_T>,Span>
( i_dtexFile,
i_numDtexChans,
i_params ) {}
void processDeepPixel( int i_numPts );
};
//-*****************************************************************************
// ONE CHANNEL DEEP ALPHA DISCRETE
//-*****************************************************************************
template <typename RGBA_T>
class OneChanDeepAlphaDiscrete
: public BaseDeepHelper<RGBA_T,
OneChanDeepAlphaDiscrete<RGBA_T>,Span>
{
public:
typedef BaseDeepHelper<RGBA_T,
OneChanDeepAlphaDiscrete<RGBA_T>,Span>
super_type;
typedef OneChanDeepAlphaDiscrete<RGBA_T> this_type;
typedef typename super_type::span_type span_type;
OneChanDeepAlphaDiscrete( DtexFile* i_dtexFile,
int i_numDtexChans,
const Parameters& i_params )
: BaseDeepHelper<RGBA_T,
OneChanDeepAlphaDiscrete<RGBA_T>,Span>
( i_dtexFile,
i_numDtexChans,
i_params ) {}
void processDeepPixel( int i_numPts );
};
//-*****************************************************************************
template <typename RGBA_T>
void OneChanDeepAlphaContinuous<RGBA_T>::processDeepPixel( int i_numPts )
{
assert( i_numPts > 0 );
// Loop over all the dtex points and get their deepAlphas
// and their depths. Enforce the case that deepAlpha
// is always between 0 and 1.
// Also, find a good "best slope" for extraplolation.
(this->m_spans).resize( ( size_t )i_numPts );
for ( int j = 0; j < i_numPts; ++j )
{
float z;
float pts[4];
DtexPixelGetPoint( (this->m_pixel), j, &z, ( float * )pts );
z = ClampDepth( z );
double alpha = ClampAlpha( pts[0] );
span_type& spanJ = (this->m_spans)[j];
spanJ.clear();
spanJ.in = z;
spanJ.out = z;
spanJ.viz = ClampViz( 1.0 - alpha );
spanJ.index = j;
}
// Sort the spans.
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
// Combine identical depths, gathering max density along
// the way.
double maxDensity = PXDU_MIN_NON_ZERO_DENSITY;
{
int activeBegin = 0;
int activeEnd = 0;
float interestingDepth = 0.0f;
int numRemoved = 0;
while ( activeBegin < i_numPts )
{
span_type& spanActiveBegin = (this->m_spans)[activeBegin];
float nextInterestingDepth = spanActiveBegin.in;
assert( nextInterestingDepth > interestingDepth );
activeEnd = i_numPts;
for ( int a = activeBegin + 1; a < i_numPts; ++a )
{
span_type& spanNext = (this->m_spans)[a];
assert( spanNext.in > interestingDepth );
assert( spanNext.in >= nextInterestingDepth );
if ( spanNext.in > nextInterestingDepth )
{
// This span is not active in this round,
// set activeEnd and get out.
activeEnd = a;
break;
}
else
{
// This span has an identical depth to
// the previous one, so we must combine their
// vizs and eliminate the depth.
spanActiveBegin.viz *= spanNext.viz;
spanNext.in = FLT_MAX;
spanNext.out = FLT_MAX;
++numRemoved;
}
}
spanActiveBegin.viz = ClampViz( spanActiveBegin.viz );
// Accumulate density from here to the next point.
if ( activeEnd < i_numPts )
{
span_type& spanNext = (this->m_spans)[activeEnd];
double dz = spanNext.in - spanActiveBegin.in;
assert( spanNext.in > spanActiveBegin.in );
assert( dz > 0.0 );
double density = DensityFromVizDz( spanActiveBegin.viz,
dz );
maxDensity = std::max( maxDensity, density );
}
activeBegin = activeEnd;
interestingDepth = nextInterestingDepth;
}
// If any removed, re-sort the list and remove the end
// points.
if ( numRemoved > 0 )
{
assert( numRemoved < i_numPts );
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
i_numPts -= numRemoved;
(this->m_spans).resize( i_numPts );
}
}
// Handle the single point case.
if ( i_numPts == 1 )
{
span_type& span0 = (this->m_spans)[0];
if ( (this->m_params).discardZeroAlphaSamples &&
span0.viz >= 1.0 )
{
// Nothing!
return;
}
span0.out = ClampDepth( IncrementPositiveFloat( span0.in ) );
float alphaF = ClampAlpha( 1.0 - span0.viz );
(this->m_deepOutPixel).push_back( span0.in,
span0.out,
alphaF );
return;
}
// Put the spans back out.
// If the last point has a non-zero alpha, extrapolate the
// maximum density to create an end point.
for ( int j = 0; j < i_numPts; ++j )
{
span_type& spanJ = (this->m_spans)[j];
if ( (this->m_params).discardZeroAlphaSamples &&
spanJ.viz >= 1.0 )
{
// This span is transparent, ignore it.
continue;
}
// Set the out points.
if ( j < i_numPts-1 )
{
spanJ.out = (this->m_spans)[j+1].in;
}
else
{
// This is the last point.
// If it has non-zero alpha, it needs depth,
// which we use the max density for.
if ( spanJ.viz >= 1.0 )
{
// Don't need to worry about this last span!
// It is at the end of the continuous span, and
// is completely transparent.
continue;
}
double dz = DzFromVizDensity( spanJ.viz, maxDensity );
spanJ.out = ClampDepth( spanJ.in + dz );
if ( spanJ.out <= spanJ.in )
{
spanJ.out = ClampDepth(
IncrementPositiveFloat( spanJ.in ) );
}
}
float alphaF = ClampAlpha( 1.0 - spanJ.viz );
(this->m_deepOutPixel).push_back( spanJ.in,
spanJ.out,
alphaF );
}
}
//-*****************************************************************************
template <typename RGBA_T>
void OneChanDeepAlphaDiscrete<RGBA_T>::processDeepPixel( int i_numPts )
{
assert( i_numPts > 0 );
// Loop over all the dtex points and get their deepAlphas
// and their depths. Enforce the case that deepAlpha
// is always between 0 and 1.
// Also, find a good "best slope" for extraplolation.
(this->m_spans).resize( ( size_t )i_numPts );
for ( int j = 0; j < i_numPts; ++j )
{
float z;
float pts[4];
DtexPixelGetPoint( (this->m_pixel), j, &z, ( float * )pts );
z = ClampDepth( z );
double alpha = ClampAlpha( pts[0] );
span_type& spanJ = (this->m_spans)[j];
spanJ.clear();
spanJ.in = z;
spanJ.viz = ClampViz( 1.0 - alpha );
spanJ.index = j;
}
// Sort the spans.
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
// Combine identical depths.
{
int activeBegin = 0;
int activeEnd = 0;
float interestingDepth = 0.0f;
int numRemoved = 0;
while ( activeBegin < i_numPts )
{
span_type& spanActiveBegin = (this->m_spans)[activeBegin];
float nextInterestingDepth = spanActiveBegin.in;
assert( nextInterestingDepth > interestingDepth );
activeEnd = i_numPts;
for ( int a = activeBegin + 1; a < i_numPts; ++a )
{
span_type& spanNext = (this->m_spans)[a];
assert( spanNext.in > interestingDepth );
assert( spanNext.in >= nextInterestingDepth );
if ( spanNext.in > nextInterestingDepth )
{
// This span is not active in this round,
// set activeEnd and get out.
activeEnd = a;
break;
}
else
{
// This span has an identical depth to
// the previous one, so we must combine their
// alphas and eliminate the depth.
spanActiveBegin.viz *= spanNext.viz;
spanNext.in = FLT_MAX;
++numRemoved;
}
}
spanActiveBegin.viz = ClampViz( spanActiveBegin.viz );
activeBegin = activeEnd;
interestingDepth = nextInterestingDepth;
}
// If any removed, re-sort the list and remove the end
// points.
if ( numRemoved > 0 )
{
assert( numRemoved < i_numPts );
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
i_numPts -= numRemoved;
(this->m_spans).resize( i_numPts );
}
}
// Put the spans back out.
for ( int j = 0; j < i_numPts; ++j )
{
span_type& spanJ = (this->m_spans)[j];
if ( (this->m_params).discardZeroAlphaSamples &&
spanJ.viz >= 1.0 )
{
// This span is transparent, ignore it.
continue;
}
float alphaF = ClampAlpha( 1.0 - spanJ.viz );
// Set the channels!
(this->m_deepOutPixel).push_back( spanJ.in,
alphaF );
}
}
} // End namespace PxDeep
#endif

View File

@@ -0,0 +1,497 @@
//-*****************************************************************************
// Copyright (c) 2012, Pixar. All rights reserved. *
// *
// This license governs use of the accompanying software. If you *
// use the software, you accept this license. If you do not accept *
// the license, do not use the software. *
// *
// 1. Definitions *
// The terms "reproduce," "reproduction," "derivative works," and *
// "distribution" have the same meaning here as under U.S. *
// copyright law. A "contribution" is the original software, or *
// any additions or changes to the software. *
// A "contributor" is any person or entity that distributes its *
// contribution under this license. *
// "Licensed patents" are a contributor's patent claims that read *
// directly on its contribution. *
// *
// 2. Grant of Rights *
// (A) Copyright Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free copyright license to reproduce its contribution, *
// prepare derivative works of its contribution, and distribute *
// its contribution or any derivative works that you create. *
// (B) Patent Grant- Subject to the terms of this license, *
// including the license conditions and limitations in section 3, *
// each contributor grants you a non-exclusive, worldwide, *
// royalty-free license under its licensed patents to make, have *
// made, use, sell, offer for sale, import, and/or otherwise *
// dispose of its contribution in the software or derivative works *
// of the contribution in the software. *
// *
// 3. Conditions and Limitations *
// (A) No Trademark License- This license does not grant you *
// rights to use any contributor's name, logo, or trademarks. *
// (B) If you bring a patent claim against any contributor over *
// patents that you claim are infringed by the software, your *
// patent license from such contributor to the software ends *
// automatically. *
// (C) If you distribute any portion of the software, you must *
// retain all copyright, patent, trademark, and attribution *
// notices that are present in the software. *
// (D) If you distribute any portion of the software in source *
// code form, you may do so only under this license by including a *
// complete copy of this license with your distribution. If you *
// distribute any portion of the software in compiled or object *
// code form, you may only do so under a license that complies *
// with this license. *
// (E) The software is licensed "as-is." You bear the risk of *
// using it. The contributors give no express warranties, *
// guarantees or conditions. You may have additional consumer *
// rights under your local laws which this license cannot change. *
// To the extent permitted under your local laws, the contributors *
// exclude the implied warranties of merchantability, fitness for *
// a particular purpose and non-infringement. *
//-*****************************************************************************
//-*****************************************************************************
// Written by Pixar, 2011-2012.
//-*****************************************************************************
#ifndef _PxOneChanDeepOpacity_h_
#define _PxOneChanDeepOpacity_h_
#include "PxDeepUtils.h"
#include "PxBaseDeepHelper.h"
namespace PxDeep {
//-*****************************************************************************
// ONE CHANNEL DEEP OPACITY CONTINUOUS
//-*****************************************************************************
template <typename RGBA_T>
class OneChanDeepOpacityContinuous
: public BaseDeepHelper<RGBA_T,
OneChanDeepOpacityContinuous<RGBA_T>,SpanOpac>
{
public:
typedef BaseDeepHelper<RGBA_T,
OneChanDeepOpacityContinuous<RGBA_T>,SpanOpac>
super_type;
typedef OneChanDeepOpacityContinuous<RGBA_T> this_type;
typedef typename super_type::span_type span_type;
OneChanDeepOpacityContinuous( DtexFile* i_dtexFile,
int i_numDtexChans,
const Parameters& i_params )
: BaseDeepHelper<RGBA_T,
OneChanDeepOpacityContinuous<RGBA_T>,SpanOpac>
( i_dtexFile,
i_numDtexChans,
i_params ) {}
void processDeepPixel( int i_numPts );
};
//-*****************************************************************************
// ONE CHANNEL DEEP OPACITY DISCRETE
//-*****************************************************************************
template <typename RGBA_T>
class OneChanDeepOpacityDiscrete
: public BaseDeepHelper<RGBA_T,
OneChanDeepOpacityDiscrete<RGBA_T>,SpanOpac>
{
public:
typedef BaseDeepHelper<RGBA_T,
OneChanDeepOpacityDiscrete<RGBA_T>,SpanOpac>
super_type;
typedef OneChanDeepOpacityDiscrete<RGBA_T> this_type;
typedef typename super_type::span_type span_type;
OneChanDeepOpacityDiscrete( DtexFile* i_dtexFile,
int i_numDtexChans,
const Parameters& i_params )
: BaseDeepHelper<RGBA_T,
OneChanDeepOpacityDiscrete<RGBA_T>,SpanOpac>
( i_dtexFile,
i_numDtexChans,
i_params ) {}
void processDeepPixel( int i_numPts );
};
//-*****************************************************************************
template <typename RGBA_T>
void OneChanDeepOpacityContinuous<RGBA_T>::processDeepPixel( int i_numPts )
{
assert( i_numPts > 0 );
// Loop over all the dtex points and get their deepOpacities and
// depths.
(this->m_spans).resize( ( size_t )i_numPts );
for ( int j = 0; j < i_numPts; ++j )
{
float z;
float pts[4];
DtexPixelGetPoint( (this->m_pixel), j, &z, ( float * )pts );
z = ClampDepth( z );
span_type& spanJ = (this->m_spans)[j];
spanJ.clear();
spanJ.in = z;
spanJ.out = z;
// Data stored in dtex files for "deepopacity" is actually
// "deeptransmission", monotonically decreasing from an initial
// value of 1.0. We just convert it to viz directly.
// (viz == transmissivity)
spanJ.deepViz = ClampViz( pts[0] );
spanJ.index = j;
}
// Sort the spans by depth (and then index)
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
// Combine identical depths, accumulating maximum density
// along the way. Because we have deep opacity,
// coincident samples use the maximum deepOpacity value.
double maxDensity = PXDU_MIN_NON_ZERO_DENSITY;
{
int prevSpanIndex = 0;
int activeBegin = 0;
int activeEnd = 0;
float interestingDepth = 0.0f;
int numRemoved = 0;
while ( activeBegin < i_numPts )
{
span_type& spanActiveBegin = (this->m_spans)[activeBegin];
float nextInterestingDepth = spanActiveBegin.in;
assert( nextInterestingDepth > interestingDepth );
// This loop combines all the coincident samples
// into a single sample, invalidates the other coincident
// samples, and sets activeEnd to point to the next
// sample with a larger depth.
activeEnd = i_numPts;
for ( int a = activeBegin + 1; a < i_numPts; ++a )
{
span_type& spanNext = (this->m_spans)[a];
assert( spanNext.in > interestingDepth );
assert( spanNext.in >= nextInterestingDepth );
if ( spanNext.in > nextInterestingDepth )
{
// This span is not active in this round,
// set activeEnd and get out.
activeEnd = a;
break;
}
else
{
// This span has an identical depth to
// the previous one, so we use whichever one has the
// largest deep opacity, which equates to the
// smallest deep viz.
spanActiveBegin.deepViz =
std::min( spanActiveBegin.deepViz,
spanNext.deepViz );
spanNext.in = FLT_MAX;
spanNext.out = FLT_MAX;
++numRemoved;
}
}
// Okay, the deep vizibility at our in point
// is equal to the total vizibility before us,
// which is the deep vizibility at the previous point,
// times the vizibility of this point.
// deepViz = deepVizPrev * viz
// viz = deepViz / deepVizPrev;
if ( activeBegin == 0 )
{
spanActiveBegin.viz = spanActiveBegin.deepViz;
}
else
{
span_type& spanPrev = (this->m_spans)[prevSpanIndex];
// Make sure the deep visibilities are
// monotonically decreasing with depth.
spanActiveBegin.deepViz =
std::min( spanActiveBegin.deepViz,
spanPrev.deepViz );
if ( spanPrev.deepViz > 0.0 )
{
// If we have non-zero accumulated visibility,
// we can compute the span visibility.
spanActiveBegin.viz = spanActiveBegin.deepViz /
spanPrev.deepViz;
}
else
{
// If we have zero accumulated visibility,
// then the span visibility is also zero.
spanActiveBegin.viz = 0.0;
}
// Use the viz of this span to update the
// max density.
spanActiveBegin.viz = ClampViz( spanActiveBegin.viz );
spanActiveBegin.in = spanPrev.out;
double dz = spanActiveBegin.out - spanActiveBegin.in;
assert( dz > 0.0 );
assert( spanActiveBegin.out > spanActiveBegin.in );
double density = DensityFromVizDz( spanActiveBegin.viz,
dz );
maxDensity = std::max( maxDensity, density );
}
prevSpanIndex = activeBegin;
activeBegin = activeEnd;
interestingDepth = nextInterestingDepth;
}
// If any removed, re-sort the list and remove the end
// points.
if ( numRemoved > 0 )
{
assert( numRemoved < i_numPts );
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
i_numPts -= numRemoved;
(this->m_spans).resize( i_numPts );
}
}
// Handle the single point case.
if ( i_numPts == 1 )
{
span_type& span0 = (this->m_spans)[0];
if ( (this->m_params).discardZeroAlphaSamples &&
span0.viz >= 1.0 )
{
// Nothing!
return;
}
span0.in = ClampDepth( DecrementPositiveFloat( span0.out ) );
float alphaF = ClampAlpha( 1.0 - span0.viz );
(this->m_deepOutPixel).push_back( span0.in,
span0.out,
alphaF );
return;
}
// Put the spans back out.
// If the first point has a non-zero alpha, extrapolate the
// maximum density to create a begin point.
for ( int j = 0; j < i_numPts; ++j )
{
span_type& spanJ = (this->m_spans)[j];
if ( (this->m_params.discardZeroAlphaSamples) &&
spanJ.viz >= 1.0 )
{
// This span is transparent, ignore it.
continue;
}
if ( j == 0 )
{
// This is first point.
// If it has non-zero alpha, it needs depth,
// which we use the max density for.
if ( spanJ.viz >= 1.0 )
{
// Don't need to worry about this last span!
// It is at the end of the continuous span, and
// is completely transparent.
continue;
}
double dz = DzFromVizDensity( spanJ.viz, maxDensity );
spanJ.in = ClampDepth( spanJ.out - dz );
if ( spanJ.out <= spanJ.in )
{
spanJ.in = ClampDepth(
DecrementPositiveFloat( spanJ.out ) );
}
}
float alphaF = ClampAlpha( 1.0 - spanJ.viz );
// Set the channels!
(this->m_deepOutPixel).push_back( spanJ.in,
spanJ.out,
alphaF );
}
}
//-*****************************************************************************
template <typename RGBA_T>
void OneChanDeepOpacityDiscrete<RGBA_T>::processDeepPixel( int i_numPts )
{
assert( i_numPts > 0 );
// Loop over all the dtex points and get their deepOpacities and
// depths.
(this->m_spans).resize( ( size_t )i_numPts );
for ( int j = 0; j < i_numPts; ++j )
{
float z;
float pts[4];
DtexPixelGetPoint( (this->m_pixel), j, &z, ( float * )pts );
z = ClampDepth( z );
span_type& spanJ = (this->m_spans)[j];
spanJ.clear();
spanJ.in = z;
spanJ.out = z;
// Data stored in dtex files for "deepopacity" is actually
// "deeptransmission", monotonically decreasing from an initial
// value of 1.0. We just convert it to viz directly.
// (viz == transmissivity)
spanJ.deepViz = ClampViz( pts[0] );
spanJ.index = j;
}
// Sort the spans.
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
// Combine identical depths. Because we have deep opacity,
// coincident samples use the maximum deepOpacity value.
{
int prevSpanIndex = 0;
int activeBegin = 0;
int activeEnd = 0;
float interestingDepth = 0.0f;
int numRemoved = 0;
while ( activeBegin < i_numPts )
{
span_type& spanActiveBegin = (this->m_spans)[activeBegin];
float nextInterestingDepth = spanActiveBegin.in;
assert( nextInterestingDepth > interestingDepth );
// This loop combines all the coincident samples
// into a single sample, invalidates the other coincident
// samples, and sets activeEnd to point to the next
// sample with a larger depth.
activeEnd = i_numPts;
for ( int a = activeBegin + 1; a < i_numPts; ++a )
{
span_type& spanNext = (this->m_spans)[a];
assert( spanNext.in > interestingDepth );
assert( spanNext.in >= nextInterestingDepth );
if ( spanNext.in > nextInterestingDepth )
{
// This span is not active in this round,
// set activeEnd and get out.
activeEnd = a;
break;
}
else
{
// This span has an identical depth to
// the previous one, so we use whichever one has the
// largest deep opacity, which equates to the
// smallest deep viz.
spanActiveBegin.deepViz =
std::min( spanActiveBegin.deepViz,
spanNext.deepViz );
spanNext.in = FLT_MAX;
spanNext.out = FLT_MAX;
++numRemoved;
}
}
// Okay, the deep vizibility at our in point
// is equal to the total vizibility before us,
// which is the deep vizibility at the previous point,
// times the vizibility of this point.
// deepViz = deepVizPrev * viz
// viz = deepViz / deepVizPrev;
if ( activeBegin == 0 )
{
spanActiveBegin.viz = spanActiveBegin.deepViz;
}
else
{
span_type& spanPrev = (this->m_spans)[prevSpanIndex];
// Make sure the deep visibilities are
// monotonically decreasing with depth.
spanActiveBegin.deepViz =
std::min( spanActiveBegin.deepViz,
spanPrev.deepViz );
if ( spanPrev.deepViz > 0.0 )
{
// If we have non-zero accumulated visibility,
// we can compute the span visibility.
spanActiveBegin.viz = spanActiveBegin.deepViz /
spanPrev.deepViz;
}
else
{
// If we have zero accumulated visibility,
// then the span visibility is also zero.
spanActiveBegin.viz = 0.0;
}
// Clean up the viz!
spanActiveBegin.viz = ClampViz( spanActiveBegin.viz );
}
prevSpanIndex = activeBegin;
activeBegin = activeEnd;
interestingDepth = nextInterestingDepth;
}
// If any removed, re-sort the list and remove the end
// points.
if ( numRemoved > 0 )
{
assert( numRemoved < i_numPts );
std::sort( (this->m_spans).begin(), (this->m_spans).end() );
i_numPts -= numRemoved;
(this->m_spans).resize( i_numPts );
}
}
// Put the spans back out.
for ( int j = 0; j < i_numPts; ++j )
{
span_type& spanJ = (this->m_spans)[j];
if ( (this->m_params).discardZeroAlphaSamples &&
spanJ.viz >= 1.0 )
{
// This span is transparent, ignore it.
continue;
}
float alphaF = ClampAlpha( 1.0 - spanJ.viz );
(this->m_deepOutPixel).push_back( spanJ.in,
alphaF );
}
}
} // End namespace PxDeep
#endif

View File

@@ -0,0 +1,85 @@
//-*****************************************************************************
Pixar's Dtex to Exr conversion utility
Aug 1, 2012 - first checkin to OpenEXR 2.0 branch of OpenEXR git repository.
This utility converts a DTEX deep shadow file to an OpenEXR 2.0 deep exr file,
formerly, ".odz" (or .dexr, or whatever extension your facility may use). As of
the first checkin, the utility only supports 1, 3, or 4-channel dtex files,
corresponding to deep alpha or deep RGBA only. The Nuke DTEX reader, which
uses basically the same code, will support a more complete arbitrary channel
set, and this utility may be upgraded as well. We also only support a single
view for the time being.
DTEX has a complicated set of interpretations, which represent six separate
code paths for conversion to the deep representation in OpenEXR 2.0. They
represent the permutations of these exemplary Display Driver config strings
to prman:
Display "+filename.dtex" "deepshad" "deepopacity" "string volumeinterpretation" "continuous"
Display "+filename.dtex" "deepshad" "deepopacity" "string volumeinterpretation" "discrete"
Display "+filename.dtex" "deepshad" "a" "string volumeinterpretation" "continuous"
Display "+filename.dtex" "deepshad" "a" "string volumeinterpretation" "discrete"
Display "+filename.dtex" "deepshad" "rgba" "string volumeinterpretation" "continuous"
Display "+filename.dtex" "deepshad" "rgba" "string volumeinterpretation" "discrete"
In our terminology, these six options are called:
OneChanDeepOpacityContinuous
OneChanDeepOpacityDiscrete
OneChanDeepAlphaContinuous
OneChanDeepAlphaDiscrete
FourChanDeepRgbaContinuous
FourChanDeepRgbaDiscrete
Renderman will write out both 1-channel and 3-channel opacity in the
"deepopacity" case, which we currently only use the first channel of, as
we are only targeting a single opacity curve in space. This may evolve in
the future.
There are weird gotchas for each of these 6 cases, and they are documented
in the PxDeepUtils.h file, along with specific comments in each of the six
header files that correspond to each case:
PxOneChanDeepOpacityContinuous.h
PxOneChanDeepOpacityDiscrete.h
PxOneChanDeepAlphaContinuous.h
PxOneChanDeepAlphaDiscrete.h
PxFourChanDeepRgbaContinuous.h
PxFourChanDeepRgbaDiscrete.h
The gotchas relate to several issues, mostly to do with coincident or
out-of-order samples, precision issues, compression artifacts, and the
differences between the "deepopacity" vs "deepalpha" interpretations.
With "deepopacity" (the pre-prman 16 usage), opacity values stored in
dtex files were accumulated, so they were bounded between 0 and 1. The
values stored are actually not opacities, but rather transmissivities
(1-opacity), and monotonically decreased from fully transparent (1)
to fully opaque (0). This representation is ideal for meaningful error
minimization during compression, and also for usage as a shadow map
by a renderer, because the extinction at a particular depth, at a
particular pixel, can be evaluated with a single look-up. However,
this representation is poor for deep compositing, because each of the
samples includes data from smaller depth samples, and recombination is
difficult. With these types of files, when using volumetric (continuous)
interpretation, the samples represent the accumulated transmissivity at
the NEAR SIDE of a depth span, and our code paths take this into account.
With all other usages - "a" and "rgba", the values represent filtered
samples of the given field at that point in space. The alpha values
will be between 0 and 1, but are not guaranteed to be increasing or
decreasing. This presents a strange problem for volumetric interpretation,
as what does it mean to describe the alpha of an infintesimally small
region of space (point sample). The best interpretation of the data
in this case uses the alpha to represent the accumulated opacity of
the region of space nearer than the sample, and thus each sample
represents the FAR SIDE of a depth span. Our code paths take this into
account as well.
Please see the files for additional comments, and the command
"dtexToExr" may be run with -h, --h, --help, or no arguments to
print its usage.
-Christopher Horvath, Aug 2012, Pixar

View File

@@ -0,0 +1,60 @@
#! /bin/sh
# If we're on OS X, use glibtoolize instead of toolize
HOSTTYPE=`uname`
if [ "$HOSTTYPE" == "Darwin" ]; then
LIBTOOLIZE=glibtoolize
else
LIBTOOLIZE=libtoolize
fi
# Check Autoconf version
if [ -x `which autoconf` ]; then
AC_VER=`autoconf --version | head -n 1 | sed 's/^[^0-9]*//'`
AC_VER_MAJOR=`echo $AC_VER | cut -f1 -d'.'`
AC_VER_MINOR=`echo $AC_VER | cut -f2 -d'.' | sed 's/[^0-9]*$//'`
if [ "$AC_VER_MAJOR" -lt "2" ]; then
echo "Autoconf 2.13 or greater needed to build configure."
exit 1
fi
if [ "$AC_VER_MINOR" -lt "13" ]; then
echo "Autoconf 2.13 or greater needed to build configure."
exit 1
fi
if [ "$AC_VER_MINOR" -lt "50" ]; then
if [ ! -e configure.in ]; then
ln -s configure.ac configure.in
fi
echo "If you see some warnings about cross-compiling, don't worry; this is normal."
else
rm -f configure.in
fi
else
echo autoconf not found. DtexToExr requires autoconf to bootstrap itself.
exit 1
fi
run_cmd() {
echo running $* ...
if ! $*; then
echo failed!
exit 1
fi
}
# Check if /usr/local/share/aclocal exists
if [ -d /usr/local/share/aclocal ]; then
ACLOCAL_INCLUDE="$ACLOCAL_INCLUDE -I /usr/local/share/aclocal"
fi
run_cmd aclocal -I m4 $ACLOCAL_INCLUDE
run_cmd $LIBTOOLIZE --automake --copy
run_cmd automake --add-missing --copy
run_cmd autoconf
echo
echo "Now type './configure' to configure DtexToExr."
echo

View File

@@ -0,0 +1,223 @@
dnl Process this file with autoconf to produce a configure script.
AC_INIT(DtexToExr, 1.0.0)
AC_SUBST(DTEXTOEXR_VERSION, 1.0.0)
AC_CANONICAL_HOST
AC_CONFIG_SRCDIR(DtexToExr.cpp)
AM_INIT_AUTOMAKE(1.6.3) dnl Require automake 1.6.3 or better
AM_MAINTAINER_MODE
LIBTOOL_CURRENT=6
LIBTOOL_REVISION=0
LIBTOOL_AGE=0
LIBTOOL_VERSION=$LIBTOOL_CURRENT:$LIBTOOL_REVISION:$LIBTOOL_AGE
AC_SUBST(LIBTOOL_VERSION)
dnl Checks for programs.
AC_PROG_CXX
AC_PROG_INSTALL
AC_PROG_CC
AC_PROG_LN_S
AC_PROG_LIBTOOL
AC_PROG_MAKE_SET
dnl
dnl PKGCONFIG preparations
dnl
if test -z "${PKG_CONFIG_PATH}"; then
PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig:/usr/local/lib/pkgconfig:/usr/lib/pkgconfig
fi
export PKG_CONFIG_PATH
LIB64_IF_EXISTS=""
if [[ -e /usr/lib64 ]]; then
LIB64_IF_EXISTS="-L/usr/lib64"
fi
dnl
dnl get ccflags and libs from openexr and prmansdk packages
dnl
dnl
dnl get ccflags and libs from other packages in use and check
dnl whether test programs compile.
dnl OpenEXR is required. IlmBase is required.
dnl
dnl
dnl check openexr
dnl
AM_PATH_PKGCONFIG(
[OPENEXR_CXXFLAGS],
[OPENEXR_LDFLAGS],
[OPENEXR_LIBS],
[OpenEXR],
[OpenEXR],
[$LIB64_IF_EXISTS -L/usr/local/lib],
[-lIlmImf -lImath -lIex -lHalf -lz -lpthread],
[openexr-prefix])
PRMANSDK_CXXFLAGS=""
PRMANSDK_LDFLAGS=""
PRMANSDK_LIBS=""
PRMANSDK_LIBNAME="prman"
AC_ARG_WITH(
[prmansdk-include-dir],
[AS_HELP_STRING([--with-prmansdk-include-dir],
[prman sdk include directory])],
[PRMANSDK_CXXFLAGS="-I$withval"])
AC_ARG_WITH(
[prmansdk-lib-dir],
[AS_HELP_STRING([--with-prmansdk-lib-dir],
[prman sdk library directory])],
[PRMANSDK_LDFLAGS="-L$withval -Wl,-rpath $withval"])
AC_ARG_WITH(
[prmansdk-libname],
[AS_HELP_STRING([--with-prmansdk-libname],
[prman sdk library name (default:prman)])],
[PRMANSDK_LIBNAME="$withval"])
PRMANSDK_LIBS="-l$PRMANSDK_LIBNAME"
export PRMANSDK_CXXFLAGS
export PRMANSDK_LDFLAGS
export PRMANSDK_LIBS
export PRMANSDK_LIBNAME
AC_SUBST([PRMANSDK_CXXFLAGS])
AC_SUBST([PRMANSDK_LDFLAGS])
AC_SUBST([PRMANSDK_LIBS])
AC_SUBST([PRMANSDK_LIBNAME])
CXXFLAGS="$CXXFLAGS $PRMANSDK_CXXFLAGS $OPENEXR_CXXFLAGS"
LDFLAGS="$LDFLAGS $PRMANSDK_LDFLAGS $OPENEXR_LDFLAGS"
dnl
dnl OpenEXR test program
dnl
AM_COMPILELINKRUN(
[OpenEXR],
[openexrtest],
[$OPENEXR_CXXFLAGS],
[$OPENEXR_LDFLAGS],
[$OPENEXR_LIBS],[[
#include <stdlib.h>
#include <ImfTestFile.h>
#include <OpenEXRConfig.h>
]],
[[OPENEXR_IMF_NAMESPACE::isOpenExrFile("notExist");]],
AC_MSG_RESULT([Compiled and ran OpenEXR test program.]),
AC_MSG_ERROR([Could not compile OpenEXR test program.]))
dnl
dnl Dtex test program
dnl
AM_COMPILELINKRUN(
[PrmanSDK],
[prmansdktest],
[$PRMANSDK_CXXFLAGS],
[$PRMANSDK_LDFLAGS],
[$PRMANSDK_LIBS],
[[
#include <stdio.h>
#include <stdlib.h>
#include <dtex.h>
]],
[[
DtexCache* dtexCache = DtexCreateCache( 10000, NULL );
if ( dtexCache ) { DtexDestroyCache( dtexCache ); }
]],
AC_MSG_RESULT([Compiled and ran PrmanSDK test program.]),
AC_MSG_ERROR([Could not compile PrmanSDK test program.]))
dnl
dnl if some autoconf expert knows how to get the actual prefix used, please
dnl tell us. Until then...
dnl
if test "x$prefix" != "xNONE"; then
ACTUAL_PREFIX=$prefix
else
ACTUAL_PREFIX=/usr/local
fi
dnl Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS(limits.h unistd.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
dnl gcc optimization
AC_MSG_CHECKING(for gcc optimization flags)
old_cflags=$CFLAGS
CFLAGS="$CFLAGS -pipe"
AC_TRY_COMPILE([#include <stdio.h>],
[ printf ("hello, world"); ],
[ EXTRA_OPT_CFLAGS="-pipe"],[ EXTRA_OPT_CFLAGS=""])
CFLAGS=$old_cflags
AC_MSG_RESULT([$EXTRA_OPT_CFLAGS])
dnl Platform-specific stuff
case "$host" in
*darwin*)
AC_DEFINE(HAVE_DARWIN)
dnl OS X universal binary support, requires --disable-dependency-tracking
AC_ARG_ENABLE(osx-universal-binaries,
AC_HELP_STRING([--enable-osx-universal-binaries],
[build universal binaries on OS X [[default=no]]]),
[build_osxuniversal="${enableval}"], [build_osxuniversal=no])
if test "${build_osxuniversal}" != no ; then
if test "$enable_dependency_tracking" != no ; then
AC_MSG_ERROR([--enable-osx-universal-binary requires --disable-dependency-tracking.
Please re-run configure with these options:
--disable-dependency-tracking --enable-osx-universal-binary
])
fi
CXXFLAGS="$CXXFLAGS -isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386"
dnl LDFLAGS="$LDFLAGS -Wl,-syslibroot,/Developer/SDKs/MacOSX10.4u.sdk -arch ppc -arch i386"
fi
CXXFLAGS="$CXXFLAGS"
;;
esac
AM_CFLAGS="$EXTRA_OPT_CFLAGS"
AM_CXXFLAGS="$EXTRA_OPT_CFLAGS"
AC_SUBST(AM_CFLAGS)
AC_SUBST(AM_CXXFLAGS)
AC_OUTPUT([
Makefile
])
if test "x$build_osxuniversal" = xyes; then
AC_MSG_RESULT([
---------------------------------------------
Summary for DtexToExr features:
build OS X universal binaries $build_osxuniversal
---------------------------------------------
])
else
AC_MSG_RESULT([
---------------------------------------------
Summary for DtexToExr features:
---------------------------------------------
])
fi

View File

@@ -0,0 +1,171 @@
dnl
dnl
dnl compilelinkrun.m4 - used to check whether a required package is properly
dnl installed. Compiles, links and runs a c++ test program that uses the
dnl package to verify that the package is properly installed
dnl
dnl Expected arguments:
dnl $1: the name of the package we are testing, e.g. "OpenEXR"
dnl used for informational messages, warnings & errors
dnl
dnl $2: the argument passed to configure specifying how to disable this test
dnl for example:
dnl $3 = "openexrtest" and
dnl "configure --disable-openexrtest" will skip the test
dnl
dnl $3: CXXFLAGS used by the test
dnl
dnl $4: LDFLAGS used by the test
dnl
dnl $5: include section of sourcecode for a c++ test program
dnl $6: body section of sourcecode for a c++ test program
dnl The test program should make use of a library that is supposed to
dnl be tested.
dnl
dnl $7: the action to be perfomed if the test succeeds
dnl (e.g. AC_MSG_RESULT("OpenEXR test program succeeded"))
dnl
dnl $8 the action to be perfomed if the test fails
dnl (e.g. AC_MSG_ERROR("OpenEXR test program failed"))
dnl
AC_DEFUN([AM_COMPILELINKRUN],
[
dnl create some local m4 "variables" so that we don't have to use numbers
define([arg_pkg_name],$1)
define([arg_disable],$2)
define([arg_cxxflags],$3)
define([arg_ldflags],$4)
define([arg_libs],$5)
define([arg_include_source],$6)
define([arg_body_source],$7)
define([arg_do_yes],$8)
define([arg_do_no],$9)
dnl check arguments
AC_ARG_ENABLE(arg_disable, [ --disable-arg_disable Do not try to compile and run a test arg_pkg_name program],, enable_programtest=yes)
dnl
dnl if the test hasn't been disabled, then compile, link and run test program
dnl
if test "x$enable_programtest" = "xyes" ; then
dnl basic preliminary checks
AC_MSG_CHECKING(for arg_pkg_name)
test_runs="yes"
dnl save settings and setup c++ before we start
ac_save_CXXFLAGS="$CXXFLAGS"
ac_save_LDFLAGS="$LDFLAGS"
ac_save_LIBS="$LIBS"
CXXFLAGS="$CXXFLAGS arg_cxxflags"
LDFLAGS="$LDFLAGS arg_ldflags"
LIBS="$LIBS arg_libs"
AC_REQUIRE_CPP()
AC_LANG_PUSH([C++])
rm -f conf.testprogram
dnl
dnl first try a complete test - compile, link run
dnl
AC_RUN_IFELSE([AC_LANG_PROGRAM(arg_include_source,
arg_body_source; [[system("touch conf.testprogram"); ]])],
test_runs=yes,
test_runs=no,
[echo $ac_n "cross compiling; assumed OK... $ac_c"])
if test "x$test_runs" = "xyes" || test -f conf.testprogram ; then
AC_MSG_RESULT(yes)
ifelse([arg_do_yes], , :, [arg_do_yes])
else
AC_MSG_RESULT(no)
echo "*** Could not run the arg_pkg_name test program, checking why..."
test_compiles="yes"
test_links="yes"
dnl
dnl if the program did not run, attempt to compile only
dnl
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(arg_include_source,
arg_body_source ; )],
test_compiles=yes,
test_compiles=no)
if test "x$test_compiles" = "xno" ; then
echo "*** The test program could not be compiled. Is arg_pkg_name installed?"
echo "*** Check that the cflags (below) includes the arg_pkg_name include directory"
else
dnl
dnl if the program did compile, try linking
dnl
AC_LINK_IFELSE([AC_LANG_PROGRAM(arg_include_source,
arg_body_source ; )],
test_links=yes,
test_links=no)
if test "x$test_links" = "xyes"; then
echo "*** The test program compiled and staticly linked, but did not run. This "
echo "*** usually means that the run-time linker is not finding arg_pkg_name or finding"
echo "*** the wrong version of arg_pkg_name."
echo "***"
echo "*** If the linker is not finding arg_pkg_name, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system."
else
echo "*** The arg_pkg_name test program could be compiled, but could not be dynamically."
echo "*** or statically linked."
echo "***"
echo "*** Make sure the LDFLAGS points to the location of the arg_pkg_name library."
echo "*** (e.g. -L/usr/local/lib)."
echo "*** If the run-time linker is not finding arg_pkg_name, you'll need to set your"
echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point"
echo "*** to the installed location Also, make sure you have run ldconfig if that"
echo "*** is required on your system."
fi
fi
dnl
dnl The test failed for some reason. Print out more info,
dnl unset flags and signal an error.
dnl
echo "***"
echo "*** Flags used by the test:"
echo "*** cflags: $CXXFLAGS "
echo "*** ldflags: $LDFLAGS"
echo "***"
echo "*** You can also run configure with --disable-arg_disable to skip this test."
ifelse([arg_do_no], , :, [arg_do_no])
fi
AC_LANG_POP([C++])
CXXFLAGS="$ac_save_CXXFLAGS"
LDFLAGS="$ac_save_LDFLAGS"
LIBS="$ac_save_LIBS"
dnl
dnl clean up
dnl
rm -f conf.testprogram
fi
dnl clean up local "variables"
undefine([arg_pkg_name])
undefine([arg_disable])
undefine([arg_cxxflags])
undefine([arg_ldflags])
undefine([arg_libs])
undefine([arg_include_source])
undefine([arg_body_source])
undefine([arg_do_yes])
undefine([arg_do_no])
])

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,368 @@
# Helper functions for option handling. -*- Autoconf -*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltoptions.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])])
# _LT_MANGLE_OPTION(MACRO-NAME, OPTION-NAME)
# ------------------------------------------
m4_define([_LT_MANGLE_OPTION],
[[_LT_OPTION_]m4_bpatsubst($1__$2, [[^a-zA-Z0-9_]], [_])])
# _LT_SET_OPTION(MACRO-NAME, OPTION-NAME)
# ---------------------------------------
# Set option OPTION-NAME for macro MACRO-NAME, and if there is a
# matching handler defined, dispatch to it. Other OPTION-NAMEs are
# saved as a flag.
m4_define([_LT_SET_OPTION],
[m4_define(_LT_MANGLE_OPTION([$1], [$2]))dnl
m4_ifdef(_LT_MANGLE_DEFUN([$1], [$2]),
_LT_MANGLE_DEFUN([$1], [$2]),
[m4_warning([Unknown $1 option `$2'])])[]dnl
])
# _LT_IF_OPTION(MACRO-NAME, OPTION-NAME, IF-SET, [IF-NOT-SET])
# ------------------------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
m4_define([_LT_IF_OPTION],
[m4_ifdef(_LT_MANGLE_OPTION([$1], [$2]), [$3], [$4])])
# _LT_UNLESS_OPTIONS(MACRO-NAME, OPTION-LIST, IF-NOT-SET)
# -------------------------------------------------------
# Execute IF-NOT-SET unless all options in OPTION-LIST for MACRO-NAME
# are set.
m4_define([_LT_UNLESS_OPTIONS],
[m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[m4_ifdef(_LT_MANGLE_OPTION([$1], _LT_Option),
[m4_define([$0_found])])])[]dnl
m4_ifdef([$0_found], [m4_undefine([$0_found])], [$3
])[]dnl
])
# _LT_SET_OPTIONS(MACRO-NAME, OPTION-LIST)
# ----------------------------------------
# OPTION-LIST is a space-separated list of Libtool options associated
# with MACRO-NAME. If any OPTION has a matching handler declared with
# LT_OPTION_DEFINE, dispatch to that macro; otherwise complain about
# the unknown option and exit.
m4_defun([_LT_SET_OPTIONS],
[# Set options
m4_foreach([_LT_Option], m4_split(m4_normalize([$2])),
[_LT_SET_OPTION([$1], _LT_Option)])
m4_if([$1],[LT_INIT],[
dnl
dnl Simply set some default values (i.e off) if boolean options were not
dnl specified:
_LT_UNLESS_OPTIONS([LT_INIT], [dlopen], [enable_dlopen=no
])
_LT_UNLESS_OPTIONS([LT_INIT], [win32-dll], [enable_win32_dll=no
])
dnl
dnl If no reference was made to various pairs of opposing options, then
dnl we run the default mode handler for the pair. For example, if neither
dnl `shared' nor `disable-shared' was passed, we enable building of shared
dnl archives by default:
_LT_UNLESS_OPTIONS([LT_INIT], [shared disable-shared], [_LT_ENABLE_SHARED])
_LT_UNLESS_OPTIONS([LT_INIT], [static disable-static], [_LT_ENABLE_STATIC])
_LT_UNLESS_OPTIONS([LT_INIT], [pic-only no-pic], [_LT_WITH_PIC])
_LT_UNLESS_OPTIONS([LT_INIT], [fast-install disable-fast-install],
[_LT_ENABLE_FAST_INSTALL])
])
])# _LT_SET_OPTIONS
## --------------------------------- ##
## Macros to handle LT_INIT options. ##
## --------------------------------- ##
# _LT_MANGLE_DEFUN(MACRO-NAME, OPTION-NAME)
# -----------------------------------------
m4_define([_LT_MANGLE_DEFUN],
[[_LT_OPTION_DEFUN_]m4_bpatsubst(m4_toupper([$1__$2]), [[^A-Z0-9_]], [_])])
# LT_OPTION_DEFINE(MACRO-NAME, OPTION-NAME, CODE)
# -----------------------------------------------
m4_define([LT_OPTION_DEFINE],
[m4_define(_LT_MANGLE_DEFUN([$1], [$2]), [$3])[]dnl
])# LT_OPTION_DEFINE
# dlopen
# ------
LT_OPTION_DEFINE([LT_INIT], [dlopen], [enable_dlopen=yes
])
AU_DEFUN([AC_LIBTOOL_DLOPEN],
[_LT_SET_OPTION([LT_INIT], [dlopen])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `dlopen' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_DLOPEN], [])
# win32-dll
# ---------
# Declare package support for building win32 dll's.
LT_OPTION_DEFINE([LT_INIT], [win32-dll],
[enable_win32_dll=yes
case $host in
*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-cegcc*)
AC_CHECK_TOOL(AS, as, false)
AC_CHECK_TOOL(DLLTOOL, dlltool, false)
AC_CHECK_TOOL(OBJDUMP, objdump, false)
;;
esac
test -z "$AS" && AS=as
_LT_DECL([], [AS], [0], [Assembler program])dnl
test -z "$DLLTOOL" && DLLTOOL=dlltool
_LT_DECL([], [DLLTOOL], [0], [DLL creation program])dnl
test -z "$OBJDUMP" && OBJDUMP=objdump
_LT_DECL([], [OBJDUMP], [0], [Object dumper program])dnl
])# win32-dll
AU_DEFUN([AC_LIBTOOL_WIN32_DLL],
[AC_REQUIRE([AC_CANONICAL_HOST])dnl
_LT_SET_OPTION([LT_INIT], [win32-dll])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `win32-dll' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [])
# _LT_ENABLE_SHARED([DEFAULT])
# ----------------------------
# implement the --enable-shared flag, and supports the `shared' and
# `disable-shared' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_SHARED],
[m4_define([_LT_ENABLE_SHARED_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([shared],
[AS_HELP_STRING([--enable-shared@<:@=PKGS@:>@],
[build shared libraries @<:@default=]_LT_ENABLE_SHARED_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_shared=yes ;;
no) enable_shared=no ;;
*)
enable_shared=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_shared=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_shared=]_LT_ENABLE_SHARED_DEFAULT)
_LT_DECL([build_libtool_libs], [enable_shared], [0],
[Whether or not to build shared libraries])
])# _LT_ENABLE_SHARED
LT_OPTION_DEFINE([LT_INIT], [shared], [_LT_ENABLE_SHARED([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-shared], [_LT_ENABLE_SHARED([no])])
# Old names:
AC_DEFUN([AC_ENABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[shared])
])
AC_DEFUN([AC_DISABLE_SHARED],
[_LT_SET_OPTION([LT_INIT], [disable-shared])
])
AU_DEFUN([AM_ENABLE_SHARED], [AC_ENABLE_SHARED($@)])
AU_DEFUN([AM_DISABLE_SHARED], [AC_DISABLE_SHARED($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_SHARED], [])
dnl AC_DEFUN([AM_DISABLE_SHARED], [])
# _LT_ENABLE_STATIC([DEFAULT])
# ----------------------------
# implement the --enable-static flag, and support the `static' and
# `disable-static' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_STATIC],
[m4_define([_LT_ENABLE_STATIC_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([static],
[AS_HELP_STRING([--enable-static@<:@=PKGS@:>@],
[build static libraries @<:@default=]_LT_ENABLE_STATIC_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_static=yes ;;
no) enable_static=no ;;
*)
enable_static=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_static=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_static=]_LT_ENABLE_STATIC_DEFAULT)
_LT_DECL([build_old_libs], [enable_static], [0],
[Whether or not to build static libraries])
])# _LT_ENABLE_STATIC
LT_OPTION_DEFINE([LT_INIT], [static], [_LT_ENABLE_STATIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-static], [_LT_ENABLE_STATIC([no])])
# Old names:
AC_DEFUN([AC_ENABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[static])
])
AC_DEFUN([AC_DISABLE_STATIC],
[_LT_SET_OPTION([LT_INIT], [disable-static])
])
AU_DEFUN([AM_ENABLE_STATIC], [AC_ENABLE_STATIC($@)])
AU_DEFUN([AM_DISABLE_STATIC], [AC_DISABLE_STATIC($@)])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AM_ENABLE_STATIC], [])
dnl AC_DEFUN([AM_DISABLE_STATIC], [])
# _LT_ENABLE_FAST_INSTALL([DEFAULT])
# ----------------------------------
# implement the --enable-fast-install flag, and support the `fast-install'
# and `disable-fast-install' LT_INIT options.
# DEFAULT is either `yes' or `no'. If omitted, it defaults to `yes'.
m4_define([_LT_ENABLE_FAST_INSTALL],
[m4_define([_LT_ENABLE_FAST_INSTALL_DEFAULT], [m4_if($1, no, no, yes)])dnl
AC_ARG_ENABLE([fast-install],
[AS_HELP_STRING([--enable-fast-install@<:@=PKGS@:>@],
[optimize for fast installation @<:@default=]_LT_ENABLE_FAST_INSTALL_DEFAULT[@:>@])],
[p=${PACKAGE-default}
case $enableval in
yes) enable_fast_install=yes ;;
no) enable_fast_install=no ;;
*)
enable_fast_install=no
# Look at the argument we got. We use all the common list separators.
lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR,"
for pkg in $enableval; do
IFS="$lt_save_ifs"
if test "X$pkg" = "X$p"; then
enable_fast_install=yes
fi
done
IFS="$lt_save_ifs"
;;
esac],
[enable_fast_install=]_LT_ENABLE_FAST_INSTALL_DEFAULT)
_LT_DECL([fast_install], [enable_fast_install], [0],
[Whether or not to optimize for fast installation])dnl
])# _LT_ENABLE_FAST_INSTALL
LT_OPTION_DEFINE([LT_INIT], [fast-install], [_LT_ENABLE_FAST_INSTALL([yes])])
LT_OPTION_DEFINE([LT_INIT], [disable-fast-install], [_LT_ENABLE_FAST_INSTALL([no])])
# Old names:
AU_DEFUN([AC_ENABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], m4_if([$1], [no], [disable-])[fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `fast-install' option into LT_INIT's first parameter.])
])
AU_DEFUN([AC_DISABLE_FAST_INSTALL],
[_LT_SET_OPTION([LT_INIT], [disable-fast-install])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you put
the `disable-fast-install' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_ENABLE_FAST_INSTALL], [])
dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], [])
# _LT_WITH_PIC([MODE])
# --------------------
# implement the --with-pic flag, and support the `pic-only' and `no-pic'
# LT_INIT options.
# MODE is either `yes' or `no'. If omitted, it defaults to `both'.
m4_define([_LT_WITH_PIC],
[AC_ARG_WITH([pic],
[AS_HELP_STRING([--with-pic],
[try to use only PIC/non-PIC objects @<:@default=use both@:>@])],
[pic_mode="$withval"],
[pic_mode=default])
test -z "$pic_mode" && pic_mode=m4_default([$1], [default])
_LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl
])# _LT_WITH_PIC
LT_OPTION_DEFINE([LT_INIT], [pic-only], [_LT_WITH_PIC([yes])])
LT_OPTION_DEFINE([LT_INIT], [no-pic], [_LT_WITH_PIC([no])])
# Old name:
AU_DEFUN([AC_LIBTOOL_PICMODE],
[_LT_SET_OPTION([LT_INIT], [pic-only])
AC_DIAGNOSE([obsolete],
[$0: Remove this warning and the call to _LT_SET_OPTION when you
put the `pic-only' option into LT_INIT's first parameter.])
])
dnl aclocal-1.4 backwards compatibility:
dnl AC_DEFUN([AC_LIBTOOL_PICMODE], [])
## ----------------- ##
## LTDL_INIT Options ##
## ----------------- ##
m4_define([_LTDL_MODE], [])
LT_OPTION_DEFINE([LTDL_INIT], [nonrecursive],
[m4_define([_LTDL_MODE], [nonrecursive])])
LT_OPTION_DEFINE([LTDL_INIT], [recursive],
[m4_define([_LTDL_MODE], [recursive])])
LT_OPTION_DEFINE([LTDL_INIT], [subproject],
[m4_define([_LTDL_MODE], [subproject])])
m4_define([_LTDL_TYPE], [])
LT_OPTION_DEFINE([LTDL_INIT], [installable],
[m4_define([_LTDL_TYPE], [installable])])
LT_OPTION_DEFINE([LTDL_INIT], [convenience],
[m4_define([_LTDL_TYPE], [convenience])])

View File

@@ -0,0 +1,123 @@
# ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007, 2008 Free Software Foundation, Inc.
# Written by Gary V. Vaughan, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 6 ltsugar.m4
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTSUGAR_VERSION], [m4_if([0.1])])
# lt_join(SEP, ARG1, [ARG2...])
# -----------------------------
# Produce ARG1SEPARG2...SEPARGn, omitting [] arguments and their
# associated separator.
# Needed until we can rely on m4_join from Autoconf 2.62, since all earlier
# versions in m4sugar had bugs.
m4_define([lt_join],
[m4_if([$#], [1], [],
[$#], [2], [[$2]],
[m4_if([$2], [], [], [[$2]_])$0([$1], m4_shift(m4_shift($@)))])])
m4_define([_lt_join],
[m4_if([$#$2], [2], [],
[m4_if([$2], [], [], [[$1$2]])$0([$1], m4_shift(m4_shift($@)))])])
# lt_car(LIST)
# lt_cdr(LIST)
# ------------
# Manipulate m4 lists.
# These macros are necessary as long as will still need to support
# Autoconf-2.59 which quotes differently.
m4_define([lt_car], [[$1]])
m4_define([lt_cdr],
[m4_if([$#], 0, [m4_fatal([$0: cannot be called without arguments])],
[$#], 1, [],
[m4_dquote(m4_shift($@))])])
m4_define([lt_unquote], $1)
# lt_append(MACRO-NAME, STRING, [SEPARATOR])
# ------------------------------------------
# Redefine MACRO-NAME to hold its former content plus `SEPARATOR'`STRING'.
# Note that neither SEPARATOR nor STRING are expanded; they are appended
# to MACRO-NAME as is (leaving the expansion for when MACRO-NAME is invoked).
# No SEPARATOR is output if MACRO-NAME was previously undefined (different
# than defined and empty).
#
# This macro is needed until we can rely on Autoconf 2.62, since earlier
# versions of m4sugar mistakenly expanded SEPARATOR but not STRING.
m4_define([lt_append],
[m4_define([$1],
m4_ifdef([$1], [m4_defn([$1])[$3]])[$2])])
# lt_combine(SEP, PREFIX-LIST, INFIX, SUFFIX1, [SUFFIX2...])
# ----------------------------------------------------------
# Produce a SEP delimited list of all paired combinations of elements of
# PREFIX-LIST with SUFFIX1 through SUFFIXn. Each element of the list
# has the form PREFIXmINFIXSUFFIXn.
# Needed until we can rely on m4_combine added in Autoconf 2.62.
m4_define([lt_combine],
[m4_if(m4_eval([$# > 3]), [1],
[m4_pushdef([_Lt_sep], [m4_define([_Lt_sep], m4_defn([lt_car]))])]]dnl
[[m4_foreach([_Lt_prefix], [$2],
[m4_foreach([_Lt_suffix],
]m4_dquote(m4_dquote(m4_shift(m4_shift(m4_shift($@)))))[,
[_Lt_sep([$1])[]m4_defn([_Lt_prefix])[$3]m4_defn([_Lt_suffix])])])])])
# lt_if_append_uniq(MACRO-NAME, VARNAME, [SEPARATOR], [UNIQ], [NOT-UNIQ])
# -----------------------------------------------------------------------
# Iff MACRO-NAME does not yet contain VARNAME, then append it (delimited
# by SEPARATOR if supplied) and expand UNIQ, else NOT-UNIQ.
m4_define([lt_if_append_uniq],
[m4_ifdef([$1],
[m4_if(m4_index([$3]m4_defn([$1])[$3], [$3$2$3]), [-1],
[lt_append([$1], [$2], [$3])$4],
[$5])],
[lt_append([$1], [$2], [$3])$4])])
# lt_dict_add(DICT, KEY, VALUE)
# -----------------------------
m4_define([lt_dict_add],
[m4_define([$1($2)], [$3])])
# lt_dict_add_subkey(DICT, KEY, SUBKEY, VALUE)
# --------------------------------------------
m4_define([lt_dict_add_subkey],
[m4_define([$1($2:$3)], [$4])])
# lt_dict_fetch(DICT, KEY, [SUBKEY])
# ----------------------------------
m4_define([lt_dict_fetch],
[m4_ifval([$3],
m4_ifdef([$1($2:$3)], [m4_defn([$1($2:$3)])]),
m4_ifdef([$1($2)], [m4_defn([$1($2)])]))])
# lt_if_dict_fetch(DICT, KEY, [SUBKEY], VALUE, IF-TRUE, [IF-FALSE])
# -----------------------------------------------------------------
m4_define([lt_if_dict_fetch],
[m4_if(lt_dict_fetch([$1], [$2], [$3]), [$4],
[$5],
[$6])])
# lt_dict_filter(DICT, [SUBKEY], VALUE, [SEPARATOR], KEY, [...])
# --------------------------------------------------------------
m4_define([lt_dict_filter],
[m4_if([$5], [], [],
[lt_join(m4_quote(m4_default([$4], [[, ]])),
lt_unquote(m4_split(m4_normalize(m4_foreach(_Lt_key, lt_car([m4_shiftn(4, $@)]),
[lt_if_dict_fetch([$1], _Lt_key, [$2], [$3], [_Lt_key ])])))))])[]dnl
])

View File

@@ -0,0 +1,23 @@
# ltversion.m4 -- version numbers -*- Autoconf -*-
#
# Copyright (C) 2004 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# Generated from ltversion.in.
# serial 3017 ltversion.m4
# This file is part of GNU Libtool
m4_define([LT_PACKAGE_VERSION], [2.2.6b])
m4_define([LT_PACKAGE_REVISION], [1.3017])
AC_DEFUN([LTVERSION_VERSION],
[macro_version='2.2.6b'
macro_revision='1.3017'
_LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?])
_LT_DECL(, macro_revision, 0)
])

View File

@@ -0,0 +1,92 @@
# lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*-
#
# Copyright (C) 2004, 2005, 2007 Free Software Foundation, Inc.
# Written by Scott James Remnant, 2004.
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
# serial 4 lt~obsolete.m4
# These exist entirely to fool aclocal when bootstrapping libtool.
#
# In the past libtool.m4 has provided macros via AC_DEFUN (or AU_DEFUN)
# which have later been changed to m4_define as they aren't part of the
# exported API, or moved to Autoconf or Automake where they belong.
#
# The trouble is, aclocal is a bit thick. It'll see the old AC_DEFUN
# in /usr/share/aclocal/libtool.m4 and remember it, then when it sees us
# using a macro with the same name in our local m4/libtool.m4 it'll
# pull the old libtool.m4 in (it doesn't see our shiny new m4_define
# and doesn't know about Autoconf macros at all.)
#
# So we provide this file, which has a silly filename so it's always
# included after everything else. This provides aclocal with the
# AC_DEFUNs it wants, but when m4 processes it, it doesn't do anything
# because those macros already exist, or will be overwritten later.
# We use AC_DEFUN over AU_DEFUN for compatibility with aclocal-1.6.
#
# Anytime we withdraw an AC_DEFUN or AU_DEFUN, remember to add it here.
# Yes, that means every name once taken will need to remain here until
# we give up compatibility with versions before 1.7, at which point
# we need to keep only those names which we still refer to.
# This is to help aclocal find these macros, as it can't see m4_define.
AC_DEFUN([LTOBSOLETE_VERSION], [m4_if([1])])
m4_ifndef([AC_LIBTOOL_LINKER_OPTION], [AC_DEFUN([AC_LIBTOOL_LINKER_OPTION])])
m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP])])
m4_ifndef([_LT_AC_PROG_ECHO_BACKSLASH], [AC_DEFUN([_LT_AC_PROG_ECHO_BACKSLASH])])
m4_ifndef([_LT_AC_SHELL_INIT], [AC_DEFUN([_LT_AC_SHELL_INIT])])
m4_ifndef([_LT_AC_SYS_LIBPATH_AIX], [AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX])])
m4_ifndef([_LT_PROG_LTMAIN], [AC_DEFUN([_LT_PROG_LTMAIN])])
m4_ifndef([_LT_AC_TAGVAR], [AC_DEFUN([_LT_AC_TAGVAR])])
m4_ifndef([AC_LTDL_ENABLE_INSTALL], [AC_DEFUN([AC_LTDL_ENABLE_INSTALL])])
m4_ifndef([AC_LTDL_PREOPEN], [AC_DEFUN([AC_LTDL_PREOPEN])])
m4_ifndef([_LT_AC_SYS_COMPILER], [AC_DEFUN([_LT_AC_SYS_COMPILER])])
m4_ifndef([_LT_AC_LOCK], [AC_DEFUN([_LT_AC_LOCK])])
m4_ifndef([AC_LIBTOOL_SYS_OLD_ARCHIVE], [AC_DEFUN([AC_LIBTOOL_SYS_OLD_ARCHIVE])])
m4_ifndef([_LT_AC_TRY_DLOPEN_SELF], [AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF])])
m4_ifndef([AC_LIBTOOL_PROG_CC_C_O], [AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O])])
m4_ifndef([AC_LIBTOOL_SYS_HARD_LINK_LOCKS], [AC_DEFUN([AC_LIBTOOL_SYS_HARD_LINK_LOCKS])])
m4_ifndef([AC_LIBTOOL_OBJDIR], [AC_DEFUN([AC_LIBTOOL_OBJDIR])])
m4_ifndef([AC_LTDL_OBJDIR], [AC_DEFUN([AC_LTDL_OBJDIR])])
m4_ifndef([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH], [AC_DEFUN([AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH])])
m4_ifndef([AC_LIBTOOL_SYS_LIB_STRIP], [AC_DEFUN([AC_LIBTOOL_SYS_LIB_STRIP])])
m4_ifndef([AC_PATH_MAGIC], [AC_DEFUN([AC_PATH_MAGIC])])
m4_ifndef([AC_PROG_LD_GNU], [AC_DEFUN([AC_PROG_LD_GNU])])
m4_ifndef([AC_PROG_LD_RELOAD_FLAG], [AC_DEFUN([AC_PROG_LD_RELOAD_FLAG])])
m4_ifndef([AC_DEPLIBS_CHECK_METHOD], [AC_DEFUN([AC_DEPLIBS_CHECK_METHOD])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_NO_RTTI], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_NO_RTTI])])
m4_ifndef([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE])])
m4_ifndef([AC_LIBTOOL_PROG_COMPILER_PIC], [AC_DEFUN([AC_LIBTOOL_PROG_COMPILER_PIC])])
m4_ifndef([AC_LIBTOOL_PROG_LD_SHLIBS], [AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS])])
m4_ifndef([AC_LIBTOOL_POSTDEP_PREDEP], [AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP])])
m4_ifndef([LT_AC_PROG_EGREP], [AC_DEFUN([LT_AC_PROG_EGREP])])
m4_ifndef([LT_AC_PROG_SED], [AC_DEFUN([LT_AC_PROG_SED])])
m4_ifndef([_LT_CC_BASENAME], [AC_DEFUN([_LT_CC_BASENAME])])
m4_ifndef([_LT_COMPILER_BOILERPLATE], [AC_DEFUN([_LT_COMPILER_BOILERPLATE])])
m4_ifndef([_LT_LINKER_BOILERPLATE], [AC_DEFUN([_LT_LINKER_BOILERPLATE])])
m4_ifndef([_AC_PROG_LIBTOOL], [AC_DEFUN([_AC_PROG_LIBTOOL])])
m4_ifndef([AC_LIBTOOL_SETUP], [AC_DEFUN([AC_LIBTOOL_SETUP])])
m4_ifndef([_LT_AC_CHECK_DLFCN], [AC_DEFUN([_LT_AC_CHECK_DLFCN])])
m4_ifndef([AC_LIBTOOL_SYS_DYNAMIC_LINKER], [AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER])])
m4_ifndef([_LT_AC_TAGCONFIG], [AC_DEFUN([_LT_AC_TAGCONFIG])])
m4_ifndef([AC_DISABLE_FAST_INSTALL], [AC_DEFUN([AC_DISABLE_FAST_INSTALL])])
m4_ifndef([_LT_AC_LANG_CXX], [AC_DEFUN([_LT_AC_LANG_CXX])])
m4_ifndef([_LT_AC_LANG_F77], [AC_DEFUN([_LT_AC_LANG_F77])])
m4_ifndef([_LT_AC_LANG_GCJ], [AC_DEFUN([_LT_AC_LANG_GCJ])])
m4_ifndef([AC_LIBTOOL_RC], [AC_DEFUN([AC_LIBTOOL_RC])])
m4_ifndef([AC_LIBTOOL_LANG_C_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_C_CONFIG])])
m4_ifndef([_LT_AC_LANG_C_CONFIG], [AC_DEFUN([_LT_AC_LANG_C_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_CXX_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_CXX_CONFIG])])
m4_ifndef([_LT_AC_LANG_CXX_CONFIG], [AC_DEFUN([_LT_AC_LANG_CXX_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_F77_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_F77_CONFIG])])
m4_ifndef([_LT_AC_LANG_F77_CONFIG], [AC_DEFUN([_LT_AC_LANG_F77_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_GCJ_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_GCJ_CONFIG])])
m4_ifndef([_LT_AC_LANG_GCJ_CONFIG], [AC_DEFUN([_LT_AC_LANG_GCJ_CONFIG])])
m4_ifndef([AC_LIBTOOL_LANG_RC_CONFIG], [AC_DEFUN([AC_LIBTOOL_LANG_RC_CONFIG])])
m4_ifndef([_LT_AC_LANG_RC_CONFIG], [AC_DEFUN([_LT_AC_LANG_RC_CONFIG])])
m4_ifndef([AC_LIBTOOL_CONFIG], [AC_DEFUN([AC_LIBTOOL_CONFIG])])
m4_ifndef([_LT_AC_FILE_LTDLL_C], [AC_DEFUN([_LT_AC_FILE_LTDLL_C])])

View File

@@ -0,0 +1,134 @@
AC_DEFUN([AM_PATH_PKGCONFIG],
[
dnl sets cflags and ldflags
dnl TEST_CXXFLAGS and TEST_LDFLAGS, by trying thes following
dnl until something works:
dnl
dnl 1 - try the test_prefix
dnl 2 - check whether pkgconfig can find values (unless --with-pkg-config=no)
dnl 3 - use the prefix, if it is not the default
dnl 4 - use defaults, /usr/local/include/OpenEXR and /usr/local/lib
dnl
dnl
dnl Expected arguments
dnl $1: arg_cxxflags - CXXFLAGS variable to set
dnl
dnl $2: arg-ldflags - LDFLAGS variable to set
dnl
dnl $3: package name (the package being checked), as requried by pkg-config
dnl
dnl $4: arg_include_subdir
dnl the name of the subdirectory name that is tacked on to
dnl the end of the include path e.g. "OpenEXR" in
dnl /usr/local/include/OpenEXR
dnl
dnl $5: arg_default_libs - default libraries, used if pkgconfig doesnt work
dnl
dnl $6: arg_test_prefix
dnl the argument passed to configure specifying a directory to
dnl be used in the CXX and LD flags for example:
dnl $2 = "openexr-prefix" and
dnl "configure --openexr-prefix=/usr/lib"
dnl leads to CXX including "-I/usr/lib/OpenEXR"
dnl
dnl create some local m4 "variables" so that we don't have to use numbers
define([arg_cxxflags],$1)
define([arg_ldflags],$2)
define([arg_libs],$3)
define([arg_pkg_name],$4)
define([arg_include_subdir],$5)
define([arg_default_ldflags],$6)
define([arg_default_libs],$7)
define([arg_test_prefix],$8)
TEST_CXXFLAGS=""
TEST_LDFLAGS=""
TEST_LIBS=""
AC_ARG_WITH(arg_test_prefix,[ --with-arg_test_prefix=PFX Prefix where tested libraries are supposed to be installed (optional)], test_prefix="$withval", test_prefix="NONE")
echo "test_prefix = $test_prefix"
AC_ARG_VAR(PKG_CONFIG, Path to pkg-config command)
AC_PATH_PROG(PKG_CONFIG, pkg-config, no)
AC_ARG_WITH(pkg-config,[ --with-pkg-config=PATH Specify which pkg-config to use (optional)], PKG_CONFIG="$withval",)
if test "x$test_prefix" != "xNONE" ; then
echo "using arg_test_prefix to set arg_cxxflags, arg_ldflags and arg_libs:"
for inc_dir in arg_include_subdir
do
TEST_CXXFLAGS="$TEST_CXXFLAGS -I$test_prefix/include/$inc_dir"
done
TEST_LDFLAGS="-L$test_prefix/lib"
TEST_LDFLAGS="$TEST_LDFLAGS arg_default_ldflags"
TEST_LIBS="arg_default_libs"
else
dnl
dnl Get the cflags and libraries from the arg_pkg_name package using
dnl pkg-config
dnl
dnl Note: the TEST_LIBS contains both the -L and the -l flags. This means
dnl the -L flags will appear twice on the command line, but we can not
dnl limit it to --libs-only-l because it may include the "-pthread" flag.
dnl
if test x$PKG_CONFIG != xno ; then
echo "using pkg-config to set arg_cxxflags and arg_ldflags:"
TEST_CXXFLAGS="`$PKG_CONFIG --cflags arg_pkg_name`"
TEST_LDFLAGS="`$PKG_CONFIG --libs-only-L arg_pkg_name`"
TEST_LIBS="`$PKG_CONFIG --libs arg_pkg_name`"
else
echo "Not using pkg-config."
TEST_CXXFLAGS=""
TEST_LDFLAGS=""
TEST_LIBS=""
fi
dnl
dnl if the flags are still not set, try a prefix and finally a default
dnl
if test -z "${TEST_CXXFLAGS}"; then
TEST_CXXFLAGS=""
if test "x$prefix" != "xNONE"; then
echo "using prefix to set arg_cxxflags and arg_ldflags:"
for inc_dir in arg_include_subdir
do
TEST_CXXFLAGS="$TEST_CXXFLAGS -I$prefix/include/$inc_dir"
done
TEST_LDFLAGS="-L$prefix/lib"
else
echo "using default as guess for arg_cxxflags and arg_ldflags:"
for inc_dir in arg_include_subdir
do
TEST_CXXFLAGS="$TEST_CXXFLAGS -I/usr/local/include/$inc_dir"
done
TEST_LDFLAGS="arg_default_ldflags"
fi
TEST_LIBS="arg_default_libs"
fi
fi
echo " arg_cxxflags = $TEST_CXXFLAGS"
echo " arg_ldflags = $TEST_LDFLAGS"
echo " arg_libs = $TEST_LIBS"
AC_SUBST(arg_cxxflags, $TEST_CXXFLAGS)
AC_SUBST(arg_ldflags, $TEST_LDFLAGS)
AC_SUBST(arg_libs, $TEST_LIBS)
dnl clean up local "variables"
undefine([arg_cxxflags])
undefine([arg_ldflags])
undefine([arg_libs])
undefine([arg_pkg_name])
undefine([arg_include_subdir])
undefine([arg_default_ldflags])
undefine([arg_default_libs])
undefine([arg_test_prefix])
])

View File

@@ -0,0 +1,291 @@
dnl @synopsis ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
dnl
dnl Modified by Wojciech Jarosz (2005) to include check for POSIX
dnl semaphore usability. Defines HAVE_POSIX_SEMAPHORES if found.
dnl
dnl This macro figures out how to build C programs using POSIX threads.
dnl It sets the PTHREAD_LIBS output variable to the threads library and
dnl linker flags, and the PTHREAD_CFLAGS output variable to any special
dnl C compiler flags that are needed. (The user can also force certain
dnl compiler flags/libs to be tested by setting these environment
dnl variables.)
dnl
dnl Also sets PTHREAD_CC to any special C compiler that is needed for
dnl multi-threaded programs (defaults to the value of CC otherwise).
dnl (This is necessary on AIX to use the special cc_r compiler alias.)
dnl
dnl NOTE: You are assumed to not only compile your program with these
dnl flags, but also link it with them as well. e.g. you should link
dnl with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
dnl $LIBS
dnl
dnl If you are only building threads programs, you may wish to use
dnl these variables in your default LIBS, CFLAGS, and CC:
dnl
dnl LIBS="$PTHREAD_LIBS $LIBS"
dnl CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
dnl CC="$PTHREAD_CC"
dnl
dnl In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
dnl constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
dnl that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
dnl
dnl ACTION-IF-FOUND is a list of shell commands to run if a threads
dnl library is found, and ACTION-IF-NOT-FOUND is a list of commands to
dnl run it if it is not found. If ACTION-IF-FOUND is not specified, the
dnl default action will define HAVE_PTHREAD.
dnl
dnl Please let the authors know if this macro fails on any platform, or
dnl if you have any other suggestions or comments. This macro was based
dnl on work by SGJ on autoconf scripts for FFTW (www.fftw.org) (with
dnl help from M. Frigo), as well as ac_pthread and hb_pthread macros
dnl posted by Alejandro Forero Cuervo to the autoconf macro repository.
dnl We are also grateful for the helpful feedback of numerous users.
dnl
dnl @category InstalledPackages
dnl @author Steven G. Johnson <stevenj@alum.mit.edu>
dnl @version 2005-01-14
dnl @license GPLWithACException
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthread or
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
PTHREAD_LIBS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_TRY_LINK([#include <pthread.h>],
[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ],
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr;],
[attr_name=$attr; break])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with cc_r
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD
dnl
dnl Posix Semaphore support
dnl
AC_DEFUN([AM_POSIX_SEM],
[
AC_ARG_ENABLE([posix-sem], AC_HELP_STRING([--disable-posix-sem],
[do not attempt to use POSIX unnamed semaphores]))
am_posix_sem_ok=no
if test "${enable_posix_sem:-yes}" != "no"; then
AC_CHECK_HEADERS([semaphore.h], [
AC_SEARCH_LIBS(sem_init, [posix4 pthread], [
AC_MSG_CHECKING([whether to use POSIX unnamed semaphores])
AC_RUN_IFELSE([
AC_LANG_PROGRAM([#include <semaphore.h>], [
sem_t mysem;
if (sem_init (&mysem, 1, 1) == 0)
{
if (sem_wait (&mysem) == 0)
{
sem_post (&mysem);
sem_destroy (&mysem);
return 0;
}
}
return 1;
])
], [
AC_MSG_RESULT([yes])
am_posix_sem_ok=yes], [
AC_MSG_RESULT([no (pshared not usable)])], [
AC_MSG_RESULT([no (cannot check usability when cross compiling)])])
])
])
fi
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$am_posix_sem_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_POSIX_SEMAPHORES),[$1])
:
else
am_posix_sem_ok=no
$2
fi
])

View File

@@ -0,0 +1,2 @@
.DS_Store
CVS

View File

@@ -0,0 +1,90 @@
############################################################################
Building the OpenEXR Photoshop plug-in
By Paul Schneider (pauls@ilm.com) 5-15-03
############################################################################
The Macintosh build requires Metrowerks CodeWarrior 8.3 (or higher).
The Windows build requires Microsoft Visual C++ 6.0 (or higher).
1) install the Photoshop SDK
These projects expect that you have checked the "Photoshop"
module out to the same root directory that contains the other
OpenEXR modules, and that you have added a directory called
"sdk" to the Photoshop module that contains the Adobe Photoshop
SDK. Your source tree should look like this:
|- MacCodeWarrior
|- OpenEXR
|- Photoshop
|- doc
|- mac
|- rsrc
|- sdk
| |- PhotoshopAPI
| |- PhotoshopUtils
| |- resources
|- src
|- win32
|- zlib
Note that this distribution does not include the Photoshop SDK because of
licensing issues. You must be a registered Adobe developer to obtain this
SDK. Visit www.adobe.com to learn more.
The "Photoshop/sdk/resources" folder can be found here:
{Photoshop SDK}/samplecode/resources
This contains the tools necessary to create the PiPL resources on the Windows platform.
If you're unfamiliar with PiPLs, there is some excellent documentation available
in the Photoshop SDK.
Note that if you're only interested in building the Windows version of this plug-in,
you don't need to check out the "MacCodeWarrior" module from the OpenEXR repository.
If you plan to make changes for submission to CVS, though, please make sure they
work correctly on both platforms.
2) build zlib
Both the Mac and Windows builds require a static library, "zlib.lib", to be built.
The Macintosh project will look for the library in "MacCodeWarrior/zlib-1.1.3",
while the Windows project will look for the library in "zlib".
Zlib source is not included with this distribution because of licensing issues.
The source is available for download at www.gzip.org/zlib/ and is very easy to
build on any platform.
3) build the plug-ins
Macintosh:
- open the project file "Photoshop/mac/EXRFormat.mcp" in CodeWarrior.
- build the target "Plugin".
This will build both Carbon and Classic versions of the plug-in in the
package "Photoshop/mac/EXRFormat". It will also turn this folder into
a package, but you may have to log out and log back in to see this change
in the Finder.
Windows:
- open the project file "Photoshop/win32/EXRFormat.dsw" in VC++.
- you will be asked to locate the file "SimpleFormat.dsp". Choose
"Photoshop/win32/EXRFormat.dsp". If you know how to stop VC++ from
asking for this file, please let me know.\
- build the target "Win32 - Release".
This will create the plug-in "Photoshop/win32/Release/EXRFormat.8bi"
4) install the plug-in:
Copy the built plug-in to the "Plug-Ins" folder located in the directory
where Photoshop lives.
5) Enjoy!

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -0,0 +1,180 @@
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.18-19.7.x+obaq i686) [Netscape]">
<meta name="Author" content="Paul Schneider">
<meta name="Description" content="Describes how to use the OpenEXR file format plug-in for Photoshop
">
<title>OpenEXR for Adobe Photoshop</title>
</head>
<body>
<h1>
OpenEXR for Adobe Photoshop</h1>
This document describes how to use the "EXRFormat" plug-in to read and
write OpenEXR images using Adobe Photoshop.&nbsp; For more information
about the OpenEXR format, please visit <a href="http://www.openexr.com">www.openexr.com</a>.
<br>&nbsp;
<h2>
Supported Operating Systems</h2>
This plug-in has only been tested on MacOS 9.2.2, Mac OS X 10.2.4, and
Windows 2000.&nbsp; It should work on MacOS 8.1 and higher, and Windows
98 and higher, but this has not been verified.
<br>&nbsp;
<h2>
Supported Host Applications</h2>
This plug-in has only been tested with Adobe Photoshop 7.0.&nbsp; It should
work with Photoshop 5.5 and higher, but this has not been verified.&nbsp;
This plug-in will not work with versions of Photoshop earlier than 5.5.
<p>This plug-in will not work correctly with other applications which support
some Photoshop file format plug-ins, such as combustion from Discreet,
or Commotion from Pinnacle Systems.
<p>This plug-in will also not work correctly with Adobe After Effects.&nbsp;
An After Effects-specific plug-in may be included in a future release of
OpenEXR.
<br>&nbsp;
<h2>
Installation</h2>
To install the plug-in, copy it to your Photoshop plug-ins folder.&nbsp;
If Photoshop is running, you will have to quit it and launch it again.&nbsp;
Here is a typical Macintosh installation:
<p><img SRC="images/Picture00.jpg" NOSAVE height=717 width=453>
<p>You could also place the EXRFormat plug-in in the "File Formats" folder,
or in any folder inside the "Plug-Ins" folder.
<br>&nbsp;
<br>&nbsp;
<h2>
Opening an OpenEXR image</h2>
Once you have installed the plug-in, you will be able to open images in
the OpenEXR format.&nbsp; Select "Open..." from Photoshop's File menu:
<p><img SRC="images/Picture01.jpg" NOSAVE height=100 width=212>
<p>and navigate to a folder containing OpenEXR images.&nbsp; This example
uses the images distributed with the OpenEXR source code release.
<p><img SRC="images/Picture02.jpg" NOSAVE height=434 width=561>
<p>Note that when you select an OpenEXR image, the "Format:" menu in the
Open dialog reads "OpenEXR".&nbsp; This lets you know that the plug-in
is installed correctly, and that Photoshop has detected that the file is
in the OpenEXR format.
<p>When you click Open in the Open dialog, you will see a new dialog which
allows you to specify how the image is interpreted in Photoshop.
<p><img SRC="images/Picture03.jpg" NOSAVE height=323 width=494>
<p>This dialog is necessary because an OpenEXR image can contain many more
colors than you can work with in Photoshop, even in Photoshop's "16 Bits/Channel"
mode.&nbsp; OpenEXR uses floating-point (real number) pixels, and supports
a high dynamic range of pixel values - that is, colors which are brighter
than white.&nbsp; Photoshop uses integer (whole number) pixels, and does
not support colors brighter than white.&nbsp; Because of this, not all
of the pixels in the OpenEXR image will be preserved when the image is
loaded into Photoshop.&nbsp; This dialog lets you control which pixels
are preserved, so that you can work with the image in Photoshop with a
minimal loss of quality.
<p>Here is a quick explanation of what these controls do:
<ul>
<li>
Exposure: this controls the apparent exposure of the image.&nbsp; An exposure
of 0 (the default) will apply no change to the image.&nbsp; An exposure
of 1 will make the image twice as bright, revealing more detail in the
low end.&nbsp; An exposure of -1 will make the image twice as dark, revealing
highlights that may have been clipped at higher exposures.</li>
<li>
Gamma: this controls the gamma correction that is applied to the image.&nbsp;
Most images, such as JPEGs or TIFFs, are stored with an implicit gamma
encoding of 2.2, the standard for video images.&nbsp; OpenEXR images are
stored with no gamma correction.&nbsp; By default, the EXRFormat plug-in
applies a gamma correction of 2.2 to the image as it is read into Photoshop,
so that it will match the color space of other images, and display correctly
on a computer monitor.&nbsp; If you do not need to color-match the EXR
image with an image in another, gamma-corrected format, you might find
other gamma values more visually appealing.&nbsp; For example, most Macintosh
monitors have a display gamma of 1.8, not 2.2.&nbsp; (Microsoft Windows
computers generally have a display gamma of 2.2).</li>
<li>
Un-Premultiply: by convention, OpenEXR images are "premultiplied" - the
color channel values are already matted against black using the alpha channel.&nbsp;
In Photoshop, it's more convenient to work with unmatted images.&nbsp;
It's important to use this option rather than un-premultiplying the image
within Photoshop, because the plug-in will un-premultiply before applying
exposure and gamma correction.&nbsp; This option will have no affect if
your image does not contain an alpha channel.</li>
</ul>
The dialog also contains a preview area, which lets you see the effect
your settings will have on the image.&nbsp; Click in the black area of
the dialog to load the preview:
<p><img SRC="images/Picture04.jpg" NOSAVE height=324 width=494>
<p>In this preview, we can see that this image has a fairly broad dynamic
range.&nbsp; Much of the image is too dark to see clearly, but the lamps
are so bright that they have been clipped at the default settings.&nbsp;
If we darken our exposure, however, we can see that the image does contain
data for those bright areas.&nbsp; Setting the exposure to -2 makes the
image four times darker - the pixels that now appear white are actually
four times brighter than "white".
<p><img SRC="images/Picture05.jpg" NOSAVE height=324 width=494>
<p>We could reduce the exposure even further, and reveal more detail in
the highlights, but we would start to lose detail in the dark areas.&nbsp;&nbsp;
If we click "OK" at this point, the image will be opened in Photoshop at
an exposure of -2, and will appear very dark (as we saw in the preview):
<p><img SRC="images/Picture06.jpg" NOSAVE height=461 width=636>
<p>It appears that we have lost a large amount of detail in the image,
but there is actually much more detail here than can be displayed on your
computer screen.&nbsp; Checking the "Image->Mode" menu in Photoshop reveals
that this image is 16 bits per channel, and a computer monitor can only
display 8 bits of information per channel.
<p><img SRC="images/Picture07.jpg" NOSAVE height=315 width=337>
<p>To see the hidden detail, we can use the preview feature of Photoshop's
Levels command:
<p><img SRC="images/Picture08.jpg" NOSAVE height=99 width=367>
<p>This will create a dialog that will show us the histogram of the image.&nbsp;
Note that there is a large gap between the brightest pixels (the blown-out
highlights) and the majority of the colors in the image.
<p><img SRC="images/Picture09.jpg" NOSAVE height=465 width=926>
<p>If we adjust the white point so that the majority of the pixels define
the full range of the image, the highlights will be blown out, but more
low-end detail will be revealed.
<p><img SRC="images/Picture10.jpg" NOSAVE height=467 width=926>
<p>Note that if you click OK in the Levels dialog, the range adjustment
will be applied to the actual image, and all of the overrange pixel values
will be clipped to white.&nbsp; When working with OpenEXR image in Photoshop,
It's important to be careful that the details you care about are preserved.
<p>Also, note that when working on a 16 bit image in Photoshop, many features
such as painting and layers are unavailable.&nbsp; If you wish to use these
tools, you must convert the image to 8 bits per channel using the "Image->Mode"
menu, which will result in an even greater loss of data.&nbsp; Cautious
use of the exposure and gamma controls in the EXR Import dialog, along
with applying the Levels command before converting to 8 bits, will help
you use all of Photoshop's powerful tools while preserving the colors that
are most important in your image.&nbsp; Of course, some images will simply
contain too much data to be manipulated safely in Photoshop - it's up to
you to ensure that the image you end up with is correct and visually appealing.
<br>&nbsp;
<h2>
Saving an OpenEXR image</h2>
Saving an OpenEXR image is similar to opening one.&nbsp; When you choose
to save an image in OpenEXR format, a dialog will appear, allowing you
to specify how the image should be saved.&nbsp; Many of these settings
are similar to the controls provided by the Import dialog.
<p><img SRC="images/Picture11.jpg" NOSAVE height=301 width=363>
<p>Note that the Exposure and Gamma settings mean something different in
this dialog - they specify the settings that currently apply to the image.&nbsp;
For example, when the image opened in the previous example is saved, this
dialog states that the image has been gamma corrected and darkened.&nbsp;
The plug-in will undo both of these settings before saving the OpenEXR
file.&nbsp; This means that if you use the same settings when you save
an OpenEXR image as when you opened it, the color space of the image will
stay the same.&nbsp; However, any colors which were lost when the image
was opened (clipped highlights or crushed low-end values) will not be restored.&nbsp;
If you are saving a new image, or an image originally in another format,
as an OpenEXR image, the default settings will result in a valid image.
<p>This dialog also allows you to specify the compression scheme used to
save the OpenEXR image.&nbsp; The OpenEXR format supports several methods
of compression, all of them lossless.&nbsp; For details about which method
best suits your needs, see <a href="http://www.openexr.com">www.openexr.com.</a>
<p><img SRC="images/Picture12.jpg" NOSAVE height=302 width=362>
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
<br>&nbsp;
</body>
</html>

View File

@@ -0,0 +1 @@
// ===========================================================================

View File

@@ -0,0 +1 @@
// ===========================================================================

View File

@@ -0,0 +1 @@
// ===========================================================================

View File

@@ -0,0 +1 @@
// ===========================================================================

View File

@@ -0,0 +1,105 @@
// ===========================================================================
// ExrFormat.r Part of OpenEXR
// ===========================================================================
#include "PIGeneral.r"
//-------------------------------------------------------------------------------
// PiPL resource
//-------------------------------------------------------------------------------
resource 'PiPL' (16000, "OpenEXR PiPL", purgeable)
{
{
Kind { ImageFormat },
Name { "OpenEXR" },
Version { (latestFormatVersion << 16) | latestFormatSubVersion },
#if MSWindows
CodeWin32X86 { "PluginMain" },
#elif TARGET_API_MAC_CARBON
CodeCarbonPowerPC { 0, 0, "" },
#else
CodePowerPC { 0, 0, "" },
#endif
FmtFileType { 'EXR ', '8BIM' },
ReadTypes { { 'EXR ', ' ' } },
FilteredTypes { { 'EXR ', ' ' } },
ReadExtensions { { 'exr ' } },
WriteExtensions { { 'exr ' } },
FilteredExtensions { { 'exr ' } },
FormatMaxSize { { 32767, 32767 } },
// this is to make us available when saving a 16-bit image
EnableInfo
{
"in (PSHOP_ImageMode, RGBMode, RGB48Mode)"
},
// this is apparently just for backwards compatability
SupportedModes
{
noBitmap,
noGrayScale,
noIndexedColor,
doesSupportRGBColor, // yes
noCMYKColor,
noHSLColor,
noHSBColor,
noMultichannel,
noDuotone,
noLABColor
#if !MSWindows
,
noGray16,
doesSupportRGB48, // yes
noLab48,
noCMYK64,
noDeepMultichannel,
noDuotone16
#endif
},
FormatFlags
{
fmtDoesNotSaveImageResources,
fmtCanRead,
fmtCanWrite,
fmtCanWriteIfRead,
fmtCannotWriteTransparency
#if MSWindows
,
fmtCannotCreateThumbnail
#endif
},
FormatMaxChannels
{
{
1,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4,
4
}
}
}
};

View File

@@ -0,0 +1,46 @@
// ===========================================================================
// PSAutoBuffer.cp Part of OpenEXR
// ===========================================================================
//
#if MSWindows
#pragma warning (disable: 161)
#endif
#include "PSAutoBuffer.h"
#include <new>
PSAutoBuffer::PSAutoBuffer
(
int32 inSize,
BufferProcs* inProcs
)
{
OSErr err;
mBufferID = 0;
mProcs = inProcs;
err = mProcs->allocateProc (inSize, &mBufferID);
if (err != noErr)
{
throw std::bad_alloc();
}
}
PSAutoBuffer::~PSAutoBuffer ()
{
if (mBufferID != 0)
{
mProcs->freeProc (mBufferID);
mBufferID = 0;
}
}
Ptr PSAutoBuffer::Lock ()
{
return mProcs->lockProc (mBufferID, false);
}

View File

@@ -0,0 +1,27 @@
// ===========================================================================
// PSAutoBuffer.h Part of OpenEXR
// ===========================================================================
//
#pragma once
#include "PIGeneral.h"
class PSAutoBuffer
{
public:
PSAutoBuffer (int32 inSize,
BufferProcs* inProcs);
~PSAutoBuffer ();
Ptr Lock ();
protected:
BufferProcs* mProcs;
BufferID mBufferID;
};

View File

@@ -0,0 +1,42 @@
// ===========================================================================
// PSAutoBuffer.cp Part of OpenEXR
// ===========================================================================
//
#include "PSAutoBuffer.h"
#include <new>
PSAutoBuffer::PSAutoBuffer
(
int32 inSize,
BufferProcs* inProcs
)
{
OSErr err;
mBufferID = 0;
mProcs = inProcs;
err = mProcs->allocateProc (inSize, &mBufferID);
if (err != noErr)
{
throw std::bad_alloc();
}
}
PSAutoBuffer::~PSAutoBuffer ()
{
if (mBufferID != 0)
{
mProcs->freeProc (mBufferID);
mBufferID = 0;
}
}
Ptr PSAutoBuffer::Lock ()
{
return mProcs->lockProc (mBufferID, false);
}

View File

@@ -0,0 +1,27 @@
// ===========================================================================
// PSAutoBuffer.h Part of OpenEXR
// ===========================================================================
//
#pragma once
#include "PIGeneral.h"
class PSAutoBuffer
{
public:
PSAutoBuffer (int32 inSize,
BufferProcs* inProcs);
~PSAutoBuffer ();
Ptr Lock ();
protected:
BufferProcs* mProcs;
BufferID mBufferID;
};

View File

@@ -0,0 +1,28 @@
// ===========================================================================
// PSFormatGlobals.h Part of OpenEXR
// ===========================================================================
#pragma once
//-------------------------------------------------------------------------------
// Forward Declarations
//-------------------------------------------------------------------------------
struct FormatRecord;
//-------------------------------------------------------------------------------
// Globals struct
//-------------------------------------------------------------------------------
//
// you may subclass this struct for your own globals, but don't add a vtable!
// (no virtual methods, please) If you do add fields, you will have to override
// GlobalsSize() and InitGlobals() to account for your additional fields.
//
struct PSFormatGlobals
{
};

View File

@@ -0,0 +1,413 @@
// ===========================================================================
// PSFormatPlugin.cp Part of OpenEXR
// ===========================================================================
#if MSWindows
#pragma warning (disable: 161)
#endif
#include "PSFormatPlugin.h"
#include "PIFormat.h"
#include <string.h>
//-------------------------------------------------------------------------------
// PSFormatPlugin
//-------------------------------------------------------------------------------
PSFormatPlugin::PSFormatPlugin ()
{
mGlobals = NULL;
mFormatRec = NULL;
mResult = NULL;
}
//-------------------------------------------------------------------------------
// ~PSFormatPlugin
//-------------------------------------------------------------------------------
PSFormatPlugin::~PSFormatPlugin ()
{
}
#pragma mark-
//-------------------------------------------------------------------------------
// Run
//-------------------------------------------------------------------------------
void PSFormatPlugin::Run
(
short inSelector,
FormatRecord* inFormatRecord,
long* inData,
short* outResult
)
{
// plug-in's main routine
// does the work of setting up the globals, and then
// calls the appropriate override hook
if (inSelector == formatSelectorAbout)
{
// format record isn't valid, so can't set up globals
// just show about box
DoAbout ((AboutRecord*) inFormatRecord);
}
else
{
// set up globals
mResult = outResult;
mFormatRec = inFormatRecord;
AllocateGlobals (inFormatRecord, inData, outResult);
if (mGlobals == NULL)
{
*outResult = memFullErr;
return;
}
// handle selector through override hooks
switch (inSelector)
{
case formatSelectorFilterFile: DoFilterFile(); break;
case formatSelectorReadPrepare: DoReadPrepare(); break;
case formatSelectorReadStart: DoReadStart(); break;
case formatSelectorReadContinue: DoReadContinue(); break;
case formatSelectorReadFinish: DoReadFinish(); break;
case formatSelectorOptionsPrepare: DoOptionsPrepare(); break;
case formatSelectorOptionsStart: DoOptionsStart(); break;
case formatSelectorOptionsContinue: DoOptionsContinue(); break;
case formatSelectorOptionsFinish: DoOptionsFinish(); break;
case formatSelectorEstimatePrepare: DoEstimatePrepare(); break;
case formatSelectorEstimateStart: DoEstimateStart(); break;
case formatSelectorEstimateContinue: DoEstimateContinue(); break;
case formatSelectorEstimateFinish: DoEstimateFinish(); break;
case formatSelectorWritePrepare: DoWritePrepare(); break;
case formatSelectorWriteStart: DoWriteStart(); break;
case formatSelectorWriteContinue: DoWriteContinue(); break;
case formatSelectorWriteFinish: DoWriteFinish(); break;
default: *mResult = formatBadParameters; break;
}
// unlock the handle containing our globals
if ((Handle)*inData != NULL)
inFormatRecord->handleProcs->unlockProc ((Handle)*inData);
}
}
#pragma mark-
//-------------------------------------------------------------------------------
// AllocateGlobals
//-------------------------------------------------------------------------------
//
void PSFormatPlugin::AllocateGlobals
(
FormatRecord* inFormatRecord,
long* inData,
short* outResult
)
{
// make sure globals are ready to go
// allocate them if necessary, set pointer correctly if not needed
// based heavily on AllocateGlobals() in PIUtilities.c, but modified
// to allow subclasses to easily extend the Globals struct
mGlobals = NULL;
if (!*inData)
{
// Data is empty, so initialize our globals
// Create a chunk of memory to put our globals.
// Have to call HostNewHandle directly, since gStuff (in
// the PINewHandle macro) hasn't been defined yet
// use override hook to get size of globals struct
Handle h = inFormatRecord->handleProcs->newProc (GlobalsSize());
if (h != NULL)
{
// We created a valid handle. Use it.
// lock the handle and move it high
// (we'll unlock it after we're done):
mGlobals = (PSFormatGlobals*) inFormatRecord->handleProcs->lockProc (h, TRUE);
if (mGlobals != NULL)
{
// was able to create global pointer.
// if we have revert info, copy it into the globals
// otherwise, just init them
if (inFormatRecord->revertInfo != NULL)
{
char* ptr = inFormatRecord->handleProcs->lockProc (inFormatRecord->revertInfo, false);
memcpy (mGlobals, ptr, GlobalsSize());
inFormatRecord->handleProcs->unlockProc (inFormatRecord->revertInfo);
}
else
{
InitGlobals ();
}
// store the handle in the passed in long *data:
*inData = (long)h;
h = NULL; // clear the handle, just in case
}
else
{
// There was an error creating the pointer. Back out
// of all of this.
inFormatRecord->handleProcs->disposeProc (h);
h = NULL; // just in case
}
}
}
else
{
// we've already got a valid structure pointed to by *data
// lock it, cast the returned pointer to a global pointer
// and point globals at it:
mGlobals = (PSFormatGlobals*) inFormatRecord->handleProcs->lockProc ((Handle)*inData, TRUE);
}
}
//-------------------------------------------------------------------------------
// GlobalsSize
//-------------------------------------------------------------------------------
int PSFormatPlugin::GlobalsSize ()
{
// override if your subclass adds fields to the Globals struct
// the first two fields must always be:
// short* result;
// FormatRecord* formatParamBlock;
return sizeof (PSFormatGlobals);
}
//-------------------------------------------------------------------------------
// InitGlobals
//-------------------------------------------------------------------------------
void PSFormatPlugin::InitGlobals ()
{
// override hook - PSFormatGlobals are set up in AllocateGlobals()
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoAbout
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoAbout (AboutRecord* inAboutRec)
{
// override hook
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoReadPrepare
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoReadPrepare ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoReadStart
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoReadStart ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoReadContinue
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoReadContinue ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoReadFinish
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoReadFinish ()
{
// override hook
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoOptionsPrepare
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoOptionsPrepare ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoOptionsStart
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoOptionsStart ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoOptionsContinue
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoOptionsContinue ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoOptionsFinish
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoOptionsFinish ()
{
// override hook
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoEstimatePrepare
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoEstimatePrepare ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoEstimateStart
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoEstimateStart ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoEstimateContinue
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoEstimateContinue ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoEstimateFinish
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoEstimateFinish ()
{
// override hook
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoWritePrepare
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoWritePrepare ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoWriteStart
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoWriteStart ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoWriteContinue
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoWriteContinue ()
{
// override hook
}
//-------------------------------------------------------------------------------
// DoWriteFinish
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoWriteFinish ()
{
// override hook
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoFilterFile
//-------------------------------------------------------------------------------
void PSFormatPlugin::DoFilterFile ()
{
// override hook
}

View File

@@ -0,0 +1,97 @@
// ===========================================================================
// PSFormatPlugin.h Part of OpenEXR
// ===========================================================================
#pragma once
#include "PSFormatGlobals.h"
#include "PIAbout.h"
//-------------------------------------------------------------------------------
// PSFormatPlugin
//-------------------------------------------------------------------------------
//
// Base class for a Photoshop File Format plugin.
//
class PSFormatPlugin
{
public:
//-------------------------------------------------------------------
// Constructor / Destructor
//-------------------------------------------------------------------
PSFormatPlugin ();
virtual ~PSFormatPlugin ();
//-------------------------------------------------------------------
// Run - main function called from plug-ins main entry point
//-------------------------------------------------------------------
void Run (short inSelector,
FormatRecord* inFormatRecord,
long* inData,
short* outResult);
protected:
//-------------------------------------------------------------------
// Convenience routines for making globals as painless
// as possible (not very painless, though)
//-------------------------------------------------------------------
void AllocateGlobals (FormatRecord* inFormatRecord,
long* inData,
short* outResult);
//-------------------------------------------------------------------
// Override hooks - subclasses should override as many of these
// as they need to, and disregard the rest
//-------------------------------------------------------------------
virtual int GlobalsSize ();
virtual void InitGlobals ();
virtual void DoAbout (AboutRecord* inAboutRec);
virtual void DoReadPrepare ();
virtual void DoReadStart ();
virtual void DoReadContinue ();
virtual void DoReadFinish ();
virtual void DoOptionsPrepare ();
virtual void DoOptionsStart ();
virtual void DoOptionsContinue ();
virtual void DoOptionsFinish ();
virtual void DoEstimatePrepare ();
virtual void DoEstimateStart ();
virtual void DoEstimateContinue ();
virtual void DoEstimateFinish ();
virtual void DoWritePrepare ();
virtual void DoWriteStart ();
virtual void DoWriteContinue ();
virtual void DoWriteFinish ();
virtual void DoFilterFile ();
//-------------------------------------------------------------------
// Globals - valid upon entry into every override hook
// except DoAbout(). May actually be a pointer to your
// subclass of PSFormatGlobals.
//-------------------------------------------------------------------
PSFormatGlobals* mGlobals;
short* mResult;
FormatRecord* mFormatRec;
};

View File

@@ -0,0 +1,83 @@
// ===========================================================================
// ExrFormatGlobals.h Part of OpenEXR
// ===========================================================================
//
// Structure in which the EXRFormat plug-in stores its state
//
#pragma once
#include "PSFormatGlobals.h"
#include <ImfRgbaFile.h>
#include <ImfLineOrder.h>
#include <ImfCompression.h>
class RefNumIFStream;
//-------------------------------------------------------------------------------
// Limits
//-------------------------------------------------------------------------------
const int kExr_MaxPixelValue_8 = 0xFF;
const int kExr_MaxPixelValue_16 = 0xFFFF;
//-------------------------------------------------------------------------------
// Configurable Limits
//-------------------------------------------------------------------------------
//
// these are globals so they can be changed based on the capabilities
// of the host. For example, Commotion has a max pixel depth of 8 and
// a max pixel value of 0xFF. Photoshop has a max pixel depth of 16, but
// only a max pixel value of 0x8000. Other hosts might support the full
// 16-bit range up to 0xFFFF (combustion?)
//
extern int gExr_MaxPixelValue;
extern int gExr_MaxPixelDepth;
//-------------------------------------------------------------------------------
// Globals struct
//-------------------------------------------------------------------------------
class EXRFormatGlobals : public PSFormatGlobals
{
public:
void Reset ();
void DefaultIOSettings ();
int MaxPixelValue () const;
Imf::RgbaInputFile* inputFile;
RefNumIFStream* inputStream;
int bpc;
double exposure;
double gamma;
bool premult;
Imf::RgbaChannels outputChannels;
Imf::LineOrder outputLineOrder;
Imf::Compression outputCompression;
};
typedef EXRFormatGlobals* GPtr;
//-------------------------------------------------------------------------------
// MaxPixelValue
//-------------------------------------------------------------------------------
inline int EXRFormatGlobals::MaxPixelValue () const
{
if (bpc == 16)
return (kExr_MaxPixelValue_16 < gExr_MaxPixelValue) ? kExr_MaxPixelValue_16 : gExr_MaxPixelValue;
return (kExr_MaxPixelValue_8 < gExr_MaxPixelValue) ? kExr_MaxPixelValue_8 : gExr_MaxPixelValue;
}

View File

@@ -0,0 +1,692 @@
// ===========================================================================
// EXRFormatPlugin.cp Part of OpenEXR
// ===========================================================================
#if MSWindows
#pragma warning (disable: 161)
#endif
#include "EXRFormatPlugin.h"
#include "EXRResample.h"
#include "EXRImportDialog.h"
#include "EXRExportDialog.h"
#include "RefNumIO.h"
#include "PIFormat.h"
#include "PSAutoBuffer.h"
#include "ImfFrameBuffer.h"
#include "ImfRgbaFile.h"
#include "ImathBox.h"
#include "ImfArray.h"
#include "ImfIO.h"
#include "ImathFun.h"
#include "PITypes.h"
#include "ADMBasic.h"
#include <cassert>
//-------------------------------------------------------------------------------
// ConfigureLimits
//-------------------------------------------------------------------------------
static void ConfigureLimits (const FormatRecord* inFormatRec)
{
// set gExr_MaxPixelValue and gExr_MaxPixelDepth here
if (inFormatRec != NULL)
{
if (inFormatRec->maxValue >= 0xFFFF)
{
// host supports 16 bit pixels
gExr_MaxPixelDepth = 16;
gExr_MaxPixelValue = 0x8000;
}
else
{
// host only supports 8 bit pixels.
gExr_MaxPixelDepth = 8;
gExr_MaxPixelValue = 0x00FF;
}
}
}
#pragma mark-
//-------------------------------------------------------------------------------
// EXRFormatPlugin
//-------------------------------------------------------------------------------
EXRFormatPlugin::EXRFormatPlugin ()
{
// nothing to do
}
//-------------------------------------------------------------------------------
// ~EXRFormatPlugin
//-------------------------------------------------------------------------------
EXRFormatPlugin::~EXRFormatPlugin ()
{
// nothing to do
}
#pragma mark-
//-------------------------------------------------------------------------------
// GlobalsSize
//-------------------------------------------------------------------------------
int EXRFormatPlugin::GlobalsSize ()
{
return sizeof (EXRFormatGlobals);
}
//-------------------------------------------------------------------------------
// InitGlobals
//-------------------------------------------------------------------------------
void EXRFormatPlugin::InitGlobals ()
{
Globals()->Reset();
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoAbout
//-------------------------------------------------------------------------------
void EXRFormatPlugin::DoAbout (AboutRecord* inAboutRec)
{
if (inAboutRec != NULL && inAboutRec->sSPBasic != NULL)
{
ADMBasicSuite6* basicSuite = NULL;
inAboutRec->sSPBasic->AcquireSuite (kADMBasicSuite, kADMBasicSuiteVersion6, (void**) &basicSuite);
if (basicSuite != NULL)
{
basicSuite->MessageAlert ("OpenEXR Format v1.1.1\n\n"
"Format by Florian Kainz, Rod Bogart, Josh Pines, and Drew Hess\n"
"Plug-in by Paul Schneider\n"
"www.openexr.com");
inAboutRec->sSPBasic->ReleaseSuite (kADMBasicSuite, kADMBasicSuiteVersion6);
basicSuite = NULL;
}
}
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoReadStart
//-------------------------------------------------------------------------------
void EXRFormatPlugin::DoReadStart ()
{
using namespace Imf;
using namespace Imath;
// construct input file from refnum
assert( Globals()->inputStream == NULL );
assert( Globals()->inputFile == NULL );
Globals()->inputStream = new RefNumIFStream (mFormatRec->dataFork, "EXR File");
Globals()->inputFile = new RgbaInputFile (* (Globals()->inputStream));
// get dimension info
const Box2i& dw = Globals()->inputFile->dataWindow();
int w = dw.max.x - dw.min.x + 1;
int h = dw.max.y - dw.min.y + 1;
int dx = dw.min.x;
int dy = dw.min.y;
// get resampling configuration
// pop up dialog, ask user for config
// don't display dialog if running in a host other than Photoshop,
// for partial After Effects compatibility
if (mFormatRec->hostSig == '8BIM' || mFormatRec->hostSig == 'MIB8')
{
if (!DoImportPreviewDlog())
{
// user hit cancel. clean up (some hosts like AE won't
// call us with the ReadFinish selector in this case)
// and return a user canceled error to the host.
DoReadFinish();
*mResult = userCanceledErr;
return;
}
}
// we need this here, because the table is initialized to
// 8-bit (preview) mode.
ResetHalfToIntTable (Globals());
// return image info to host
// always do interleaved RGB or RGBA for now
// if image is RGB, don't add an alpha channel
// if image is single channel, add all four channels
// so that we don't have to switch to grayscale mode
mFormatRec->imageSize.v = h;
mFormatRec->imageSize.h = w;
mFormatRec->planes = (Globals()->inputFile->channels() == WRITE_RGB) ? 3 : 4;
mFormatRec->depth = (Globals()->bpc == 8) ? 8 : 16;
mFormatRec->imageMode = (mFormatRec->depth > 8) ? plugInModeRGB48 : plugInModeRGBColor;
mFormatRec->maxValue = Globals()->MaxPixelValue();
}
//-------------------------------------------------------------------------------
// DoReadContinue
//-------------------------------------------------------------------------------
void EXRFormatPlugin::DoReadContinue ()
{
using namespace Imf;
using namespace Imath;
int rowBytes;
int done, total;
bool haveAlpha;
bool premult;
// sanity check
if (Globals()->inputFile == NULL)
{
*mResult = formatCannotRead;
return;
}
// get channel info
haveAlpha = !(Globals()->inputFile->channels() == WRITE_RGB);
premult = Globals()->premult;
// get dimension info
const Box2i& dw = Globals()->inputFile->dataWindow();
int w = dw.max.x - dw.min.x + 1;
int h = dw.max.y - dw.min.y + 1;
int dx = dw.min.x;
int dy = dw.min.y;
// prepare for progress reporting
done = 0;
total = h;
// get rowbytes, and add alignment padding
rowBytes = (mFormatRec->imageSize.h * mFormatRec->planes * (mFormatRec->depth / 8));
rowBytes = (rowBytes * mFormatRec->depth + 7) >> 3;
// create a half buffer for reading into
// buffer is big enough for one scanline
Array2D<Rgba> p2 (1, w);
// create an integer buffer for returning pixels to the host
// buffer is big enough for one scanline
PSAutoBuffer intBuffer (rowBytes, mFormatRec->bufferProcs);
mFormatRec->data = intBuffer.Lock();
unsigned char* data8 = (unsigned char*) mFormatRec->data;
unsigned short* data16 = (unsigned short*) mFormatRec->data;
// Set up to start returning chunks of data.
// use RGBA interleaved format
mFormatRec->colBytes = mFormatRec->planes * (mFormatRec->depth / 8);
mFormatRec->rowBytes = rowBytes;
mFormatRec->planeBytes = mFormatRec->depth / 8;
mFormatRec->loPlane = 0;
mFormatRec->hiPlane = 3;
mFormatRec->theRect.left = 0;
mFormatRec->theRect.right = mFormatRec->imageSize.h;
// read one scanline at a time
for (int scanline = dw.min.y; scanline <= dw.max.y && *mResult == noErr; ++scanline)
{
// read scanline
// need to offset into array so that scanline
// starts at the front of the array
Globals()->inputFile->setFrameBuffer (&p2[-scanline][-dx], 1, w);
Globals()->inputFile->readPixels (scanline);
// unmult scanline if necessary
if (premult)
{
for (int x = 0; x < w; ++x)
{
// we're going to throw away any alpha data > 1, so
// clamp it to that range before using it for unmulting
float a = p2[0][x].a;
a = Imath::clamp (a, 0.f, 1.f);
if (a != 0)
{
p2[0][x].r /= a;
p2[0][x].g /= a;
p2[0][x].b /= a;
}
}
}
// convert scanline
int i = 0;
if (mFormatRec->depth > 8)
{
for (int x = 0; x < w; ++x)
{
data16[i] = HalfToInt (p2[0][x].r, 0); i++;
data16[i] = HalfToInt (p2[0][x].g, 1); i++;
data16[i] = HalfToInt (p2[0][x].b, 2); i++;
if (haveAlpha)
{
data16[i] = HalfToInt (p2[0][x].a, 3);
i++;
}
}
}
else
{
for (int x = 0; x < w; ++x)
{
data8[i] = HalfToInt (p2[0][x].r, 0); i++;
data8[i] = HalfToInt (p2[0][x].g, 1); i++;
data8[i] = HalfToInt (p2[0][x].b, 2); i++;
if (haveAlpha)
{
data8[i] = HalfToInt (p2[0][x].a, 3);
i++;
}
}
}
// pass scanline back to host
// offset data window to origin, because pshop doesn't have "data window" concept
mFormatRec->theRect.top = scanline - dw.min.y;
mFormatRec->theRect.bottom = mFormatRec->theRect.top + 1;
*mResult = mFormatRec->advanceState();
// report progress
mFormatRec->progressProc (++done, total);
}
// we are done
mFormatRec->data = NULL;
}
//-------------------------------------------------------------------------------
// DoReadFinish
//-------------------------------------------------------------------------------
void EXRFormatPlugin::DoReadFinish ()
{
// clean up Globals()
delete Globals()->inputFile;
Globals()->inputFile = NULL;
delete Globals()->inputStream;
Globals()->inputStream = NULL;
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoOptionsStart
//-------------------------------------------------------------------------------
void EXRFormatPlugin::DoOptionsStart ()
{
// show options dialog
if (DoExportSettingsDlog ())
{
// user configured options, so set revert info up so that it reflects
// the new options. Commotion, in particular, uses this so it doesn't
// bring the options dialog up when saving each frame of a sequence.
if (mFormatRec->revertInfo == NULL)
{
mFormatRec->revertInfo = mFormatRec->handleProcs->newProc (GlobalsSize());
}
if (mFormatRec->revertInfo != NULL)
{
char* ptr = mFormatRec->handleProcs->lockProc (mFormatRec->revertInfo, false);
memcpy (ptr, Globals(), GlobalsSize());
mFormatRec->handleProcs->unlockProc (mFormatRec->revertInfo);
}
}
else
{
// user canceled out of options dialog
*mResult = userCanceledErr;
}
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoEstimateStart
//-------------------------------------------------------------------------------
void EXRFormatPlugin::DoEstimateStart ()
{
// provide an estimate as to how much disk space
// we need to write the file. If we don't set a
// non-zero size, Photoshop won't open the file!
// Thanks to Chris Cox @ Adobe for this fix.
int32 dataBytes;
// minimum file size estimate is just the header
mFormatRec->minDataBytes = 100;
// estimate maximum file size if it were uncompressed
// header plus 4 channels, 2 bytes per channel
dataBytes = 100 +
4 * 2 * (int32) mFormatRec->imageSize.h * mFormatRec->imageSize.v;
mFormatRec->maxDataBytes = dataBytes;
// tell the host not to call us with DoEstimateContinue
mFormatRec->data = NULL;
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoWriteStart
//-------------------------------------------------------------------------------
void EXRFormatPlugin::DoWriteStart ()
{
using namespace Imf;
using namespace Imath;
int done, total;
unsigned char* pix8;
unsigned short* pix16;
// set globals to reflect the pixels we're recieving, and
// rebuild the LUT to convert integer pixels
// to floating point pixels
Globals()->bpc = mFormatRec->depth;
ResetIntToHalfTable (Globals());
// construct output file from file spec
Header header (mFormatRec->imageSize.h,
mFormatRec->imageSize.v,
1,
Imath::V2f (0, 0),
1,
Imf::INCREASING_Y,
Globals()->outputCompression);
RefNumOFStream stream (mFormatRec->dataFork, "EXR File");
RgbaOutputFile out (stream, header, (mFormatRec->planes == 3) ? WRITE_RGB : WRITE_RGBA);
// tell the host what format we want to recieve pixels in
// interleaved RGBA format is always popular
// note that we don't align the rowbytes in this case
mFormatRec->imageMode = (mFormatRec->depth > 8) ? plugInModeRGB48 : plugInModeRGBColor;
mFormatRec->loPlane = 0;
mFormatRec->hiPlane = mFormatRec->planes - 1;
mFormatRec->planeBytes = mFormatRec->depth / 8;
mFormatRec->colBytes = mFormatRec->planeBytes * mFormatRec->planes;
mFormatRec->rowBytes = mFormatRec->colBytes * mFormatRec->imageSize.h;
mFormatRec->theRect.left = 0;
mFormatRec->theRect.right = mFormatRec->imageSize.h;
// set up progress
done = 0;
total = mFormatRec->imageSize.v;
// create buffers for one scanline
PSAutoBuffer intBuffer (mFormatRec->rowBytes, mFormatRec->bufferProcs);
Array2D<Rgba> p2 (1, mFormatRec->imageSize.h);
// tell host where our buffer is
mFormatRec->data = intBuffer.Lock();
// convert one scanline at a time
for (int y = 0; y < mFormatRec->imageSize.v; ++y)
{
// get one scanline from host
mFormatRec->theRect.top = y;
mFormatRec->theRect.bottom = y+1;
mFormatRec->advanceState();
// convert scanline
if (mFormatRec->depth > 8)
{
pix16 = (unsigned short*) (mFormatRec->data);
for (int x = 0; x < mFormatRec->imageSize.h; ++x)
{
p2[0][x].r = IntToHalf (*pix16++, 0);
p2[0][x].g = IntToHalf (*pix16++, 1);
p2[0][x].b = IntToHalf (*pix16++, 2);
p2[0][x].a = (mFormatRec->planes > 3) ? IntToHalf (*pix16++, 3) : half(1.0);
}
}
else
{
pix8 = (unsigned char*) (mFormatRec->data);
for (int x = 0; x < mFormatRec->imageSize.h; ++x)
{
p2[0][x].r = IntToHalf (*pix8++, 0);
p2[0][x].g = IntToHalf (*pix8++, 1);
p2[0][x].b = IntToHalf (*pix8++, 2);
p2[0][x].a = (mFormatRec->planes > 3) ? IntToHalf (*pix8++, 3) : half(1.0);
}
}
// premult if necessary
if (Globals()->premult)
{
for (int x = 0; x < mFormatRec->imageSize.h; ++x)
{
half a = p2[0][x].a;
p2[0][x].r *= a;
p2[0][x].g *= a;
p2[0][x].b *= a;
}
}
// write scanline
out.setFrameBuffer (&p2[-y][0], 1, mFormatRec->imageSize.h);
out.writePixels (1);
// report progress
mFormatRec->progressProc (++done, total);
}
// we are done
mFormatRec->data = NULL;
}
#pragma mark-
//-------------------------------------------------------------------------------
// DoImportPreviewDlog
//-------------------------------------------------------------------------------
bool EXRFormatPlugin::DoImportPreviewDlog ()
{
return EXRImportDialog (Globals(), mFormatRec->sSPBasic, mFormatRec->plugInRef);
}
//-------------------------------------------------------------------------------
// DoExportSettingsDlog
//-------------------------------------------------------------------------------
bool EXRFormatPlugin::DoExportSettingsDlog ()
{
return EXRExportDialog (Globals(), mFormatRec->sSPBasic, mFormatRec->plugInRef);
}
#pragma mark-
//-------------------------------------------------------------------------------
// Main entry point
//-------------------------------------------------------------------------------
DLLExport MACPASCAL
void PluginMain
(
const short inSelector,
FormatRecord* inFormatRecord,
long* inData,
short* outResult
)
{
// configure resampling based on host's capabilities
if (inSelector != formatSelectorAbout)
{
ConfigureLimits (inFormatRecord);
}
// create and run the plug-in
try
{
EXRFormatPlugin plugin;
plugin.Run (inSelector, inFormatRecord, inData, outResult);
}
// catch out-of-memory exception
catch (const std::bad_alloc&)
{
*outResult = memFullErr;
}
// catch an exception that provides an error string
catch (const std::exception& ex)
{
if (inSelector == formatSelectorAbout || ex.what() == NULL)
{
*outResult = formatCannotRead;
}
else
{
memcpy (& (*inFormatRecord->errorString)[1], ex.what(), strlen (ex.what()));
(*inFormatRecord->errorString)[0] = strlen (ex.what());
*outResult = errReportString;
}
}
// catch any other exception (we don't want to throw back into the host)
catch (...)
{
*outResult = formatCannotRead;
}
}

View File

@@ -0,0 +1,69 @@
// ===========================================================================
// EXRFormatPlugin.h Part of OpenEXR
// ===========================================================================
#pragma once
#include "PSFormatPlugin.h"
#include "EXRFormatGlobals.h"
#include "PIDefines.h"
#include "PITypes.h"
//-------------------------------------------------------------------------------
// EXRFormatPlugin
//-------------------------------------------------------------------------------
class EXRFormatPlugin : public PSFormatPlugin
{
public:
EXRFormatPlugin ();
virtual ~EXRFormatPlugin ();
protected:
// access to our Globals struct
inline EXRFormatGlobals* Globals ()
{
return (EXRFormatGlobals*) mGlobals;
}
// PSFormatPlugin Overrides
virtual int GlobalsSize ();
virtual void InitGlobals ();
virtual void DoAbout (AboutRecord* inAboutRec);
virtual void DoReadStart ();
virtual void DoReadContinue ();
virtual void DoReadFinish ();
virtual void DoOptionsStart ();
virtual void DoEstimateStart ();
virtual void DoWriteStart ();
// UI methods
bool DoImportPreviewDlog ();
bool DoExportSettingsDlog ();
};
//-------------------------------------------------------------------------------
// Main entry point
//-------------------------------------------------------------------------------
DLLExport MACPASCAL
void PluginMain (const short inSelector,
FormatRecord* inFormatRecord,
long* inData,
short* outResult);

View File

@@ -0,0 +1,52 @@
// ===========================================================================
// ExrFormatGlobals.cp Part of OpenEXR
// ===========================================================================
//
// Structure in which the EXRFormat plug-in stores its state
//
#if MSWindows
#pragma warning (disable: 161)
#endif
#include "EXRFormatGlobals.h"
//-------------------------------------------------------------------------------
// Globals
//-------------------------------------------------------------------------------
int gExr_MaxPixelValue = 0xFF;
int gExr_MaxPixelDepth = 8;
//-------------------------------------------------------------------------------
// Reset
//-------------------------------------------------------------------------------
void EXRFormatGlobals::Reset ()
{
inputFile = NULL;
inputStream = NULL;
DefaultIOSettings();
}
//-------------------------------------------------------------------------------
// DefaultIOSettings
//-------------------------------------------------------------------------------
void EXRFormatGlobals::DefaultIOSettings ()
{
exposure = 0;
gamma = 2.2;
bpc = (gExr_MaxPixelDepth == 8) ? 8 : 16;
premult = true;
outputChannels = Imf::WRITE_RGBA;
outputLineOrder = Imf::DECREASING_Y;
outputCompression = Imf::PIZ_COMPRESSION;
}

View File

@@ -0,0 +1,434 @@
// ===========================================================================
// RefNumIO.cpp Part of OpenEXR
// ===========================================================================
#include "RefNumIO.h"
#include <IexBaseExc.h>
#include <PITypes.h> // for Macintosh and MSWindows defines
// ===========================================================================
// Macintosh IO Abstraction
//
// use 64-bit HFS+ APIs if the system supports them,
// fall back to 32-bit classic File Manager APIs otherwise
// ===========================================================================
#pragma mark ===== Macintosh =====
#if Macintosh
#include <Gestalt.h>
#include <Files.h>
//-------------------------------------------------------------------------------
// HaveHFSPlusAPIs
//-------------------------------------------------------------------------------
static bool HaveHFSPlusAPIs ()
{
static bool sCheckedForHFSPlusAPIs = false;
static bool sHaveHFSPlusAPIs = false;
if (!sCheckedForHFSPlusAPIs)
{
long response = 0;
OSErr err = noErr;
err = Gestalt (gestaltFSAttr, &response);
if (err == noErr && (response & (1 << gestaltHasHFSPlusAPIs)))
{
sHaveHFSPlusAPIs = true;
}
sCheckedForHFSPlusAPIs = true;
}
return sHaveHFSPlusAPIs;
}
//-------------------------------------------------------------------------------
// Read
//-------------------------------------------------------------------------------
static bool Read (short refNum, int n, void* c)
{
OSErr err = noErr;
if (HaveHFSPlusAPIs())
{
ByteCount actual;
err = FSReadFork (refNum, fsFromMark, 0, n, c, &actual);
}
else
{
long count = n;
err = FSRead (refNum, &count, c);
}
return (err == noErr);
}
//-------------------------------------------------------------------------------
// Write
//-------------------------------------------------------------------------------
static bool Write (short refNum, int n, const void* c)
{
OSErr err = noErr;
if (HaveHFSPlusAPIs())
{
ByteCount actual;
err = FSWriteFork (refNum, fsFromMark, 0, n, c, &actual);
}
else
{
long count = n;
err = FSWrite (refNum, &count, c);
}
return (err == noErr);
}
//-------------------------------------------------------------------------------
// Tell
//-------------------------------------------------------------------------------
static bool Tell (short refNum, Imf::Int64& pos)
{
OSErr err = noErr;
if (HaveHFSPlusAPIs())
{
SInt64 p;
err = FSGetForkPosition (refNum, &p);
pos = p;
}
else
{
long p;
err = GetFPos (refNum, &p);
pos = p;
}
return (err == noErr);
}
//-------------------------------------------------------------------------------
// Seek
//-------------------------------------------------------------------------------
static bool Seek (short refNum, const Imf::Int64& pos)
{
OSErr err = noErr;
if (HaveHFSPlusAPIs())
{
err = FSSetForkPosition (refNum, fsFromStart, pos);
}
else
{
err = SetFPos (refNum, fsFromStart, pos);
}
return (err == noErr);
}
//-------------------------------------------------------------------------------
// GetSize
//-------------------------------------------------------------------------------
static bool GetSize (short refNum, Imf::Int64& size)
{
OSErr err = noErr;
if (HaveHFSPlusAPIs())
{
SInt64 fileSize;
err = FSGetForkSize (refNum, &fileSize);
size = fileSize;
}
else
{
long fileSize;
err = GetEOF (refNum, &fileSize);
size = fileSize;
}
return (err == noErr);
}
#endif
#pragma mark-
#pragma mark ===== Windows =====
// ===========================================================================
// Windows IO Abstraction
// ===========================================================================
#if MSWindows
//-------------------------------------------------------------------------------
// Read
//-------------------------------------------------------------------------------
static bool Read (short refNum, int n, void* c)
{
DWORD nRead;
return ReadFile ((HANDLE) refNum, c, n, &nRead, NULL);
}
//-------------------------------------------------------------------------------
// Write
//-------------------------------------------------------------------------------
static bool Write (short refNum, int n, const void* c)
{
DWORD nRead;
return WriteFile ((HANDLE) refNum, c, n, &nRead, NULL);
}
//-------------------------------------------------------------------------------
// Tell
//-------------------------------------------------------------------------------
static bool Tell (short refNum, Imf::Int64& pos)
{
LARGE_INTEGER li;
li.QuadPart = 0;
li.LowPart = SetFilePointer ((HANDLE) refNum, 0, &li.HighPart, FILE_CURRENT);
if (li.HighPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR)
{
return false;
}
pos = li.QuadPart;
return true;
}
//-------------------------------------------------------------------------------
// Seek
//-------------------------------------------------------------------------------
static bool Seek (short refNum, const Imf::Int64& pos)
{
LARGE_INTEGER li;
li.QuadPart = pos;
SetFilePointer ((HANDLE) refNum, li.LowPart, &li.HighPart, FILE_BEGIN);
return !(li.HighPart == INVALID_SET_FILE_POINTER && GetLastError() != NO_ERROR);
}
//-------------------------------------------------------------------------------
// GetSize
//-------------------------------------------------------------------------------
static bool GetSize (short refNum, Imf::Int64& size)
{
LARGE_INTEGER li;
DWORD hi;
li.QuadPart = 0;
li.LowPart = GetFileSize ((HANDLE) refNum, &hi);
li.HighPart = hi;
size = li.QuadPart;
return !(li.LowPart == INVALID_FILE_SIZE && GetLastError() != NO_ERROR);
}
#endif
#pragma mark-
//-------------------------------------------------------------------------------
// IStream Constructor
//-------------------------------------------------------------------------------
RefNumIFStream::RefNumIFStream
(
short refNum,
const char fileName[]
) :
IStream (fileName),
_refNum (refNum)
{
}
//-------------------------------------------------------------------------------
// IStream Destructor
//-------------------------------------------------------------------------------
RefNumIFStream::~RefNumIFStream ()
{
}
//-------------------------------------------------------------------------------
// read
//-------------------------------------------------------------------------------
bool
RefNumIFStream::read (char c[/*n*/], int n)
{
if (!Read (_refNum, n, c))
{
throw Iex::InputExc ("Unable to read file.");
}
Imf::Int64 fileSize;
if (!GetSize (_refNum, fileSize))
{
throw Iex::InputExc ("Couldn't get file size.");
}
return !(fileSize == tellg());
}
//-------------------------------------------------------------------------------
// tellg
//-------------------------------------------------------------------------------
Imf::Int64
RefNumIFStream::tellg ()
{
Imf::Int64 fpos = 0;
if (!Tell (_refNum, fpos))
{
throw Iex::InputExc ("Error finding file positon.");
}
return fpos;
}
//-------------------------------------------------------------------------------
// seekg
//-------------------------------------------------------------------------------
void
RefNumIFStream::seekg (Imf::Int64 pos)
{
if (!Seek (_refNum, pos))
{
throw Iex::InputExc ("Error setting file positon.");
}
}
//-------------------------------------------------------------------------------
// clear
//-------------------------------------------------------------------------------
void
RefNumIFStream::clear ()
{
// nothing to do
}
#pragma mark-
//-------------------------------------------------------------------------------
// OStream Constructor
//-------------------------------------------------------------------------------
RefNumOFStream::RefNumOFStream
(
short refNum,
const char fileName[]
) :
OStream (fileName),
_refNum (refNum)
{
}
//-------------------------------------------------------------------------------
// OStream Destructor
//-------------------------------------------------------------------------------
RefNumOFStream::~RefNumOFStream ()
{
}
//-------------------------------------------------------------------------------
// write
//-------------------------------------------------------------------------------
void
RefNumOFStream::write (const char c[/*n*/], int n)
{
if (!Write (_refNum, n, c))
{
throw Iex::IoExc ("Unable to write file.");
}
}
//-------------------------------------------------------------------------------
// tellp
//-------------------------------------------------------------------------------
Imf::Int64
RefNumOFStream::tellp ()
{
Imf::Int64 fpos = 0;
if (!Tell (_refNum, fpos))
{
throw Iex::InputExc ("Error finding file positon.");
}
return fpos;
}
//-------------------------------------------------------------------------------
// seekp
//-------------------------------------------------------------------------------
void
RefNumOFStream::seekp (Imf::Int64 pos)
{
if (!Seek (_refNum, pos))
{
throw Iex::InputExc ("Error setting file positon.");
}
}

View File

@@ -0,0 +1,58 @@
// ===========================================================================
// RefNumIO.h Part of OpenEXR
// ===========================================================================
#ifndef INCLUDED_REFNUM_IO_H
#define INCLUDED_REFNUM_IO_H
#include <ImfIO.h>
//-------------------------------------------------------------------------------
// RefNumIFStream - an implementation of Imf::IStream that uses the "data fork"
// reference number passed to us by Photoshop
//-------------------------------------------------------------------------------
class RefNumIFStream : public Imf::IStream
{
public:
RefNumIFStream (short refNum,
const char fileName[]);
virtual ~RefNumIFStream ();
virtual bool read (char c[/*n*/], int n);
virtual Imf::Int64 tellg ();
virtual void seekg (Imf::Int64 pos);
virtual void clear ();
private:
short _refNum;
};
//-------------------------------------------------------------------------------
// RefNumOFStream - an implementation of Imf::OStream that uses the "data fork"
// reference number passed to us by Photoshop
//-------------------------------------------------------------------------------
class RefNumOFStream : public Imf::OStream
{
public:
RefNumOFStream (short refNum,
const char fileName[]);
virtual ~RefNumOFStream ();
virtual void write (const char c[/*n*/], int n);
virtual Imf::Int64 tellp ();
virtual void seekp (Imf::Int64 pos);
private:
short _refNum;
};
#endif

View File

@@ -0,0 +1,212 @@
// ===========================================================================
// EXRResample.cp Part of OpenEXR
// ===========================================================================
//
// Routines for converting EXR pixel data to integers of various bit depths.
// Configuration parameters are passed in Globals struct
//
#if MSWindows
#pragma warning (disable: 161)
#endif
#include "EXRResample.h"
//-------------------------------------------------------------------------------
// big lookup tables
//-------------------------------------------------------------------------------
unsigned short halftoint [4] [1<<16];
unsigned short inttohalf [4] [1<<16];
//-------------------------------------------------------------------------------
// clamp
//-------------------------------------------------------------------------------
inline int clampi (int v, int l, int h)
{
return v < l ? l : v > h ? h : v;
}
//-------------------------------------------------------------------------------
// ResetHalfToIntTable
//-------------------------------------------------------------------------------
void ResetHalfToIntTable (const GPtr inGlobals)
{
float multiplier;
int i, c, v;
half x;
int maxval;
// get float - int scalar
maxval = inGlobals->MaxPixelValue();
// calculate exposure multiplier
multiplier = pow (2.0, inGlobals->exposure);
// build table
for (i = 0; i < 1<<16; ++i)
{
x.setBits (i);
//------------------------------------------
// rgb
//------------------------------------------
for (c = 0; c < 3; ++c)
{
float f = x;
// apply exposure multiplier
f *= multiplier;
// apply gamma
if (inGlobals->gamma != 0)
{
f = pow ((double) f, 1.0 / inGlobals->gamma);
}
// convert to integer space
v = f * maxval + .5;
// clamp to legal range
v = clampi (v, 0, maxval);
// store value
halftoint[c][i] = v;
}
//------------------------------------------
// alpha - no correction applied
//------------------------------------------
// convert to integer space
v = x * maxval + .5;
// clamp to legal range
v = clampi (v, 0, maxval);
// store value
halftoint[3][i] = v;
}
}
//-------------------------------------------------------------------------------
// ResetIntToHalfTable
//-------------------------------------------------------------------------------
void ResetIntToHalfTable (const GPtr inGlobals)
{
float multiplier;
int i, c;
half x;
float f;
int maxval;
// get float - int scalar
maxval = inGlobals->MaxPixelValue();
// calculate exposure multiplier
multiplier = pow (2.0, inGlobals->exposure);
// build table
for (i = 0; i < 1<<16; ++i)
{
//------------------------------------------
// rgb
//------------------------------------------
for (c = 0; c < 3; ++c)
{
// get float
f = (float) i;
// convert to float range
f /= maxval;
// undo gamma
if (inGlobals->gamma != 0)
{
f = pow ((double) f, inGlobals->gamma);
}
// undo exposure
f /= multiplier;
// store value
x = f;
inttohalf[c][i] = x.bits();
}
//------------------------------------------
// alpha - no correction applied
//------------------------------------------
// get float
f = (float) i;
// convert to float range
f = f / maxval;
// store value
x = f;
inttohalf[3][i] = x.bits();
}
}

View File

@@ -0,0 +1,64 @@
// ===========================================================================
// EXRResample.h Part of OpenEXR
// ===========================================================================
//
// Routines for converting EXR pixel data to integers of various bit depths.
// Configuration parameters are passed in Globals struct
//
// Channel 0 = red, 1 = green, 2 = blue, 3 = alpha
//
#pragma once
#include "half.h"
#include "EXRFormatGlobals.h"
//-------------------------------------------------------------------------------
// Lookup table rebuilders
//-------------------------------------------------------------------------------
extern void
ResetHalfToIntTable (const GPtr inGlobals);
extern void
ResetIntToHalfTable (const GPtr inGlobals);
//-------------------------------------------------------------------------------
// HalfToInt
//-------------------------------------------------------------------------------
inline unsigned short
HalfToInt
(
const half& inHalf,
int inChannel
)
{
extern unsigned short halftoint [4] [1<<16];
return halftoint[inChannel][inHalf.bits()];
}
//-------------------------------------------------------------------------------
// IntToHalf
//-------------------------------------------------------------------------------
inline half
IntToHalf
(
unsigned short inInt,
int inChannel
)
{
extern unsigned short inttohalf [4] [1<<16];
half x;
x.setBits (inttohalf[inChannel][inInt]);
return x;
}

View File

@@ -0,0 +1,453 @@
// ===========================================================================
// EXRExportDialog.cpp Part of OpenEXR
// ===========================================================================
#if MSWindows
#pragma warning (disable: 161)
#endif
#include "EXRExportDialog.h"
#include "ADMDialog.h"
#include "ADMItem.h"
#include "ADMList.h"
#include "ADMEntry.h"
// ---------------------------------------------------------------------------
// Resource ID's
// ---------------------------------------------------------------------------
enum
{
kItem_OK = 1,
kItem_Cancel,
kItem_Defaults,
kItem_Sep1,
kItem_ColorGroup,
kItem_ExposureLabel,
kItem_Exposure,
kItem_GammaLabel,
kItem_Gamma,
kItem_AlphaGroup,
kItem_Premult,
kItem_CompressionGroup,
kItem_CompressionNone,
kItem_CompressionRLE,
kItem_CompressionZip,
kItem_CompressionZips,
kItem_CompressionPiz,
kItem_Sep2,
kItem_Text1,
kItem_Text2
};
// ---------------------------------------------------------------------------
// Globals - ADM makes it hard to avoid them
// ---------------------------------------------------------------------------
static ADMDialogSuite5* sDlogSuite = NULL;
static ADMItemSuite5* sItemSuite = NULL;
static ADMListSuite3* sListSuite = NULL;
static ADMEntrySuite4* sEntrySuite = NULL;
// ---------------------------------------------------------------------------
// ASSetRect
// ---------------------------------------------------------------------------
inline void ASSetRect (ASRect* rect, short l, short t, short r, short b)
{
rect->left = l;
rect->top = t;
rect->right = r;
rect->bottom = b;
}
// ---------------------------------------------------------------------------
// BuildDialog
// ---------------------------------------------------------------------------
static void BuildDialog (ADMDialogRef dialog)
{
ADMItemRef item;
ASRect rect;
// set the dialog to the correct size
sDlogSuite->Size (dialog, 474, 295);
// OK button
ASSetRect (&rect, 388, 270, 468, 290);
item = sItemSuite->Create (dialog, kItem_OK, kADMTextPushButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "OK");
// cancel button
ASSetRect (&rect, 296, 270, 376, 290);
item = sItemSuite->Create (dialog, kItem_Cancel, kADMTextPushButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Cancel");
// defaults button
ASSetRect (&rect, 8, 270, 88, 290);
item = sItemSuite->Create (dialog, kItem_Defaults, kADMTextPushButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Defaults");
// separator
ASSetRect (&rect, 5, 263, 469, 265);
item = sItemSuite->Create (dialog, kItem_Sep1, kADMFrameType, &rect, NULL, NULL, 0);
sItemSuite->SetItemStyle (item, kADMEtchedFrameStyle);
// exposure label
ASSetRect (&rect, 22, 140, 115, 160);
item = sItemSuite->Create (dialog, kItem_ExposureLabel, kADMTextStaticType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Exposure:");
sItemSuite->SetJustify (item, kADMRightJustify);
// exposure control
ASSetRect (&rect, 120, 140, 220, 160);
item = sItemSuite->Create (dialog, kItem_Exposure, kADMSpinEditType, &rect, NULL, NULL, 0);
// gamma label
ASSetRect (&rect, 22, 165, 115, 185);
item = sItemSuite->Create (dialog, kItem_GammaLabel, kADMTextStaticType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Gamma:");
sItemSuite->SetJustify (item, kADMRightJustify);
// gamma control
ASSetRect (&rect, 120, 165, 220, 185);
item = sItemSuite->Create (dialog, kItem_Gamma, kADMSpinEditType, &rect, NULL, NULL, 0);
// color group
ASSetRect (&rect, 12, 113, 268, 200);
item = sItemSuite->Create (dialog, kItem_ColorGroup, kADMFrameType, &rect, NULL, NULL, 0);
sItemSuite->SetItemStyle (item, kADMEtchedFrameStyle);
sItemSuite->SetText (item, "Color Settings:");
// premult checkbox
ASSetRect (&rect, 65, 225, 250, 245);
item = sItemSuite->Create (dialog, kItem_Premult, kADMTextCheckBoxType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Premultiply");
// alpha group
ASSetRect (&rect, 12, 205, 268, 255);
item = sItemSuite->Create (dialog, kItem_AlphaGroup, kADMFrameType, &rect, NULL, NULL, 0);
sItemSuite->SetItemStyle (item, kADMEtchedFrameStyle);
sItemSuite->SetText (item, "Alpha:");
// compression choices
ASSetRect (&rect, 300, 134, 444, 154);
item = sItemSuite->Create (dialog, kItem_CompressionNone, kADMTextRadioButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "None");
ASSetRect (&rect, 300, 154, 444, 174);
item = sItemSuite->Create (dialog, kItem_CompressionRLE, kADMTextRadioButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "RLE");
ASSetRect (&rect, 300, 174, 444, 194);
item = sItemSuite->Create (dialog, kItem_CompressionZips, kADMTextRadioButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Zip");
ASSetRect (&rect, 300, 194, 444, 214);
item = sItemSuite->Create (dialog, kItem_CompressionZip, kADMTextRadioButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Zip (multi-scanline)");
ASSetRect (&rect, 300, 214, 444, 234);
item = sItemSuite->Create (dialog, kItem_CompressionPiz, kADMTextRadioButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Piz");
// compression group
ASSetRect (&rect, 288, 113, 464, 255);
item = sItemSuite->Create (dialog, kItem_CompressionGroup, kADMFrameType, &rect, NULL, NULL, 0);
sItemSuite->SetItemStyle (item, kADMEtchedFrameStyle);
sItemSuite->SetText (item, "Compression:");
// separator
ASSetRect (&rect, 5, 106, 469, 108);
item = sItemSuite->Create (dialog, kItem_Sep2, kADMFrameType, &rect, NULL, NULL, 0);
sItemSuite->SetItemStyle (item, kADMEtchedFrameStyle);
// some text
ASSetRect (&rect, 24, 8, 450, 44);
item = sItemSuite->Create (dialog, kItem_Text1, kADMTextStaticType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "The inverse of these settings will be applied to the image.");
// some more text
ASSetRect (&rect, 24, 48, 450, 100);
item = sItemSuite->Create (dialog, kItem_Text2, kADMTextStaticType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "If you use the same settings as when you loaded the image, "
"it will be returned to its original colorspace.");
// if on Windows, swap the OK and Cancel button positions
#if MSWindows
item = sDlogSuite->GetItem (dialog, kItem_OK);
sItemSuite->Move (item, 296, 270);
item = sDlogSuite->GetItem (dialog, kItem_Cancel);
sItemSuite->Move (item, 388, 270);
#endif
}
// ---------------------------------------------------------------------------
// DoDialogOK - ADM callback
// ---------------------------------------------------------------------------
static void ASAPI DoDialogOK (ADMItemRef inItem, ADMNotifierRef inNotifier)
{
ADMDialogRef dialog = (ADMDialogRef) sItemSuite->GetUserData (inItem);
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
ADMListRef list = NULL;
ADMEntryRef entry = NULL;
// apply control values to globals
item = sDlogSuite->GetItem (dialog, kItem_Exposure);
globals->exposure = sItemSuite->GetFloatValue (item);
item = sDlogSuite->GetItem (dialog, kItem_Gamma);
globals->gamma = sItemSuite->GetFloatValue (item);
item = sDlogSuite->GetItem (dialog, kItem_Premult);
globals->premult = sItemSuite->GetIntValue (item);
item = sDlogSuite->GetItem (dialog, kItem_CompressionNone);
if (sItemSuite->GetBooleanValue (item)) globals->outputCompression = Imf::NO_COMPRESSION;
item = sDlogSuite->GetItem (dialog, kItem_CompressionRLE);
if (sItemSuite->GetBooleanValue (item)) globals->outputCompression = Imf::RLE_COMPRESSION;
item = sDlogSuite->GetItem (dialog, kItem_CompressionZip);
if (sItemSuite->GetBooleanValue (item)) globals->outputCompression = Imf::ZIP_COMPRESSION;
item = sDlogSuite->GetItem (dialog, kItem_CompressionZips);
if (sItemSuite->GetBooleanValue (item)) globals->outputCompression = Imf::ZIPS_COMPRESSION;
item = sDlogSuite->GetItem (dialog, kItem_CompressionPiz);
if (sItemSuite->GetBooleanValue (item)) globals->outputCompression = Imf::PIZ_COMPRESSION;
// call default handler
sItemSuite->DefaultNotify (inItem, inNotifier);
}
// ---------------------------------------------------------------------------
// DoDialogDefaults - ADM callback
// ---------------------------------------------------------------------------
static void ASAPI DoDialogDefaults (ADMItemRef inItem, ADMNotifierRef inNotifier)
{
ADMDialogRef dialog = (ADMDialogRef) sItemSuite->GetUserData (inItem);
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
ADMListRef list = NULL;
ADMEntryRef entry = NULL;
// set control values
item = sDlogSuite->GetItem (dialog, kItem_Exposure);
sItemSuite->SetFloatValue (item, 0.0f);
item = sDlogSuite->GetItem (dialog, kItem_Gamma);
sItemSuite->SetFloatValue (item, 2.2f);
item = sDlogSuite->GetItem (dialog, kItem_Premult);
sItemSuite->SetIntValue (item, true);
item = sDlogSuite->GetItem (dialog, kItem_CompressionNone);
sItemSuite->SetBooleanValue (item, false);
item = sDlogSuite->GetItem (dialog, kItem_CompressionRLE);
sItemSuite->SetBooleanValue (item, false);
item = sDlogSuite->GetItem (dialog, kItem_CompressionZip);
sItemSuite->SetBooleanValue (item, false);
item = sDlogSuite->GetItem (dialog, kItem_CompressionZips);
sItemSuite->SetBooleanValue (item, false);
item = sDlogSuite->GetItem (dialog, kItem_CompressionPiz);
sItemSuite->SetBooleanValue (item, true);
}
// ---------------------------------------------------------------------------
// DoDialogInit - ADM callback
// ---------------------------------------------------------------------------
static ASErr ASAPI DoDialogInit (ADMDialogRef dialog)
{
const char* compressionNames[] = { "None", "RLE", "Zip - 1 Scanline", "Zip - 16 Scanlines", "Piz" };
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
ADMListRef list = NULL;
ADMEntryRef entry = NULL;
int c = (int) globals->outputCompression;
// create UI elements
BuildDialog (dialog);
// set dialog title
sDlogSuite->SetText (dialog, "EXR Export Settings");
// set control values
item = sDlogSuite->GetItem (dialog, kItem_Exposure);
sItemSuite->SetUnits (item, kADMNoUnits);
sItemSuite->SetFloatValue (item, globals->exposure);
item = sDlogSuite->GetItem (dialog, kItem_Gamma);
sItemSuite->SetUnits (item, kADMNoUnits);
sItemSuite->SetFloatValue (item, globals->gamma);
item = sDlogSuite->GetItem (dialog, kItem_Premult);
sItemSuite->SetIntValue (item, globals->premult);
item = sDlogSuite->GetItem (dialog, kItem_CompressionNone);
sItemSuite->SetBooleanValue (item, globals->outputCompression == Imf::NO_COMPRESSION);
item = sDlogSuite->GetItem (dialog, kItem_CompressionRLE);
sItemSuite->SetBooleanValue (item, globals->outputCompression == Imf::RLE_COMPRESSION);
item = sDlogSuite->GetItem (dialog, kItem_CompressionZip);
sItemSuite->SetBooleanValue (item, globals->outputCompression == Imf::ZIP_COMPRESSION);
item = sDlogSuite->GetItem (dialog, kItem_CompressionZips);
sItemSuite->SetBooleanValue (item, globals->outputCompression == Imf::ZIPS_COMPRESSION);
item = sDlogSuite->GetItem (dialog, kItem_CompressionPiz);
sItemSuite->SetBooleanValue (item, globals->outputCompression == Imf::PIZ_COMPRESSION);
// set "OK" callback
item = sDlogSuite->GetItem (dialog, kItem_OK);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, DoDialogOK);
// set "Defaults" callback
item = sDlogSuite->GetItem (dialog, kItem_Defaults);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, DoDialogDefaults);
return kSPNoError;
}
// ---------------------------------------------------------------------------
// EXRExportDialog - show the Export Settings dialog
// ---------------------------------------------------------------------------
bool EXRExportDialog (GPtr ioGlobals, SPBasicSuite* inSPBasic, void* inPluginRef)
{
int item = kItem_Cancel;
// get suites
inSPBasic->AcquireSuite (kADMDialogSuite, kADMDialogSuiteVersion5, (void**) &sDlogSuite);
inSPBasic->AcquireSuite (kADMItemSuite, kADMItemSuiteVersion5, (void**) &sItemSuite);
inSPBasic->AcquireSuite (kADMListSuite, kADMListSuiteVersion3, (void**) &sListSuite);
inSPBasic->AcquireSuite (kADMEntrySuite, kADMEntrySuiteVersion4, (void**) &sEntrySuite);
// show dialog
if (sDlogSuite != NULL && sItemSuite != NULL && sListSuite != NULL)
{
item = sDlogSuite->Modal ((SPPluginRef) inPluginRef,
"EXR Export Settings",
0,
kADMModalDialogStyle,
DoDialogInit,
ioGlobals,
0);
}
// release suites
if (sDlogSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMDialogSuite, kADMDialogSuiteVersion5);
sDlogSuite = NULL;
}
if (sItemSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMItemSuite, kADMItemSuiteVersion5);
sItemSuite = NULL;
}
if (sListSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMListSuite, kADMListSuiteVersion3);
sListSuite = NULL;
}
if (sEntrySuite != NULL)
{
inSPBasic->ReleaseSuite (kADMEntrySuite, kADMEntrySuiteVersion4);
sEntrySuite = NULL;
}
// return true if user hit OK, false if user hit Cancel
return (item == kItem_OK);
}

View File

@@ -0,0 +1,15 @@
// ===========================================================================
// EXRExportDialog.h Part of OpenEXR
// ===========================================================================
#pragma once
#include "EXRFormatGlobals.h"
struct SPBasicSuite;
extern bool
EXRExportDialog (GPtr ioGlobals, SPBasicSuite* inSPBasic, void* inPluginRef);

View File

@@ -0,0 +1,782 @@
// ===========================================================================
// EXRImportDialog.cpp Part of OpenEXR
// ===========================================================================
#if MSWindows
#pragma warning (disable: 161)
#endif
#include "EXRImportDialog.h"
#include "EXRResample.h"
#include "ADMDialog.h"
#include "ADMItem.h"
#include "ADMDrawer.h"
#include "ADMImage.h"
#include "ADMTracker.h"
#include "ADMResource.h"
#include <ImfArray.h>
#include <ImfRgbaFile.h>
#include <ImathFun.h>
#include "PITypes.h"
#if Macintosh
#include <Appearance.h>
using std::min;
using std::max;
#endif
using Imf::Array2D;
using Imf::Rgba;
// ---------------------------------------------------------------------------
// Resource IDs
// ---------------------------------------------------------------------------
enum
{
kItem_OK = 1,
kItem_Cancel,
kItem_Defaults,
kItem_Sep1,
kItem_ExposureLabel,
kItem_Exposure,
kItem_GammaLabel,
kItem_Gamma,
kItem_Unmult,
kItem_Sep2,
kItem_Preview
};
// ---------------------------------------------------------------------------
// Globals
// ---------------------------------------------------------------------------
static ADMDialogSuite5* sDlogSuite = NULL;
static ADMItemSuite5* sItemSuite = NULL;
static ADMDrawerSuite3* sDrawSuite = NULL;
static ADMImageSuite2* sImageSuite = NULL;
static ADMTrackerSuite1* sTrackSuite = NULL;
static Array2D< Rgba > sEXRBuffer;
static ADMImageRef sPreviewImage = NULL;
// ---------------------------------------------------------------------------
// round
// ---------------------------------------------------------------------------
#if MSWindows
inline double round (double d)
{
return (double) (int) (d + .5);
}
#endif
// ---------------------------------------------------------------------------
// ASSetRect
// ---------------------------------------------------------------------------
inline void ASSetRect (ASRect* rect, short l, short t, short r, short b)
{
rect->left = l;
rect->top = t;
rect->right = r;
rect->bottom = b;
}
// ---------------------------------------------------------------------------
// CenterRectInRect
// ---------------------------------------------------------------------------
//
// Return a rect that has the aspect ratio of rect A, and is centered
// in rect B.
//
static void CenterRectInRect
(
const ASRect& inRectToCenter,
const ASRect& inBoundsRect,
ASRect& outRect
)
{
int cw, ch;
int bw, bh;
int ow, oh;
double dx, dy;
cw = inRectToCenter.right - inRectToCenter.left;
ch = inRectToCenter.bottom - inRectToCenter.top;
bw = inBoundsRect.right - inBoundsRect.left;
bh = inBoundsRect.bottom - inBoundsRect.top;
dx = double (cw) / double (bw);
dy = double (ch) / double (bh);
if (dy > dx)
{
ow = cw / dy;
oh = ch / dy;
}
else
{
ow = cw / dx;
oh = ch / dx;
}
if (cw < bw)
{
ow = cw;
}
if (ch < bh)
{
oh = ch;
}
outRect.left = inBoundsRect.left + ((bw - ow) / 2);
outRect.top = inBoundsRect.top + ((bh - oh) / 2);
outRect.right = outRect.left + ow;
outRect.bottom = outRect.top + oh;
}
#pragma mark-
// ---------------------------------------------------------------------------
// AllocatePreview
// ---------------------------------------------------------------------------
static void ReadAllocatePreview (GPtr globals, ADMItemRef previewWidget)
{
int w, h, dx, dy;
int pw, ph;
ASRect r1, r2, r3;
float xSkip, ySkip;
Array2D< Rgba > scanline;
float x1, x2, y1, y2;
int x1i, x2i, y1i, y2i;
ASRect previewRect;
int previewWidth, previewHeight;
#if Macintosh
unsigned int step = 0;
unsigned int lastUpdate = 0;
#endif
#if MSWindows
SetCursor (LoadCursor (NULL, IDC_WAIT));
#endif
// get dimensions of preview widget
sItemSuite->GetBoundsRect (previewWidget, &previewRect);
previewWidth = previewRect.right - previewRect.left;
previewHeight = previewRect.bottom - previewRect.top;
// get dimensions of image on disk
const Imath::Box2i& dw = globals->inputFile->dataWindow();
w = dw.max.x - dw.min.x + 1;
h = dw.max.y - dw.min.y + 1;
dx = dw.min.x;
dy = dw.min.y;
// get dimensions preview should be
// we want to preserve the aspect ratio of the real image
ASSetRect (&r1, 0, 0, w, h);
ASSetRect (&r2, 0, 0, previewWidth, previewHeight);
CenterRectInRect (r1, r2, r3);
pw = min ((int) (r3.right - r3.left), previewWidth);
ph = min ((int) (r3.bottom - r3.top), previewHeight);
// get skip amounts for downsampling resolution
xSkip = ((float)w / (float)pw);
ySkip = ((float)h / (float)ph);
// allocate EXR buffers
scanline.resizeErase (1, w);
sEXRBuffer.resizeErase (ph, pw);
// read and downsample one scanline at a time
for (y1 = dw.min.y, y2 = 0; y2 < ph; y1 += ySkip, y2 += 1)
{
y1i = round (y1);
y2i = round (y2);
// read scanline
globals->inputFile->setFrameBuffer (&scanline[-y1i][-dx], 1, w);
globals->inputFile->readPixels (y1i);
// downsample scanline into preview buffer
for (x1 = dw.min.x, x2 = 0; x2 < pw; x1 += xSkip, x2 += 1)
{
x1i = round (x1);
x2i = round (x2);
sEXRBuffer[y2i][x2i] = scanline[0][x1i];
}
// give a little feedback
#if Macintosh
unsigned int now = TickCount();
if (now - lastUpdate > 20)
{
SetAnimatedThemeCursor (kThemeWatchCursor, step++);
lastUpdate = now;
}
#endif
}
// allocate 8-bit buffer for drawing to screen
sPreviewImage = sImageSuite->Create (pw, ph, 0);
}
// ---------------------------------------------------------------------------
// FreePreview
// ---------------------------------------------------------------------------
static void FreePreview ()
{
if (sPreviewImage != NULL)
{
sImageSuite->Destroy (sPreviewImage);
sPreviewImage = NULL;
}
sEXRBuffer.resizeErase (0, 0);
}
// ---------------------------------------------------------------------------
// ResamplePreview
// ---------------------------------------------------------------------------
static void ResamplePreview (GPtr globals)
{
// downsample the 16-bit EXR data into the 8-bit buffer
if (sPreviewImage != NULL)
{
ASBytePtr baseAddr;
int w, h, rowBytes;
// get preview image info
baseAddr = sImageSuite->BeginBaseAddressAccess (sPreviewImage);
w = sImageSuite->GetWidth (sPreviewImage);
h = sImageSuite->GetHeight (sPreviewImage);
rowBytes = sImageSuite->GetByteWidth (sPreviewImage);
// globals changed, so rebuild lookup table
int bpc = globals->bpc;
globals->bpc = 8;
ResetHalfToIntTable (globals);
globals->bpc = bpc;
// downsample one scanline at a time
for (int y = 0; y < h; ++y)
{
// downsample scanline
for (int x = 0; x < w; ++x)
{
// get half pixel
Rgba bigPixel = sEXRBuffer[y][x];
// unmult
if (globals->premult && bigPixel.a != 0)
{
// we're going to throw away any alpha data > 1, so
// clamp it to that range before using it for unmulting
float a = Imath::clamp ((float) bigPixel.a, 0.f, 1.f);
bigPixel.r /= a;
bigPixel.g /= a;
bigPixel.b /= a;
}
// convert
char r = HalfToInt (bigPixel.r, 0);
char g = HalfToInt (bigPixel.g, 1);
char b = HalfToInt (bigPixel.b, 2);
// write to preview buffer
ASBytePtr pix = &baseAddr[ (y * rowBytes) + (x * 4) ];
#if MSWindows
// ADM pixel data is little endian
*pix = b; pix++;
*pix = g; pix++;
*pix = r; pix++;
pix++;
#else
// ADM pixel data is big endian
pix++;
*pix = r; pix++;
*pix = g; pix++;
*pix = b; pix++;
#endif
}
}
// clean up
sImageSuite->EndBaseAddressAccess (sPreviewImage);
}
}
// ---------------------------------------------------------------------------
// DrawPreview - ADM callback
// ---------------------------------------------------------------------------
static void ASAPI DrawPreview (ADMItemRef item, ADMDrawerRef drawer)
{
ASRect rect;
sDrawSuite->GetBoundsRect (drawer, &rect);
sDrawSuite->SetADMColor (drawer, kADMBlackColor);
sDrawSuite->FillRect (drawer, &rect);
if (sPreviewImage != NULL)
{
sDrawSuite->DrawADMImageCentered (drawer, sPreviewImage, &rect);
}
else
{
sDrawSuite->SetADMColor (drawer, kADMWhiteColor);
sDrawSuite->DrawTextCentered (drawer, "Click for Preview", &rect);
}
}
// ---------------------------------------------------------------------------
// TrackPreview - ADM callback
// ---------------------------------------------------------------------------
static ASBoolean ASAPI TrackPreview (ADMItemRef inItem, ADMTrackerRef inTracker)
{
// we need to return true so that the notifier proc will be called
sTrackSuite->Abort(inTracker);
return true;
}
// ---------------------------------------------------------------------------
// ClickPreview - ADM callback
// ---------------------------------------------------------------------------
static void ASAPI ClickPreview (ADMItemRef inItem, ADMNotifierRef inNotifier)
{
if (sPreviewImage == NULL)
{
ADMDialogRef dialog = (ADMDialogRef) sItemSuite->GetUserData (inItem);
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
// update the preview
item = sDlogSuite->GetItem (dialog, kItem_Preview);
ReadAllocatePreview (globals, item);
ResamplePreview (globals);
sItemSuite->Invalidate (item);
}
}
#pragma mark-
// ---------------------------------------------------------------------------
// BuildDialog
// ---------------------------------------------------------------------------
static void BuildDialog (ADMDialogRef dialog)
{
ADMItemRef item;
ASRect rect;
// set the dialog to the correct size
sDlogSuite->Size (dialog, 474, 285);
// OK button
ASSetRect (&rect, 388, 260, 468, 280);
item = sItemSuite->Create (dialog, kItem_OK, kADMTextPushButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "OK");
// cancel button
ASSetRect (&rect, 296, 260, 376, 280);
item = sItemSuite->Create (dialog, kItem_Cancel, kADMTextPushButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Cancel");
// defaults button
ASSetRect (&rect, 8, 260, 88, 280);
item = sItemSuite->Create (dialog, kItem_Defaults, kADMTextPushButtonType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Defaults");
// separator
ASSetRect (&rect, 5, 253, 469, 255);
item = sItemSuite->Create (dialog, kItem_Sep1, kADMFrameType, &rect, NULL, NULL, 0);
sItemSuite->SetItemStyle (item, kADMEtchedFrameStyle);
// exposure label
ASSetRect (&rect, 15, 230, 75, 250);
item = sItemSuite->Create (dialog, kItem_ExposureLabel, kADMTextStaticType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Exposure:");
sItemSuite->SetJustify (item, kADMRightJustify);
// exposure control
ASSetRect (&rect, 80, 230, 160, 250);
item = sItemSuite->Create (dialog, kItem_Exposure, kADMSpinEditType, &rect, NULL, NULL, 0);
// gamma label
ASSetRect (&rect, 165, 230, 225, 250);
item = sItemSuite->Create (dialog, kItem_GammaLabel, kADMTextStaticType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Gamma:");
sItemSuite->SetJustify (item, kADMRightJustify);
// gamma control
ASSetRect (&rect, 230, 230, 290, 250);
item = sItemSuite->Create (dialog, kItem_Gamma, kADMSpinEditType, &rect, NULL, NULL, 0);
// unmult checkbox
ASSetRect (&rect, 320, 230, 450, 250);
item = sItemSuite->Create (dialog, kItem_Unmult, kADMTextCheckBoxType, &rect, NULL, NULL, 0);
sItemSuite->SetText (item, "Un-Premultiply");
// separator
ASSetRect (&rect, 5, 224, 469, 226);
item = sItemSuite->Create (dialog, kItem_Sep2, kADMFrameType, &rect, NULL, NULL, 0);
sItemSuite->SetItemStyle (item, kADMEtchedFrameStyle);
// preview
ASSetRect (&rect, 5, 5, 469, 212);
item = sItemSuite->Create (dialog, kItem_Preview, kADMUserType, &rect, NULL, NULL, 0);
// if on Windows, swap the OK and Cancel button positions
#if MSWindows
item = sDlogSuite->GetItem (dialog, kItem_OK);
sItemSuite->Move (item, 296, 260);
item = sDlogSuite->GetItem (dialog, kItem_Cancel);
sItemSuite->Move (item, 388, 260);
#endif
}
// ---------------------------------------------------------------------------
// DoDialogOK - ADM callback
// ---------------------------------------------------------------------------
static void ASAPI DoDialogOK (ADMItemRef inItem, ADMNotifierRef inNotifier)
{
ADMDialogRef dialog = (ADMDialogRef) sItemSuite->GetUserData (inItem);
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
// apply control values to globals
item = sDlogSuite->GetItem (dialog, kItem_Exposure);
globals->exposure = sItemSuite->GetFloatValue (item);
item = sDlogSuite->GetItem (dialog, kItem_Gamma);
globals->gamma = sItemSuite->GetFloatValue (item);
item = sDlogSuite->GetItem (dialog, kItem_Unmult);
globals->premult = sItemSuite->GetIntValue (item);
// call default handler
sItemSuite->DefaultNotify (inItem, inNotifier);
}
// ---------------------------------------------------------------------------
// DoDialogDefaults - ADM callback
// ---------------------------------------------------------------------------
static void ASAPI DoDialogDefaults (ADMItemRef inItem, ADMNotifierRef inNotifier)
{
ADMDialogRef dialog = (ADMDialogRef) sItemSuite->GetUserData (inItem);
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
// reset the globals
globals->DefaultIOSettings();
// update control values
item = sDlogSuite->GetItem (dialog, kItem_Exposure);
sItemSuite->SetFloatValue (item, globals->exposure);
item = sDlogSuite->GetItem (dialog, kItem_Gamma);
sItemSuite->SetFloatValue (item, globals->gamma);
item = sDlogSuite->GetItem (dialog, kItem_Unmult);
sItemSuite->SetIntValue (item, true);
// update the preview
ResamplePreview (globals);
item = sDlogSuite->GetItem (dialog, kItem_Preview);
sItemSuite->Invalidate (item);
}
// ---------------------------------------------------------------------------
// DoDialogControl - ADM callback
// ---------------------------------------------------------------------------
static void ASAPI DoDialogControl (ADMItemRef inItem, ADMNotifierRef inNotifier)
{
ADMDialogRef dialog = (ADMDialogRef) sItemSuite->GetUserData (inItem);
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
// call default handler first
sItemSuite->DefaultNotify (inItem, inNotifier);
// apply control values to globals
item = sDlogSuite->GetItem (dialog, kItem_Exposure);
globals->exposure = sItemSuite->GetFloatValue (item);
item = sDlogSuite->GetItem (dialog, kItem_Gamma);
globals->gamma = sItemSuite->GetFloatValue (item);
item = sDlogSuite->GetItem (dialog, kItem_Unmult);
globals->premult = sItemSuite->GetIntValue (item);
// update the preview with the new globals values
ResamplePreview (globals);
item = sDlogSuite->GetItem (dialog, kItem_Preview);
sItemSuite->Invalidate (item);
}
// ---------------------------------------------------------------------------
// DoDialogInit - ADM callback
// ---------------------------------------------------------------------------
static ASErr ASAPI DoDialogInit (ADMDialogRef dialog)
{
GPtr globals = (GPtr) sDlogSuite->GetUserData (dialog);
ADMItemRef item = NULL;
// create dialog
BuildDialog (dialog);
// set dialog title
sDlogSuite->SetText (dialog, "EXR Import Settings");
// set control values
item = sDlogSuite->GetItem (dialog, kItem_Exposure);
sItemSuite->SetUnits (item, kADMNoUnits);
sItemSuite->SetFloatValue (item, globals->exposure);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, DoDialogControl);
item = sDlogSuite->GetItem (dialog, kItem_Gamma);
sItemSuite->SetUnits (item, kADMNoUnits);
sItemSuite->SetFloatValue (item, globals->gamma);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, DoDialogControl);
item = sDlogSuite->GetItem (dialog, kItem_Unmult);
sItemSuite->SetIntValue (item, globals->premult);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, DoDialogControl);
// set up the preview widget
item = sDlogSuite->GetItem (dialog, kItem_Preview);
sItemSuite->SetDrawProc (item, DrawPreview);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, ClickPreview);
sItemSuite->SetMask (item, kADMButtonUpMask);
sItemSuite->SetTrackProc (item, TrackPreview);
// set "OK" callback
item = sDlogSuite->GetItem (dialog, kItem_OK);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, DoDialogOK);
// set "Defaults" callback
item = sDlogSuite->GetItem (dialog, kItem_Defaults);
sItemSuite->SetUserData (item, dialog);
sItemSuite->SetNotifyProc (item, DoDialogDefaults);
return kSPNoError;
}
#pragma mark-
// ---------------------------------------------------------------------------
// EXRImportDialog - show the Import Settings dialog
// ---------------------------------------------------------------------------
bool EXRImportDialog (GPtr ioGlobals, SPBasicSuite* inSPBasic, void* inPluginRef)
{
int item = kItem_Cancel;
// get suites
inSPBasic->AcquireSuite (kADMDialogSuite, kADMDialogSuiteVersion5, (void**) &sDlogSuite);
inSPBasic->AcquireSuite (kADMItemSuite, kADMItemSuiteVersion5, (void**) &sItemSuite);
inSPBasic->AcquireSuite (kADMDrawerSuite, kADMDrawerSuiteVersion3, (void**) &sDrawSuite);
inSPBasic->AcquireSuite (kADMImageSuite, kADMImageSuiteVersion2, (void**) &sImageSuite);
inSPBasic->AcquireSuite (kADMTrackerSuite, kADMTrackerSuiteVersion1, (void**) &sTrackSuite);
// show dialog
if (sDlogSuite != NULL && sItemSuite != NULL && sDrawSuite != NULL && sImageSuite != NULL)
{
item = sDlogSuite->Modal ((SPPluginRef) inPluginRef,
"EXR Import Settings",
0,
kADMModalDialogStyle,
DoDialogInit,
ioGlobals,
0);
FreePreview();
}
// release suites
if (sDlogSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMDialogSuite, kADMDialogSuiteVersion5);
sDlogSuite = NULL;
}
if (sItemSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMItemSuite, kADMItemSuiteVersion5);
sItemSuite = NULL;
}
if (sDrawSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMDrawerSuite, kADMDrawerSuiteVersion3);
sDrawSuite = NULL;
}
if (sImageSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMImageSuite, kADMImageSuiteVersion2);
sImageSuite = NULL;
}
if (sTrackSuite != NULL)
{
inSPBasic->ReleaseSuite (kADMTrackerSuite, kADMTrackerSuiteVersion1);
sTrackSuite = NULL;
}
// return true if user hit OK, false if user hit Cancel
return (item == kItem_OK);
}

View File

@@ -0,0 +1,14 @@
// ===========================================================================
// EXRImportDialog.h Part of OpenEXR
// ===========================================================================
#pragma once
#include "EXRFormatGlobals.h"
struct SPBasicSuite;
extern bool
EXRImportDialog (GPtr ioGlobals, SPBasicSuite* inSPBasic, void* inPluginRef);

View File

@@ -0,0 +1,64 @@
// Microsoft Visual C++ generated resource script.
//
#include "EXRformat-sym.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"EXRformat-sym.h\0"
END
2 TEXTINCLUDE
BEGIN
"#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
"#include ""windows.h""\r\n"
"#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#ifdef _DEBUG
#include "tempDebug\EXRFormat.pipl"
#else
#include "tempRelease\EXRFormat.pipl"
#endif
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@@ -0,0 +1,363 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="EXRFormat"
ProjectGUID="{AF6C131F-B34E-45BC-B788-4E59864740C8}"
SccProjectName="SimpleFormat"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Release|Win32"
OutputDirectory=".\tempRelease"
IntermediateDirectory=".\tempRelease"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\rsrc,..\src\framework,..\src\main,..\src\resample,..\src\ui,..\sdk\PhotoshopAPI\ADM,..\sdk\PhotoshopAPI\General,..\sdk\PhotoshopAPI\Photoshop,..\sdk\PhotoshopAPI\Pica_sp,..\sdk\PhotoshopAPI\Resources,..\sdk\PhotoshopUtils\Includes,..\..\OpenEXR\Half,..\..\OpenEXR\Iex,..\..\OpenEXR\Imath,..\..\OpenEXR\IlmImf"
PreprocessorDefinitions="NDEBUG;WIN32;_WINDOWS;MSWindows=1;ISOLATION_AWARE_ENABLED;PLATFORM_WIN32;WIN_ENV"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
PrecompiledHeaderFile=""
AssemblerListingLocation=".\tempRelease/"
ObjectFile=".\tempRelease/"
ProgramDataBaseFileName=".\tempRelease/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="0"
CompileAs="0"
DisableSpecificWarnings="4290; 4068; 4244; 4800;"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="zlib_static.lib Halfs.lib Iexs.lib IlmImfs.lib Imaths.lib odbc32.lib odbccp32.lib"
OutputFile="Release\EXRFormat.8bi"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\..\zlib\;..\..\OpenEXR\vc\vc7\lib\half;..\..\OpenEXR\vc\vc7\lib\iex;..\..\OpenEXR\vc\vc7\lib\ilmimf;..\..\OpenEXR\vc\vc7\lib\imath"
IgnoreAllDefaultLibraries="FALSE"
ProgramDatabaseFile=".\tempRelease/EXRFormat.pdb"
SubSystem="2"
ImportLibrary=".\tempRelease/EXRFormat.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\temp/EXRFormat.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="MSWindows=1"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\tempDebug"
IntermediateDirectory=".\tempDebug"
ConfigurationType="2"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\rsrc,..\src\framework,..\src\main,..\src\resample,..\src\ui,..\sdk\PhotoshopAPI\ADM,..\sdk\PhotoshopAPI\General,..\sdk\PhotoshopAPI\Photoshop,..\sdk\PhotoshopAPI\Pica_sp,..\sdk\PhotoshopAPI\Resources,..\sdk\PhotoshopUtils\Includes,..\..\OpenEXR\Half,..\..\OpenEXR\Iex,..\..\OpenEXR\Imath,..\..\OpenEXR\IlmImf"
PreprocessorDefinitions="_DEBUG;WIN32;_WINDOWS;MSWindows=1;ISOLATION_AWARE_ENABLED;PLATFORM_WIN32;WIN_ENV"
RuntimeLibrary="2"
PrecompiledHeaderFile=""
AssemblerListingLocation=".\tempDebug/"
ObjectFile=".\tempDebug/"
ProgramDataBaseFileName=".\tempDebug/"
BrowseInformation="1"
WarningLevel="3"
SuppressStartupBanner="TRUE"
DebugInformationFormat="4"
CompileAs="0"
DisableSpecificWarnings="4290; 4068; 4244; 4800;"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="zlibd.lib Halfd.lib Iexd.lib IlmImfd.lib Imathd.lib odbc32.lib odbccp32.lib"
OutputFile=".\Debug\EXRFormat.8bi"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
AdditionalLibraryDirectories="..\..\zlib\;..\..\OpenEXR\vc\vc7\lib\half;..\..\OpenEXR\vc\vc7\lib\iex;..\..\OpenEXR\vc\vc7\lib\ilmimf;..\..\OpenEXR\vc\vc7\lib\imath"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\tempDebug/EXRFormat.pdb"
SubSystem="2"
ImportLibrary=".\tempDebug/EXRFormat.lib"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
PreprocessorDefinitions="_DEBUG"
MkTypLibCompatible="TRUE"
SuppressStartupBanner="TRUE"
TargetEnvironment="1"
TypeLibraryName=".\temp/EXRFormat.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG,MSWindows=1"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Main"
Filter="">
<File
RelativePath="..\src\main\ExrFormatGlobals.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\main\EXRFormatGlobals.h">
</File>
<File
RelativePath="..\src\main\EXRFormatPlugin.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\main\EXRFormatPlugin.h">
</File>
<File
RelativePath="..\src\resample\EXRResample.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\resample\EXRResample.h">
</File>
<File
RelativePath="..\src\main\RefNumIO.cpp">
</File>
<File
RelativePath="..\src\main\RefNumIO.h">
</File>
</Filter>
<Filter
Name="Framework"
Filter="">
<File
RelativePath="..\src\framework\PSAutoBuffer.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\framework\PSAutoBuffer.h">
</File>
<File
RelativePath="..\src\framework\PSFormatGlobals.h">
</File>
<File
RelativePath="..\src\framework\PSFormatPlugin.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\framework\PSFormatPlugin.h">
</File>
</Filter>
<Filter
Name="UI"
Filter="">
<File
RelativePath="..\src\ui\EXRExportDialog.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ui\EXRExportDialog.h">
</File>
<File
RelativePath="..\src\ui\EXRImportDialog.cpp">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
BrowseInformation="1"/>
</FileConfiguration>
</File>
<File
RelativePath="..\src\ui\EXRImportDialog.h">
</File>
</Filter>
<Filter
Name="Resources"
Filter="">
<File
RelativePath="..\rsrc\EXRFormat.r">
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCustomBuildTool"
Description="Compiling PiPL resource..."
CommandLine="cl /I..\sdk\PhotoshopAPI\General /I..\sdk\PhotoshopAPI\PICA_SP /I..\sdk\PhotoshopAPI\Photoshop /I..\sdk\PhotoshopAPI\Resources /EP /DMSWindows=1 /Tc&quot;$(InputPath)&quot; &gt; &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.rr
..\sdk\resources\cnvtpipl &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.rr &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.pipl
del &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.rr
"
Outputs="$(IntDir)\$(InputName).pipl"/>
</FileConfiguration>
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCustomBuildTool"
Description="Compiling PiPL resource..."
CommandLine="cl /I..\sdk\PhotoshopAPI\General /I..\sdk\PhotoshopAPI\PICA_SP /I..\sdk\PhotoshopAPI\Photoshop /I..\sdk\PhotoshopAPI\Resources /EP /DMSWindows=1 /Tc&quot;$(InputPath)&quot; &gt; &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.rr
..\sdk\resources\cnvtpipl &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.rr &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.pipl
del &quot;$(IntDir)&quot;\\&quot;$(InputName)&quot;.rr
"
Outputs="$(IntDir)\$(InputName).pipl"/>
</FileConfiguration>
</File>
<File
RelativePath="EXRFormat.rc">
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@@ -0,0 +1,19 @@
//{{NO_DEPENDENCIES}}
// Microsoft Developer Studio generated include file.
// Used by EXRFormat.rc
//
#define IDD_ABOUT 16000
#define FORMATPARAMS 16000
#define IDC_STATIC -1
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 101
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1007
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

View File

@@ -0,0 +1,711 @@
///////////////////////////////////////////////////////////////////////////
//
// 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:
// * 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// PhotoRealistic RenderMan display driver that outputs
// floating-point image files, using ILM's IlmImf library.
//
// When you use this display driver for RGBA or Z output, you should
// turn RGBA and Z quantization off by adding the following lines to
// your RIB file:
//
// Quantize "rgba" 0 0 0 0
// Quantize "z" 0 0 0 0
//
// Like Pixar's Tiff driver, this display driver can output image
// channels other than R, G, B and A; for details on RIB file and
// shader syntax, see the Renderman Release Notes (New Display
// System, RGBAZ Output Images, Arbitrary Output Variables).
//
// This driver maps Renderman's output variables to image channels
// as follows:
//
// Renderman output image channel image channel
// variable name name type
// --------------------------------------------------------------
//
// "r" "R" HALF
//
// "g" "G" HALF
//
// "b" "B" HALF
//
// "a" "A" HALF
//
// "z" "Z" FLOAT
//
// other same as output preferred type
// variable name (see below)
//
// By default, the "preferred" channel type is HALF; the
// preferred type can be changed by adding an "exrpixeltype"
// argument to the Display command in the RIB file.
// For example:
//
// Declare "exrpixeltype" "string"
//
// # Store point positions in FLOAT format
// Display "gnome.points.exr" "exr" "P" "exrpixeltype" "float"
//
// The default compression method for the image's pixel data
// is defined in ImfHeader.h. You can select a different
// compression method by adding an "exrcompression" argument
// to the Display command. For example:
//
// Declare "exrcompression" "string"
//
// # Store RGBA using run-length encoding
// Display "gnome.rgba.exr" "exr" "rgba" "exrcompression" "rle"
//
// See function DspyImageOpen(), below, for a list of valid
// "exrpixeltype" and "exrcompression" values.
//
//-----------------------------------------------------------------------------
#undef NDEBUG // enable assert()
#include <ImfOutputFile.h>
#include <ImfChannelList.h>
#include <ImfIntAttribute.h>
#include <ImfFloatAttribute.h>
#include <ImfMatrixAttribute.h>
#include <ImfLut.h>
#include <ImfArray.h>
#include <ImathFun.h>
#include <Iex.h>
#include <half.h>
#include <halfFunction.h>
#include <string>
#include <map>
#include <vector>
#include <ndspy.h>
using namespace Imath;
using namespace Imf;
using namespace std;
namespace {
typedef map <string, int> ChannelOffsetMap;
typedef vector <halfFunction <half> *> ChannelLuts;
//
// Define halfFunctions for the identity and piz12
//
half halfID( half x ) { return x; }
halfFunction <half> id( halfID );
halfFunction <half> piz12( round12log );
class Image
{
public:
Image (const char filename[],
const Header &header,
ChannelOffsetMap &rmanChannelOffsets,
int rmanPixelSize,
ChannelLuts &channelLuts);
const Header & header () const;
void writePixels (int xMin, int xMaxPlusone,
int yMin, int yMaxPlusone,
int entrySize,
const unsigned char *data);
private:
OutputFile _file;
Array <char> _buffer;
vector <int> _rmanChannelOffsets;
vector <int> _bufferChannelOffsets;
int _rmanPixelSize;
int _bufferPixelSize;
int _bufferXMin;
int _bufferNumPixels;
int _numPixelsReceived;
ChannelLuts _channelLuts;
};
Image::Image (const char filename[],
const Header &header,
ChannelOffsetMap &rmanChannelOffsets,
int rmanPixelSize,
ChannelLuts &channelLuts
)
:
_file (filename, header),
_rmanPixelSize (rmanPixelSize),
_bufferPixelSize (0),
_bufferXMin (header.dataWindow().min.x),
_bufferNumPixels (header.dataWindow().max.x - _bufferXMin + 1),
_numPixelsReceived (0),
_channelLuts (channelLuts)
{
V2i dwSize = header.dataWindow().size();
for (ChannelList::ConstIterator i = header.channels().begin();
i != header.channels().end();
++i)
{
switch (i.channel().type)
{
case HALF:
_rmanChannelOffsets.push_back (rmanChannelOffsets[i.name()]);
_bufferChannelOffsets.push_back (_bufferPixelSize);
_bufferPixelSize += sizeof (float); // Note: to avoid alignment
break; // problems when float and half
// channels are mixed, halfs
case FLOAT: // are not packed densely.
_rmanChannelOffsets.push_back (rmanChannelOffsets[i.name()]);
_bufferChannelOffsets.push_back (_bufferPixelSize);
_bufferPixelSize += sizeof (float);
break;
default:
assert (false); // unsupported channel type
break;
}
}
_buffer.resizeErase (_bufferNumPixels * _bufferPixelSize);
FrameBuffer fb;
int j = 0;
int yStride = 0;
char *base = &_buffer[0] -
_bufferXMin * _bufferPixelSize;
for (ChannelList::ConstIterator i = header.channels().begin();
i != header.channels().end();
++i)
{
fb.insert (i.name(),
Slice (i.channel().type, // type
base + _bufferChannelOffsets[j], // base
_bufferPixelSize, // xStride
yStride, // yStride
1, // xSampling
1)); // ySampling
++j;
}
_file.setFrameBuffer (fb);
}
const Header &
Image::header () const
{
return _file.header();
}
void
Image::writePixels (int xMin, int xMaxPlusone,
int yMin, int yMaxPlusone,
int entrySize,
const unsigned char *data)
{
//
// We can only deal with one scan line at a time.
//
assert (yMin == yMaxPlusone - 1);
const ChannelList &channels = _file.header().channels();
int numPixels = xMaxPlusone - xMin;
int j = 0;
char *toBase;
int toInc;
//
// Copy the pixels into our internal one-line frame buffer.
//
toBase = _buffer + _bufferPixelSize * xMin;
toInc = _bufferPixelSize;
for (ChannelList::ConstIterator i = channels.begin();
i != channels.end();
++i)
{
const unsigned char *from = data + _rmanChannelOffsets[j];
const unsigned char *end = from + numPixels * entrySize;
char *to = toBase + _bufferChannelOffsets[j];
switch (i.channel().type)
{
case HALF:
{
halfFunction <half> &lut = *_channelLuts[j];
while (from < end)
{
*(half *) to = lut( ( half )( *(float *) from ) );
from += entrySize;
to += toInc;
}
break;
}
case FLOAT:
while (from < end)
{
*(float *) to = *(float *) from;
from += entrySize;
to += toInc;
}
break;
default:
assert (false); // channel type is not currently supported
break;
}
++j;
}
_numPixelsReceived += numPixels;
assert (_numPixelsReceived <= _bufferNumPixels);
if (_numPixelsReceived == _bufferNumPixels)
{
//
// If our one-line frame buffer is full, then write it to
// the output file.
//
_file.writePixels();
_numPixelsReceived = 0;
}
}
} // namespace
extern "C" {
PtDspyError
DspyImageOpen (PtDspyImageHandle *pvImage,
const char *drivername,
const char *filename,
int width,
int height,
int paramCount,
const UserParameter *parameters,
int formatCount,
PtDspyDevFormat *format,
PtFlagStuff *flagstuff)
{
try
{
//
// Build an output file header
//
Header header;
ChannelOffsetMap channelOffsets;
ChannelLuts channelLuts;
int pixelSize = 0;
halfFunction <half> *rgbLUT = &id;
halfFunction <half> *otherLUT = &id;
//
// Data window
//
{
Box2i &dw = header.dataWindow();
int n = 2;
DspyFindIntsInParamList ("origin", &n, &dw.min.x,
paramCount, parameters);
assert (n == 2);
dw.max.x = dw.min.x + width - 1;
dw.max.y = dw.min.y + height - 1;
}
//
// Display window
//
{
Box2i &dw = header.displayWindow();
int n = 2;
DspyFindIntsInParamList ("OriginalSize", &n, &dw.max.x,
paramCount, parameters);
assert (n == 2);
dw.min.x = 0;
dw.min.y = 0;
dw.max.x -= 1;
dw.max.y -= 1;
}
//
// Camera parameters
//
{
//
// World-to-NDC matrix, world-to-camera matrix,
// near and far clipping plane distances
//
M44f NP, Nl;
float near = 0, far = 0;
DspyFindMatrixInParamList ("NP", &NP[0][0], paramCount, parameters);
DspyFindMatrixInParamList ("Nl", &Nl[0][0], paramCount, parameters);
DspyFindFloatInParamList ("near", &near, paramCount, parameters);
DspyFindFloatInParamList ("far", &far, paramCount, parameters);
//
// The matrices reflect the orientation of the camera at
// render time.
//
header.insert ("worldToNDC", M44fAttribute (NP));
header.insert ("worldToCamera", M44fAttribute (Nl));
header.insert ("clipNear", FloatAttribute (near));
header.insert ("clipFar", FloatAttribute (far));
//
// Projection matrix
//
M44f P = Nl.inverse() * NP;
//
// Derive pixel aspect ratio, screen window width, screen
// window center from projection matrix.
//
Box2f sw (V2f ((-1 - P[3][0] - P[2][0]) / P[0][0],
(-1 - P[3][1] - P[2][1]) / P[1][1]),
V2f (( 1 - P[3][0] - P[2][0]) / P[0][0],
( 1 - P[3][1] - P[2][1]) / P[1][1]));
header.screenWindowWidth() = sw.max.x - sw.min.x;
header.screenWindowCenter() = (sw.max + sw.min) / 2;
const Box2i &dw = header.displayWindow();
header.pixelAspectRatio() = (sw.max.x - sw.min.x) /
(sw.max.y - sw.min.y) *
(dw.max.y - dw.min.y + 1) /
(dw.max.x - dw.min.x + 1);
}
//
// Line order
//
header.lineOrder() = INCREASING_Y;
flagstuff->flags |= PkDspyFlagsWantsScanLineOrder;
//
// Compression
//
{
char *comp = 0;
DspyFindStringInParamList ("exrcompression", &comp,
paramCount, parameters);
if (comp)
{
if (!strcmp (comp, "none"))
header.compression() = NO_COMPRESSION;
else if (!strcmp (comp, "rle"))
header.compression() = RLE_COMPRESSION;
else if (!strcmp (comp, "zips"))
header.compression() = ZIPS_COMPRESSION;
else if (!strcmp (comp, "zip"))
header.compression() = ZIP_COMPRESSION;
else if (!strcmp (comp, "piz"))
header.compression() = PIZ_COMPRESSION;
else if (!strcmp (comp, "piz12"))
{
header.compression() = PIZ_COMPRESSION;
rgbLUT = &piz12;
}
else
THROW (Iex::ArgExc,
"Invalid exrcompression \"" << comp << "\" "
"for image file " << filename << ".");
}
}
//
// Channel list
//
{
PixelType pixelType = HALF;
char *ptype = 0;
DspyFindStringInParamList ("exrpixeltype", &ptype,
paramCount, parameters);
if (ptype)
{
if (!strcmp (ptype, "float"))
pixelType = FLOAT;
else if (!strcmp (ptype, "half"))
pixelType = HALF;
else
THROW (Iex::ArgExc,
"Invalid exrpixeltype \"" << ptype << "\" "
"for image file " << filename << ".");
}
ChannelList &channels = header.channels();
for (int i = 0; i < formatCount; ++i)
{
if (!strcmp (format[i].name, "r"))
{
channels.insert ("R", Channel (HALF));
channelOffsets["R"] = pixelSize;
channelLuts.push_back( rgbLUT );
}
else if (!strcmp (format[i].name, "g"))
{
channels.insert ("G", Channel (HALF));
channelOffsets["G"] = pixelSize;
channelLuts.push_back( rgbLUT );
}
else if (!strcmp (format[i].name, "b"))
{
channels.insert ("B", Channel (HALF));
channelOffsets["B"] = pixelSize;
channelLuts.push_back( rgbLUT );
}
else if (!strcmp (format[i].name, "a"))
{
channels.insert ("A", Channel (HALF));
channelOffsets["A"] = pixelSize;
channelLuts.push_back( otherLUT );
}
else if (!strcmp (format[i].name, "z"))
{
channels.insert ("Z", Channel (FLOAT));
channelOffsets["Z"] = pixelSize;
channelLuts.push_back( otherLUT );
}
else
{
//
// Unknown channel name; keep its name and store
// the channel, unless the name conflicts with
// another channel's name.
//
if (!channels.findChannel (format[i].name))
{
channels.insert (format[i].name, Channel (pixelType));
channelOffsets[format[i].name] = pixelSize;
channelLuts.push_back( otherLUT );
}
}
format[i].type = PkDspyFloat32 | PkDspyByteOrderNative;
pixelSize += sizeof (float);
}
}
//
// Open the output file
//
Image *image = new Image (filename,
header,
channelOffsets,
pixelSize,
channelLuts);
*pvImage = (PtDspyImageHandle) image;
}
catch (const exception &e)
{
DspyError ("OpenEXR display driver", "%s\n", e.what());
return PkDspyErrorUndefined;
}
return PkDspyErrorNone;
}
PtDspyError
DspyImageData (PtDspyImageHandle pvImage,
int xmin,
int xmax_plusone,
int ymin,
int ymax_plusone,
int entrysize,
const unsigned char *data)
{
try
{
Image *image = (Image *) pvImage;
image->writePixels (xmin, xmax_plusone,
ymin, ymax_plusone,
entrysize, data);
}
catch (const exception &e)
{
DspyError ("OpenEXR display driver", "%s\n", e.what());
return PkDspyErrorUndefined;
}
return PkDspyErrorNone;
}
PtDspyError
DspyImageClose (PtDspyImageHandle pvImage)
{
try
{
delete (Image *) pvImage;
}
catch (const exception &e)
{
DspyError ("OpenEXR display driver", "%s\n", e.what());
return PkDspyErrorUndefined;
}
return PkDspyErrorNone;
}
PtDspyError
DspyImageQuery (PtDspyImageHandle pvImage,
PtDspyQueryType querytype,
int datalen,
void *data)
{
if (datalen > 0 && data)
{
switch (querytype)
{
case PkOverwriteQuery:
{
PtDspyOverwriteInfo overwriteInfo;
if (datalen > sizeof(overwriteInfo))
datalen = sizeof(overwriteInfo);
overwriteInfo.overwrite = 1;
overwriteInfo.interactive = 0;
memcpy(data, &overwriteInfo, datalen);
}
break;
case PkSizeQuery:
{
PtDspySizeInfo sizeInfo;
if (datalen > sizeof(sizeInfo))
datalen = sizeof(sizeInfo);
const Image *image = (const Image *) pvImage;
if (image)
{
const Box2i &dw = image->header().dataWindow();
sizeInfo.width = dw.max.x - dw.min.x + 1;
sizeInfo.height = dw.max.y - dw.min.y + 1;
//
// Renderman documentation does not specify if
// sizeInfo.aspectRatio refers to the pixel or
// the image aspect ratio, but sample code in
// the documentation suggests pixel aspect ratio.
//
sizeInfo.aspectRatio = image->header().pixelAspectRatio();
}
else
{
sizeInfo.width = 640;
sizeInfo.height = 480;
sizeInfo.aspectRatio = 1.0f;
}
memcpy(data, &sizeInfo, datalen);
}
break;
default:
return PkDspyErrorUnsupported;
}
}
else
{
return PkDspyErrorBadParams;
}
return PkDspyErrorNone;
}
} // extern C

View File

@@ -0,0 +1,4 @@
# Abbreviated rendermn.ini to make current directory first when
# PRMAN is searching for DSO's.
/display/dsopath .:@

View File

@@ -0,0 +1,11 @@
Declare "exrcompression" "uniform string"
Display "tst.EXRCOMP.exr" "exr" "rgba" "exrcompression" ["EXRCOMP"]
Quantize "rgba" 0 0 0 0
Format 720 486 1
Projection "perspective" "fov" [35]
Translate 0 0 8
WorldBegin
Translate 0 -1.3 0
Rotate -90 1 0 0
Geometry "teapot"
WorldEnd

View File

@@ -0,0 +1,17 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps
CVS

View File

@@ -0,0 +1,16 @@
IlmBase.pc
autom4te.cache/
config.guess
config.log
config.status
config.sub
config/IlmBaseConfig.h
config/stamp-h1
configure
depcomp
install-sh
libtool
ltmain.sh
missing
.metadata/

View File

@@ -0,0 +1,21 @@
Developers:
-----------
Florian Kainz <kainz@ilm.com>
Rod Bogart <rgb@ilm.com>
Drew Hess <dhess@ilm.com>
Bill Anderson <wja@ilm.com>
Wojciech Jarosz <wjarosz@ucsd.edu>
Contributors:
-------------
Rito Trevino
Josh Pines
Christian Rouet
Win32 build system:
-------------------
Nick Porcino <NPorcino@lucasarts.com>
Kimball Thurston

View File

@@ -0,0 +1,233 @@
# yue.nicholas@gmail.com
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
PROJECT ( ilmbase )
option(ILMIMF_BUILD_TESTS "Build IlmBase tests?" OFF)
option(ILMIMF_CREATE_LIBTOOL_FILE "Create libtool files?" OFF)
option(ILMIMF_INSTALL_PKGCONFIG "Install pkgconfig files?" OFF)
SET(ILMBASE_VERSION_MAJOR "2")
SET(ILMBASE_VERSION_MINOR "2")
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})
if(ILMIMF_BUILD_TESTS)
ENABLE_TESTING()
endif()
SET(CPACK_PACKAGE_VERSION_MAJOR "${ILMBASE_VERSION_MAJOR}")
SET(CPACK_PACKAGE_VERSION_MINOR "${ILMBASE_VERSION_MINOR}")
SET(CPACK_PACKAGE_VERSION_PATCH "${ILMBASE_VERSION_PATCH}")
SET(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_PACKAGE_FILE_NAME
"${CMAKE_PROJECT_NAME}-${ILMBASE_VERSION}"
)
set(CPACK_SOURCE_IGNORE_FILES
"/.git*;/.cvs*;${CPACK_SOURCE_IGNORE_FILES}")
INCLUDE ( CPack )
# Allow the developer to select if Dynamic or Static libraries are built
OPTION (ILMBASE_BUILD_SHARED_LIBS "Build Shared Libraries" ON)
# Allow the developer to select if Dynamic or Static libraries are built
OPTION (ILMBASE_NAMESPACE_VERSIONING "Namespace Versioning" ON)
# Setup osx rpathing
SET (CMAKE_MACOSX_RPATH 1)
SET (BUILD_WITH_INSTALL_RPATH 1)
IF ( NOT WIN32)
ADD_DEFINITIONS ( -pthread )
ENDIF ()
INCLUDE_DIRECTORIES ( Iex IexMath Imath Half ${CMAKE_CURRENT_BINARY_DIR}/config IlmThread)
if(ILMIMF_BUILD_TESTS)
INCLUDE_DIRECTORIES ( IexTest ImathTest HalfTest )
endif()
# also add the current directory to pick up the autogenerated headers
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
MACRO(GET_TARGET_PROPERTY_WITH_DEFAULT _variable _target _property _default_value)
GET_TARGET_PROPERTY (${_variable} ${_target} ${_property})
IF (${_variable} MATCHES NOTFOUND)
SET (${_variable} ${_default_value})
ENDIF (${_variable} MATCHES NOTFOUND)
ENDMACRO (GET_TARGET_PROPERTY_WITH_DEFAULT)
MACRO(CREATE_LIBTOOL_FILE _target _install_DIR)
GET_TARGET_PROPERTY(_target_location ${_target} LOCATION)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_static_lib ${_target} STATIC_LIB "")
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dependency_libs ${_target} LT_DEPENDENCY_LIBS "")
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_current ${_target} LT_VERSION_CURRENT 0)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_age ${_target} LT_VERSION_AGE 0)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_revision ${_target} LT_VERSION_REVISION 0)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_installed ${_target} LT_INSTALLED yes)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_shouldnotlink ${_target} LT_SHOULDNOTLINK yes)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlopen ${_target} LT_DLOPEN "")
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlpreopen ${_target} LT_DLPREOPEN "")
GET_FILENAME_COMPONENT(_laname ${_target_location} NAME_WE)
GET_FILENAME_COMPONENT(_soname ${_target_location} NAME)
SET(_laname ${PROJECT_BINARY_DIR}/${_laname}.la)
FILE(WRITE ${_laname} "# ${_laname} - a libtool library file\n")
FILE(APPEND ${_laname} "# Generated by CMake ${CMAKE_VERSION} (like GNU libtool)\n")
FILE(APPEND ${_laname} "\n# Please DO NOT delete this file!\n# It is necessary for linking the library with libtool.\n\n" )
FILE(APPEND ${_laname} "# The name that we can dlopen(3).\n")
FILE(APPEND ${_laname} "dlname='${_soname}'\n\n")
FILE(APPEND ${_laname} "# Names of this library.\n")
FILE(APPEND ${_laname} "library_names='${_soname}.${_target_current}.${_target_age}.${_target_revision} ${_soname}.${_target_current} ${_soname}'\n\n")
FILE(APPEND ${_laname} "# The name of the static archive.\n")
FILE(APPEND ${_laname} "old_library='${_target_static_lib}'\n\n")
FILE(APPEND ${_laname} "# Libraries that this one depends upon.\n")
FILE(APPEND ${_laname} "dependency_libs='${_target_dependency_libs}'\n\n")
FILE(APPEND ${_laname} "# Names of additional weak libraries provided by this library\n")
FILE(APPEND ${_laname} "weak_library_names=\n\n")
FILE(APPEND ${_laname} "# Version information for ${_laname}.\n")
FILE(APPEND ${_laname} "current=${_target_current}\n")
FILE(APPEND ${_laname} "age=${_target_age}\n")
FILE(APPEND ${_laname} "revision=${_target_revision}\n\n")
FILE(APPEND ${_laname} "# Is this an already installed library?\n")
FILE(APPEND ${_laname} "installed=${_target_installed}\n\n")
FILE(APPEND ${_laname} "# Should we warn about portability when linking against -modules?\n")
FILE(APPEND ${_laname} "shouldnotlink=${_target_shouldnotlink}\n\n")
FILE(APPEND ${_laname} "# Files to dlopen/dlpreopen\n")
FILE(APPEND ${_laname} "dlopen='${_target_dlopen}'\n")
FILE(APPEND ${_laname} "dlpreopen='${_target_dlpreopen}'\n\n")
FILE(APPEND ${_laname} "# Directory that this library needs to be installed in:\n")
FILE(APPEND ${_laname} "libdir='${CMAKE_INSTALL_PREFIX}${_install_DIR}'\n")
INSTALL( FILES ${_laname} DESTINATION ${CMAKE_INSTALL_PREFIX}${_install_DIR})
ENDMACRO(CREATE_LIBTOOL_FILE)
SET (LIB_TYPE STATIC)
IF (ILMBASE_BUILD_SHARED_LIBS)
# User wants to build Dynamic Libraries, so change the LIB_TYPE variable to CMake keyword 'SHARED'
SET (LIB_TYPE SHARED)
IF (WIN32)
ADD_DEFINITIONS(-DOPENEXR_DLL)
ENDIF ()
ENDIF (ILMBASE_BUILD_SHARED_LIBS)
ADD_SUBDIRECTORY ( Half )
ADD_SUBDIRECTORY ( Iex )
ADD_SUBDIRECTORY ( IexMath )
ADD_SUBDIRECTORY ( Imath )
ADD_SUBDIRECTORY ( IlmThread )
IF (NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h)
IF (WIN32)
FILE ( COPY ${CMAKE_CURRENT_SOURCE_DIR}/config.windows/IlmBaseConfig.h
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/config
)
ELSE ()
IF (APPLE)
FILE ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define HAVE_PTHREAD 1\n" )
ELSE ()
FILE ( WRITE ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define HAVE_PTHREAD 1\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_HAVE_LARGE_STACK 1\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define HAVE_POSIX_SEMAPHORES 1\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_HAVE_CONTROL_REGISTER_SUPPORT 1\n")
ENDIF ()
ENDIF ()
IF (ILMBASE_NAMESPACE_VERSIONING)
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_INTERNAL_ILMBASE_NAMESPACE_CUSTOM 1\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define IMATH_INTERNAL_NAMESPACE Imath_${ILMBASE_VERSION_API}\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define IEX_INTERNAL_NAMESPACE Iex_${ILMBASE_VERSION_API}\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMTHREAD_INTERNAL_NAMESPACE IlmThread_${ILMBASE_VERSION_API}\n")
ELSE ()
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_INTERNAL_ILMBASE_NAMESPACE_CUSTOM 0\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define IMATH_INTERNAL_NAMESPACE Imath\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define IEX_INTERNAL_NAMESPACE Iex\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMTHREAD_INTERNAL_NAMESPACE IlmThread\n")
ENDIF ()
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define IMATH_NAMESPACE Imath\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define IEX_NAMESPACE Iex\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMTHREAD_NAMESPACE IlmThread\n")
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_VERSION_STRING \"${ILMBASE_VERSION}\"\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_PACKAGE_STRING \"IlmBase ${ILMBASE_VERSION}\"\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_VERSION_MAJOR ${ILMBASE_VERSION_MAJOR}\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_VERSION_MINOR ${ILMBASE_VERSION_MINOR}\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "#define ILMBASE_VERSION_PATCH ${ILMBASE_VERSION_PATCH}\n" )
FILE ( APPEND ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h "
// 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))
")
ENDIF()
SET (ILMBASE_LIBSUFFIX "")
IF (ILMBASE_NAMESPACE_VERSIONING)
SET ( ILMBASE_LIBSUFFIX "-${ILMBASE_VERSION_API}" )
ENDIF ()
SET_TARGET_PROPERTIES ( Iex
PROPERTIES
OUTPUT_NAME "Iex${ILMBASE_LIBSUFFIX}"
)
SET_TARGET_PROPERTIES ( Imath
PROPERTIES
OUTPUT_NAME "Imath${ILMBASE_LIBSUFFIX}"
)
SET_TARGET_PROPERTIES ( IlmThread
PROPERTIES
OUTPUT_NAME "IlmThread${ILMBASE_LIBSUFFIX}"
)
SET_TARGET_PROPERTIES ( IexMath
PROPERTIES
OUTPUT_NAME "IexMath${ILMBASE_LIBSUFFIX}"
)
IF ( NOT WIN32 AND ILMIMF_CREATE_LIBTOOL_FILE)
CREATE_LIBTOOL_FILE ( Half /lib )
CREATE_LIBTOOL_FILE ( Iex /lib )
CREATE_LIBTOOL_FILE ( IexMath /lib )
CREATE_LIBTOOL_FILE ( Imath /lib )
CREATE_LIBTOOL_FILE ( IlmThread /lib )
ENDIF ()
# Tests
if(ILMIMF_BUILD_TESTS)
ADD_SUBDIRECTORY ( HalfTest )
ADD_SUBDIRECTORY ( IexTest )
ADD_SUBDIRECTORY ( ImathTest )
endif()
# Installation
INSTALL ( FILES
${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h
DESTINATION
include/OpenEXR
)
if(ILMIMF_INSTALL_PKGCONFIG)
FILE ( WRITE ${CMAKE_BINARY_DIR}/IlmBase.pc "prefix=${CMAKE_INSTALL_PREFIX}\n" )
FILE ( APPEND ${CMAKE_BINARY_DIR}/IlmBase.pc "exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include
OpenEXR_includedir=\${prefix}/include/OpenEXR
Name: IlmBase
Description: Base math and exception libraries
Version: ${ILMBASE_VERSION}
Libs: -L\${libdir} -lImath${ILMBASE_LIBSUFFIX} -lIexMath${ILMBASE_LIBSUFFIX} -lHalf -lIex${ILMBASE_LIBSUFFIX} -lIlmThread${ILMBASE_LIBSUFFIX} -pthread
Cflags: -pthread -I\${OpenEXR_includedir}
")
INSTALL ( FILES
${CMAKE_BINARY_DIR}/IlmBase.pc
DESTINATION
lib/pkgconfig
)
endif()

View File

@@ -0,0 +1,34 @@
Copyright (c) 2006, Industrial Light & Magic, a division of Lucasfilm
Entertainment Company Ltd. Portions contributed and copyright held by
others as indicated. 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
any other contributors to this software 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.

View File

@@ -0,0 +1,136 @@
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.
(Piotr Stanczyk)
* Added ImathNoise.(h/cpp) files. Initializes Perlin noise to match the
Renderman implmenetation.
(Pixar Contribution)
* Fixed a number of missing includes to comply with stricter
enforcement by gnu compilers.
(Piotr Stanczyk)
* Depracated compiler flag: -Wno-long-double since it is no longer
supported under OS X.
(Piotr Stanczyk)
* A minor API change to Imath::Frustum has been made: the functions
'near' and 'far' have been renamed to 'nearPlane' and 'farPlane' due
to conflicts with certain windows headers. The former alternate
accessor names for these values on windows ('hither' and 'yon')
remain, though should be considered deprecated.
(David Lenihan)
* Added SVD, eigenvalue solver, and procrustes fit calculations
to ImathMatrixAlgo.
(Chris Twigg, Ji Hun Yu)
* Added Imath::FrustumTest for frustum visibility testing.
(Eric Johnston)
* Fixed a stack corruption in the matrix minorOf functions.
(Nick Rasmussen)
* Visual studio 2008 project files have been added to the vc/vc9
directory, and several minor visual studio compile fixes have
been applied.
(Nick Rasmussen)
* Updated the so verison to 7.
(Piotr Stanczyk)
* Depracated the MacCode_Warrior and Shake submodules.
(Piotr Stanczyk)
Version 1.0.2
* Added support for targetting builds on 64bit Windows and minimising
number of compiler warnings on Windows. Thanks to Ger Hobbelt for his
contributions to CreateDLL.
(Ji Hun Yu)
* Removed a spurious restrict qualifier in the matrix manipulation code
that was causing the 64-bit MS compiler to generate code in release
mode that caused incorrect results.
(Ji Hun Yu)
* Added patches for improving universal binaries on OS X. Thanks to
Paul Schneider for the contribution
(Piotr Stanczyk)
* Imath::Box optimization: remove loops from methods by partially
specializing the class, for boxes of two and three dimensions.
(Piotr Stanczyk)
* Added explicit copy constructors to Imath::Matrix33<T> and
ImathMatrix44<T> to make conversions between float and double
matrices more convenient.
(Florian Kainz)
* Added slerpShortestArc() and euclideanInnerProduct() functions
to Imath::Quat<T>.
(Nick Porcino)
* Added 4D vector class template Imath::Vec4<T>.
(Nick Porcino)
* Copy constructors and assignment operators for Matrix33<T>
and Matrix44<T> are up to 25% faster. Added matrix constructors
that do not initialize the matrix (this is faster in cases where
the initial value of the matrix is immediately overwritten anyway).
(Nick Porcino)
* Rewrote function closestPointOnBox(point,box). Shortened
the code, improved numerical accuracy, fixed a bug where
closestPointOnBox(box.center(),box) would return the center
of the +Z side of the box, even if the +/-X or +/-Y sides
were closer.
(Florian Kainz)
* Rewrote function findEntryAndExitPoints() in ImathBoxAlgo.h.
Results are now consistent with those from intersect(), also
in ImathBoxAlgo.h.
(Florian Kainz)
* Made Vec2<T>::length() and Vec3<T>::length() more accurate for
vectors whose length is less than sqrt(limits<T>::smallest());
(Florian Kainz)
* Made Quat<T>::angle() more accurate for small angles.
(Don Hatch)
Version 1.0.1:
* Removed Windows .suo files from distribution.
(Eric Wimmer)
Version 1.0.0:
* Bumped DSO version number to 6.0
(Florian Kainz)
* Rounding during float-to-half conversion now implements
"round to nearest even" mode: if the original float value
is exactly in the middle between the two closest half values
then rounding chooses the half value whose least significant
bit is zero.
(Florian Kainz)
* Installation Tuning:
- Corrected version number on dso's (libtool) - now 5.0
- Separated ILMBASE_LDFLAGS and ILMBASE_LIBS so that test programs
in configure scripts of packages dependent on IlmBase can link
with static libraries properly
- eliminated some warning messages during install
(Andrew Kunz)
Version 0.9.0:
* Initial release of this code as a separate library.
Previously the libraries contained were part of
version 1.4.0 of OpenEXR
* New build scripts for Linux/Unix
(Andrew Kunz)
* New Windows project files and build scripts
(Kimball Thurston)

View File

@@ -0,0 +1,16 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps

View File

@@ -0,0 +1,58 @@
# yue.nicholas@gmail.com
ADD_EXECUTABLE ( eLut eLut.cpp )
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/eLut.h
COMMAND eLut ARGS > ${CMAKE_CURRENT_BINARY_DIR}/eLut.h
DEPENDS eLut
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_CURRENT_BINARY_DIR}/eLut.h
PROPERTIES HEADER_FILE_ONLY TRUE
)
ADD_EXECUTABLE ( toFloat toFloat.cpp )
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/toFloat.h
COMMAND toFloat ARGS > ${CMAKE_CURRENT_BINARY_DIR}/toFloat.h
DEPENDS toFloat
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_CURRENT_BINARY_DIR}/toFloat.h
PROPERTIES HEADER_FILE_ONLY TRUE
)
SET_SOURCE_FILES_PROPERTIES(
half.cpp
PROPERTIES
OBJECT_DEPENDS
"${CMAKE_CURRENT_BINARY_DIR}/eLut.h;${CMAKE_CURRENT_BINARY_DIR}/toFloat.h"
)
IF(ILMBASE_BUILD_SHARED_LIBS)
ADD_DEFINITIONS(-DHALF_EXPORTS)
ENDIF()
ADD_LIBRARY ( Half ${LIB_TYPE}
half.cpp
)
ADD_DEPENDENCIES ( Half toFloat eLut )
INSTALL ( TARGETS
Half
DESTINATION
${OPENEXR_INSTALL_LIB_DEST}
)
INSTALL ( FILES
half.h
halfFunction.h
halfExport.h
halfLimits.h
DESTINATION
${OPENEXR_INSTALL_HEADER_DEST}
)

View File

@@ -0,0 +1,32 @@
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir)/config
lib_LTLIBRARIES = libHalf.la
libHalf_la_SOURCES = half.cpp half.h halfFunction.h halfLimits.h
libHalf_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
libHalfincludedir = $(includedir)/OpenEXR
libHalfinclude_HEADERS = half.h halfFunction.h halfLimits.h halfExport.h
# these are used to build eLut.h and toFloat.h dynamically
EXTRA_DIST = eLut.cpp toFloat.cpp CMakeLists.txt
CLEANFILES = eLut eLut.h toFloat toFloat.h
eLut_SOURCES = eLut.cpp
toFloat_SOURCES = toFloat.cpp
eLut.h: eLut
./eLut > eLut.h
toFloat.h: toFloat
./toFloat > toFloat.h
BUILT_SOURCES = eLut.h toFloat.h
noinst_PROGRAMS = eLut toFloat

View File

@@ -0,0 +1,114 @@
///////////////////////////////////////////////////////////////////////////
//
// 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 <iostream>
#include <iomanip>
using namespace std;
//-----------------------------------------------------
// 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).
//-----------------------------------------------------
void
initELut (unsigned short eLut[])
{
for (int i = 0; i < 0x100; i++)
{
int e = (i & 0x0ff) - (127 - 15);
if (e <= 0 || e >= 30)
{
//
// Special case
//
eLut[i] = 0;
eLut[i | 0x100] = 0;
}
else
{
//
// Common case - normalized half, no exponent overflow possible
//
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] << ", ";
if (i % 8 == 7)
{
cout << "\n";
if (i < tableSize - 1)
cout << " ";
}
}
cout << "};\n";
return 0;
}

View File

@@ -0,0 +1,310 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// class half --
// implementation of non-inline members
//
//---------------------------------------------------------------------------
#include <assert.h>
#include "half.h"
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"
//-----------------------------------------------
// Overflow handler for float-to-half conversion;
// generates a hardware floating-point overflow,
// which may be trapped by the operating system.
//-----------------------------------------------
HALF_EXPORT float
half::overflow ()
{
volatile float f = 1e10;
for (int i = 0; i < 10; i++)
f *= f; // this will overflow before
// the for<6F>loop terminates
return f;
}
//-----------------------------------------------------
// Float-to-half conversion -- general case, including
// zeroes, denormalized numbers and exponent overflows.
//-----------------------------------------------------
HALF_EXPORT short
half::convert (int i)
{
//
// Our floating point number, f, is represented by the bit
// pattern in integer i. Disassemble that bit pattern into
// the sign, s, the exponent, e, and the significand, m.
// Shift s into the position where it will go in in the
// resulting half number.
// Adjust e, accounting for the different exponent bias
// of float and half (127 versus 15).
//
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:
//
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;
}
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);
}
}
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);
}
}
//---------------------
// Stream I/O operators
//---------------------
HALF_EXPORT ostream &
operator << (ostream &os, half h)
{
os << float (h);
return os;
}
HALF_EXPORT istream &
operator >> (istream &is, half &h)
{
float f;
is >> f;
h = half (f);
return is;
}
//---------------------------------------
// Functions to print the bit-layout of
// floats and halfs, mostly for debugging
//---------------------------------------
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');
if (i == 15 || i == 10)
os << ' ';
}
}
HALF_EXPORT void
printBits (ostream &os, float f)
{
half::uif x;
x.f = f;
for (int i = 31; i >= 0; i--)
{
os << (((x.i >> i) & 1)? '1': '0');
if (i == 31 || i == 23)
os << ' ';
}
}
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');
if (i == 15 || i == 10)
c[++j] = ' ';
}
c[18] = 0;
}
HALF_EXPORT void
printBits (char c[35], float f)
{
half::uif x;
x.f = f;
for (int i = 31, j = 0; i >= 0; i--, j++)
{
c[j] = (((x.i >> i) & 1)? '1': '0');
if (i == 31 || i == 23)
c[++j] = ' ';
}
c[34] = 0;
}

View File

@@ -0,0 +1,758 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// half -- a 16-bit floating point number class:
//
// Type half can represent positive and negative numbers whose
// magnitude is between roughly 6.1e-5 and 6.5e+4 with a relative
// error of 9.8e-4; numbers smaller than 6.1e-5 can be represented
// with an absolute error of 6.0e-8. All integers from -2048 to
// +2048 can be represented exactly.
//
// Type half behaves (almost) like the built-in C++ floating point
// types. In arithmetic expressions, half, float and double can be
// mixed freely. Here are a few examples:
//
// half a (3.5);
// float b (a + sqrt (a));
// a += b;
// b += a;
// b = a + 7;
//
// Conversions from half to float are lossless; all half numbers
// are exactly representable as floats.
//
// Conversions from float to half may not preserve a float's value
// exactly. If a float is not representable as a half, then the
// float value is rounded to the nearest representable half. If a
// float value is exactly in the middle between the two closest
// representable half values, then the float value is rounded to
// the closest half whose least significant bit is zero.
//
// Overflows during float-to-half conversions cause arithmetic
// exceptions. An overflow occurs when the float value to be
// converted is too large to be represented as a half, or if the
// float value is an infinity or a NAN.
//
// The implementation of type half makes the following assumptions
// about the implementation of the built-in C++ types:
//
// float is an IEEE 754 single-precision number
// sizeof (float) == 4
// sizeof (unsigned int) == sizeof (float)
// alignof (unsigned int) == alignof (float)
// sizeof (unsigned short) == 2
//
//---------------------------------------------------------------------------
#ifndef _HALF_H_
#define _HALF_H_
#include "halfExport.h" // for definition of HALF_EXPORT
#include <iostream>
class half
{
public:
//-------------
// Constructors
//-------------
half (); // no initialization
half (float f);
half(const half & h): _h(h._h) { }
//--------------------
// Conversion to float
//--------------------
operator float () const;
//------------
// Unary minus
//------------
half operator - () const;
//-----------
// Assignment
//-----------
half & operator = (half h);
half & operator = (float f);
half & operator += (half h);
half & operator += (float f);
half & operator -= (half h);
half & operator -= (float f);
half & operator *= (half h);
half & operator *= (float f);
half & operator /= (half h);
half & operator /= (float f);
//---------------------------------------------------------
// Round to n-bit precision (n should be between 0 and 10).
// After rounding, the significand's 10-n least significant
// bits will be zero.
//---------------------------------------------------------
half round (unsigned int n) const;
//--------------------------------------------------------------------
// Classification:
//
// h.isFinite() returns true if h is a normalized number,
// a denormalized number or zero
//
// h.isNormalized() returns true if h is a normalized number
//
// h.isDenormalized() returns true if h is a denormalized number
//
// h.isZero() returns true if h is zero
//
// h.isNan() returns true if h is a NAN
//
// h.isInfinity() returns true if h is a positive
// or a negative infinity
//
// h.isNegative() returns true if the sign bit of h
// is set (negative)
//--------------------------------------------------------------------
bool isFinite () const;
bool isNormalized () const;
bool isDenormalized () const;
bool isZero () const;
bool isNan () const;
bool isInfinity () const;
bool isNegative () const;
//--------------------------------------------
// Special values
//
// posInf() returns +infinity
//
// negInf() returns -infinity
//
// qNan() returns a NAN with the bit
// pattern 0111111111111111
//
// sNan() returns a NAN with the bit
// pattern 0111110111111111
//--------------------------------------------
static half posInf ();
static half negInf ();
static half qNan ();
static half sNan ();
//--------------------------------------
// Access to the internal representation
//--------------------------------------
HALF_EXPORT unsigned short bits () const;
HALF_EXPORT void setBits (unsigned short bits);
public:
union uif
{
unsigned int i;
float f;
};
private:
HALF_EXPORT static short convert (int i);
HALF_EXPORT static float overflow ();
unsigned short _h;
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);
//----------
// 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);
//-------------------------------------------------------------------------
// Limits
//
// Visual C++ will complain if HALF_MIN, HALF_NRM_MIN etc. are not float
// constants, but at least one other compiler (gcc 2.96) produces incorrect
// results if they are.
//-------------------------------------------------------------------------
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#define HALF_MIN 5.96046448e-08f // Smallest positive half
#define HALF_NRM_MIN 6.10351562e-05f // Smallest positive normalized half
#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)
#else
#define HALF_MIN 5.96046448e-08 // Smallest positive half
#define HALF_NRM_MIN 6.10351562e-05 // Smallest positive normalized half
#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)
#endif
#define HALF_MANT_DIG 11 // Number of digits in mantissa
// (significand + hidden leading 1)
#define HALF_DIG 2 // Number of base 10 digits that
// can be represented without change
#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
#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
#define HALF_MIN_10_EXP -4 // Minimum positive integer such
// 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
//---------------------------------------------------------------------------
//
// Implementation --
//
// Representation of a float:
//
// We assume that a float, f, is an IEEE 754 single-precision
// floating point number, whose bits are arranged as follows:
//
// 31 (msb)
// |
// | 30 23
// | | |
// | | | 22 0 (lsb)
// | | | | |
// X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX
//
// s e m
//
// S is the sign-bit, e is the exponent and m is the significand.
//
// If e is between 1 and 254, f is a normalized number:
//
// s e-127
// f = (-1) * 2 * 1.m
//
// If e is 0, and m is not zero, f is a denormalized number:
//
// s -126
// f = (-1) * 2 * 0.m
//
// If e and m are both zero, f is zero:
//
// f = 0.0
//
// If e is 255, f is an "infinity" or "not a number" (NAN),
// depending on whether m is zero or not.
//
// Examples:
//
// 0 00000000 00000000000000000000000 = 0.0
// 0 01111110 00000000000000000000000 = 0.5
// 0 01111111 00000000000000000000000 = 1.0
// 0 10000000 00000000000000000000000 = 2.0
// 0 10000000 10000000000000000000000 = 3.0
// 1 10000101 11110000010000000000000 = -124.0625
// 0 11111111 00000000000000000000000 = +infinity
// 1 11111111 00000000000000000000000 = -infinity
// 0 11111111 10000000000000000000000 = NAN
// 1 11111111 11111111111111111111111 = NAN
//
// Representation of a half:
//
// Here is the bit-layout for a half number, h:
//
// 15 (msb)
// |
// | 14 10
// | | |
// | | | 9 0 (lsb)
// | | | | |
// X XXXXX XXXXXXXXXX
//
// s e m
//
// S is the sign-bit, e is the exponent and m is the significand.
//
// If e is between 1 and 30, h is a normalized number:
//
// s e-15
// h = (-1) * 2 * 1.m
//
// If e is 0, and m is not zero, h is a denormalized number:
//
// S -14
// h = (-1) * 2 * 0.m
//
// If e and m are both zero, h is zero:
//
// h = 0.0
//
// If e is 31, h is an "infinity" or "not a number" (NAN),
// depending on whether m is zero or not.
//
// Examples:
//
// 0 00000 0000000000 = 0.0
// 0 01110 0000000000 = 0.5
// 0 01111 0000000000 = 1.0
// 0 10000 0000000000 = 2.0
// 0 10000 1000000000 = 3.0
// 1 10101 1111000001 = -124.0625
// 0 11111 0000000000 = +infinity
// 1 11111 0000000000 = -infinity
// 0 11111 1000000000 = NAN
// 1 11111 1111111111 = NAN
//
// Conversion:
//
// Converting from a float to a half requires some non-trivial bit
// manipulations. In some cases, this makes conversion relatively
// slow, but the most common case is accelerated via table lookups.
//
// Converting back from a half to a float is easier because we don't
// have to do any rounding. In addition, there are only 65536
// different half numbers; we can convert each of those numbers once
// and store the results in a table. Later, all conversions can be
// done using only simple table lookups.
//
//---------------------------------------------------------------------------
//--------------------
// Simple constructors
//--------------------
inline
half::half ()
{
// no initialization
}
//----------------------------
// Half-from-float constructor
//----------------------------
inline
half::half (float f)
{
uif x;
x.f = f;
if (f == 0)
{
//
// Common special case - zero.
// Preserve the zero's sign bit.
//
_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.
//
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);
}
}
}
//------------------------------------------
// Half-to-float conversion via table lookup
//------------------------------------------
inline
half::operator float () const
{
return _toFloat[_h].f;
}
//-------------------------
// Round to n-bit precision
//-------------------------
inline half
half::round (unsigned int n) const
{
//
// Parameter check.
//
if (n >= 10)
return *this;
//
// Disassemble h into the sign, s,
// and the combined exponent and significand, e.
//
unsigned short s = _h & 0x8000;
unsigned short e = _h & 0x7fff;
//
// Round the exponent and significand to the nearest value
// where ones occur only in the (10-n) most significant bits.
// Note that the exponent adjusts automatically if rounding
// up causes the significand to overflow.
//
e >>= 9 - n;
e += e & 1;
e <<= 9 - n;
//
// Check for exponent overflow.
//
if (e >= 0x7c00)
{
//
// Overflow occurred -- truncate instead of rounding.
//
e = _h;
e >>= 10 - n;
e <<= 10 - n;
}
//
// Put the original sign bit back.
//
half h;
h._h = s | e;
return h;
}
//-----------------------
// Other inline functions
//-----------------------
inline half
half::operator - () const
{
half h;
h._h = _h ^ 0x8000;
return h;
}
inline half &
half::operator = (half h)
{
_h = h._h;
return *this;
}
inline half &
half::operator = (float f)
{
*this = half (f);
return *this;
}
inline half &
half::operator += (half h)
{
*this = half (float (*this) + float (h));
return *this;
}
inline half &
half::operator += (float f)
{
*this = half (float (*this) + f);
return *this;
}
inline half &
half::operator -= (half h)
{
*this = half (float (*this) - float (h));
return *this;
}
inline half &
half::operator -= (float f)
{
*this = half (float (*this) - f);
return *this;
}
inline half &
half::operator *= (half h)
{
*this = half (float (*this) * float (h));
return *this;
}
inline half &
half::operator *= (float f)
{
*this = half (float (*this) * f);
return *this;
}
inline half &
half::operator /= (half h)
{
*this = half (float (*this) / float (h));
return *this;
}
inline half &
half::operator /= (float f)
{
*this = half (float (*this) / f);
return *this;
}
inline bool
half::isFinite () const
{
unsigned short e = (_h >> 10) & 0x001f;
return e < 31;
}
inline bool
half::isNormalized () const
{
unsigned short e = (_h >> 10) & 0x001f;
return e > 0 && e < 31;
}
inline bool
half::isDenormalized () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 0 && m != 0;
}
inline bool
half::isZero () const
{
return (_h & 0x7fff) == 0;
}
inline bool
half::isNan () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 31 && m != 0;
}
inline bool
half::isInfinity () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 31 && m == 0;
}
inline bool
half::isNegative () const
{
return (_h & 0x8000) != 0;
}
inline half
half::posInf ()
{
half h;
h._h = 0x7c00;
return h;
}
inline half
half::negInf ()
{
half h;
h._h = 0xfc00;
return h;
}
inline half
half::qNan ()
{
half h;
h._h = 0x7fff;
return h;
}
inline half
half::sNan ()
{
half h;
h._h = 0x7dff;
return h;
}
inline unsigned short
half::bits () const
{
return _h;
}
inline void
half::setBits (unsigned short bits)
{
_h = bits;
}
#endif

View File

@@ -0,0 +1,27 @@
#ifndef HALFEXPORT_H
#define HALFEXPORT_H
//
// Copyright (c) 2008 Lucasfilm Entertainment Company Ltd.
// All rights reserved. Used under authorization.
// This material contains the confidential and proprietary
// information of Lucasfilm Entertainment Company and
// may not be copied in whole or in part without the express
// written permission of Lucasfilm Entertainment Company.
// This copyright notice does not imply publication.
//
#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
#endif // #ifndef HALFEXPORT_H

View File

@@ -0,0 +1,179 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// halfFunction<T> -- a class for fast evaluation
// of half --> T functions
//
// The constructor for a halfFunction object,
//
// halfFunction (function,
// domainMin, domainMax,
// defaultValue,
// posInfValue, negInfValue,
// nanValue);
//
// evaluates the function for all finite half values in the interval
// [domainMin, domainMax], and stores the results in a lookup table.
// For finite half values that are not in [domainMin, domainMax], the
// constructor stores defaultValue in the table. For positive infinity,
// negative infinity and NANs, posInfValue, negInfValue and nanValue
// are stored in the table.
//
// The tabulated function can then be evaluated quickly for arbitrary
// half values by calling the the halfFunction object's operator()
// method.
//
// Example:
//
// #include <math.h>
// #include <halfFunction.h>
//
// halfFunction<half> hsin (sin);
//
// halfFunction<half> hsqrt (sqrt, // function
// 0, HALF_MAX, // domain
// half::qNan(), // sqrt(x) for x < 0
// half::posInf(), // sqrt(+inf)
// half::qNan(), // sqrt(-inf)
// half::qNan()); // sqrt(nan)
//
// half x = hsin (1);
// half y = hsqrt (3.5);
//
//---------------------------------------------------------------------------
#ifndef _HALF_FUNCTION_H_
#define _HALF_FUNCTION_H_
#include "half.h"
#include "IlmBaseConfig.h"
#ifndef ILMBASE_HAVE_LARGE_STACK
#include <string.h> // need this for memset
#else
#endif
#include <float.h>
template <class T>
class halfFunction
{
public:
//------------
// Constructor
//------------
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);
#ifndef ILMBASE_HAVE_LARGE_STACK
~halfFunction () { delete [] _lut; }
#endif
//-----------
// Evaluation
//-----------
T operator () (half x) const;
private:
#ifdef ILMBASE_HAVE_LARGE_STACK
T _lut[1 << 16];
#else
T * _lut;
#endif
};
//---------------
// Implementation
//---------------
template <class T>
template <class Function>
halfFunction<T>::halfFunction (Function f,
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);
}
}
template <class T>
inline T
halfFunction<T>::operator () (half x) const
{
return _lut[x.bits()];
}
#endif

View File

@@ -0,0 +1,102 @@
///////////////////////////////////////////////////////////////////////////
//
// 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.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
#ifndef INCLUDED_HALF_LIMITS_H
#define INCLUDED_HALF_LIMITS_H
//------------------------------------------------------------------------
//
// C++ standard library-style numeric_limits for class half
//
//------------------------------------------------------------------------
#include <limits>
#include "half.h"
namespace std {
template <>
class numeric_limits <half>
{
public:
static const bool is_specialized = true;
static half min () {return HALF_NRM_MIN;}
static half max () {return HALF_MAX;}
static const int digits = HALF_MANT_DIG;
static const int digits10 = HALF_DIG;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
static const int radix = HALF_RADIX;
static half epsilon () {return HALF_EPSILON;}
static half round_error () {return HALF_EPSILON / 2;}
static const int min_exponent = HALF_MIN_EXP;
static const int min_exponent10 = HALF_MIN_10_EXP;
static const int max_exponent = HALF_MAX_EXP;
static const int max_exponent10 = HALF_MAX_10_EXP;
static const bool has_infinity = true;
static const bool has_quiet_NaN = true;
static const bool has_signaling_NaN = true;
static const float_denorm_style has_denorm = denorm_present;
static const bool has_denorm_loss = false;
static half infinity () {return half::posInf();}
static half quiet_NaN () {return half::qNan();}
static half signaling_NaN () {return half::sNan();}
static half denorm_min () {return HALF_MIN;}
static const bool is_iec559 = false;
static const bool is_bounded = false;
static const bool is_modulo = false;
static const bool traps = true;
static const bool tinyness_before = false;
static const float_round_style round_style = round_to_nearest;
};
} // namespace std
#endif

View File

@@ -0,0 +1,164 @@
///////////////////////////////////////////////////////////////////////////
//
// 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;
}

View File

@@ -0,0 +1,16 @@
Makefile
Makefile.in
config.h.in
config.h
config.log
config.status
configure
libtool
stamp-h
aclocal.m4
OpenEXR.pc
autom4te.cache
ltmain.sh
stamp-h.in
depcomp
.deps

View File

@@ -0,0 +1,16 @@
# yue.nicholas@gmail.com
ADD_EXECUTABLE ( HalfTest
main.cpp
testArithmetic.cpp
testBitPatterns.cpp
testClassification.cpp
testError.cpp
testFunction.cpp
testLimits.cpp
testSize.cpp
)
TARGET_LINK_LIBRARIES ( HalfTest Half )
ADD_TEST ( TestHalf HalfTest )

View File

@@ -0,0 +1,19 @@
## Process this file with automake to produce Makefile.in
check_PROGRAMS = HalfTest
HalfTest_SOURCES = main.cpp testArithmetic.cpp testArithmetic.h \
testBitPatterns.cpp testBitPatterns.h \
testClassification.cpp testClassification.h \
testError.cpp testError.h testFunction.cpp \
testFunction.h testLimits.cpp testLimits.h testSize.cpp \
testSize.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Half -I$(top_srcdir)/config
LDADD = -L$(top_builddir)/Half -lHalf
TESTS = HalfTest
EXTRA_DIST = CMakeLists.txt

View File

@@ -0,0 +1,32 @@
#include <testSize.h>
#include <testArithmetic.h>
#include <testError.h>
#include <testBitPatterns.h>
#include <testClassification.h>
#include <testLimits.h>
#include <testFunction.h>
#include <iostream>
#include <string.h>
#define TEST(x) if (argc < 2 || !strcmp (argv[1], #x)) x();
int
main (int argc, char *argv[])
{
std::cout << "\ntesting type half:\n\n" << std::flush;
TEST (testSize);
TEST (testArithmetic);
TEST (testNormalizedConversionError);
TEST (testDenormalizedConversionError);
TEST (testRoundingError);
TEST (testBitPatterns);
TEST (testClassification);
TEST (testLimits);
TEST (testFunction);
return 0;
}

View File

@@ -0,0 +1,55 @@
#include <testArithmetic.h>
#include "half.h"
#include <iostream>
#include <assert.h>
using namespace std;
void
testArithmetic ()
{
cout << "basic arithmetic operations:\n";
float f1 (1);
float f2 (2);
half h1 (3);
half h2 (4);
cout << "f1 = " << f1 << ", "
"f2 = " << f2 << ", "
"h1 = " << h1 << ", "
"h2 = " << h2 << endl;
h1 = f1 + f2;
assert (h1 == 3);
cout << "h1 = f1 + f2: " << h1 << endl;
h2 += f1;
assert (h2 == 5);
cout << "h2 += f1: " << h2 << endl;
h2 = h1 + h2;
assert (h2 == 8);
cout << "h2 = h1 + h2: " << h2 << endl;
h2 += h1;
assert (h2 == 11);
cout << "h2 += h1: " << h2 << endl;
h1 = h2;
assert (h1 == 11);
cout << "h1 = h2: " << h1 << endl;
h2 = -h1;
assert (h2 == -11);
cout << "h2 = -h1: " << h2 << endl;
cout << "ok\n\n" << flush;
}

View File

@@ -0,0 +1,3 @@
void testArithmetic ();

View File

@@ -0,0 +1,484 @@
#include <testBitPatterns.h>
#include "half.h"
#include <float.h>
#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;
namespace {
bool
equalBitPatterns (const char *b1, const char *b2)
{
//
// Returns true if the characters in zero-terminated string b1
// are the same as the charaters in string b2, except for places
// where b1 or b2 contains an 'X'. For example:
//
// equalBitPatterns ("100", "100") returns true
// equalBitPatterns ("100", "101") returns false
// equalBitPatterns ("10X", "101") returns true
// equalBitPatterns ("10X", "100") returns true
//
while (*b1 && *b2)
{
if (*b1 != *b2 && *b1 != 'X' && *b2 != 'X')
return false;
++b1;
++b2;
}
return !(*b1 || *b2);
}
void
testBits (float f, const char bh[19], const char bg[35])
{
half h (f);
float g (h);
cout.width (15);
cout.precision (8);
cout << f << " ";
printBits (cout, f);
cout << " ";
printBits (cout, h);
cout << '\n';
cout.width (15);
cout << g << " ";
printBits (cout, g);
cout << "\n\n";
if (bh || bg)
{
char ch[19], cg[35];
printBits (ch, h);
printBits (cg, g);
if (!equalBitPatterns (ch, bh))
{
cout << "error: expected " << bh << ", got " << ch << endl;
assert (false);
}
if (!equalBitPatterns (cg, bg))
{
cout << "error: expected " << bg << ", got " << cg << endl;
assert (false);
}
}
}
float
floatPosInfinity ()
{
half::uif x;
x.i = 0x7f800000;
return x.f;
}
float
floatNegInfinity ()
{
half::uif x;
x.i = 0xff800000;
return x.f;
}
float
floatPosQNan1 ()
{
half::uif x;
x.i = 0x7fffffff;
return x.f;
}
float
floatNegQNan1 ()
{
half::uif x;
x.i = 0xffffffff;
return x.f;
}
float
floatPosQNan2 ()
{
half::uif x;
x.i = 0x7fd55555;
return x.f;
}
float
floatNegQNan2 ()
{
half::uif x;
x.i = 0xffd55555;
return x.f;
}
} // namespace
void
testBitPatterns()
{
cout << "specific bit patterns\n\n";
//
// Numbers close to 1.0
//
testBits (1.0f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f + HALF_EPSILON,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON * 0.5f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f+ HALF_EPSILON * 0.4999f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f + HALF_EPSILON * 0.5001f,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.5f,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.4999f,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.5001f,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.5f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.4999f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.5001f,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
//
// Numbers close to HALF_MIN
//
testBits (HALF_MIN,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5f,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.4999f,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5001f,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5f,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.4999f,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5001f,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
//
// Numbers close to HALF_NRM_MIN
//
testBits (HALF_NRM_MIN,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.4999f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5001f,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN - HALF_MIN,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.5f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.49995f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.50005f,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
//
// Small positive integers and simple decimal fractions
//
testBits (2,
"0 10000 0000000000",
"0 10000000 00000000000000000000000");
testBits (3,
"0 10000 1000000000",
"0 10000000 10000000000000000000000");
testBits (10,
"0 10010 0100000000",
"0 10000010 01000000000000000000000");
testBits (0.1f,
"0 01011 1001100110",
"0 01111011 10011001100000000000000");
testBits (0.2f,
"0 01100 1001100110",
"0 01111100 10011001100000000000000");
testBits (0.3f,
"0 01101 0011001101",
"0 01111101 00110011010000000000000");
//
// Numbers close to HALF_MAX
//
testBits (HALF_MAX,
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * 1.0,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25f),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25005f),
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.24995f),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
//
// Large positive numbers, positive infinity and NANs
//
testBits (HALF_MAX * HALF_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (FLT_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosInfinity(),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosQNan1(),
"0 11111 1111111111", // nan
"0 11111111 11111111110000000000000"); // nan
testBits (floatPosQNan2(),
"0 11111 1010101010", // nan
"0 11111111 10101010100000000000000"); // nan
//
// Numbers close to -1.0
//
testBits (-1.0,
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.5f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.4999f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.5001f),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.5f),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.4999f),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.5001f),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.5f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.4999f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.5001f),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
//
// Numbers close to -HALF_MIN
//
testBits (-HALF_MIN,
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5f),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.4999f),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5001f),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN),
"X 00000 0000000000",
"X 00000000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5f),
"1 00000 0000000000",
"1 00000000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.4999f),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5001f),
"1 00000 0000000000",
"1 00000000 00000000000000000000000");
//
// Numbers close to -HALF_NRM_MIN
//
testBits (-HALF_NRM_MIN,
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.4999f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5001f),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.5f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.49995f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.50005f),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
//
// Small negative integers and simple decimal fractions
//
testBits (-2,
"1 10000 0000000000",
"1 10000000 00000000000000000000000");
testBits (-3,
"1 10000 1000000000",
"1 10000000 10000000000000000000000");
testBits (-10,
"1 10010 0100000000",
"1 10000010 01000000000000000000000");
testBits (-0.1f,
"1 01011 1001100110",
"1 01111011 10011001100000000000000");
testBits (-0.2f,
"1 01100 1001100110",
"1 01111100 10011001100000000000000");
testBits (-0.3f,
"1 01101 0011001101",
"1 01111101 00110011010000000000000");
//
// Numbers close to -HALF_MAX
//
testBits (-HALF_MAX,
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * 1.0f,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25f),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25005f),
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.24995f),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
//
// Large negative numbers, negative infinity and NANs
//
testBits (-HALF_MAX * HALF_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-FLT_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegInfinity(),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegQNan1(),
"1 11111 1111111111", // nan
"1 11111111 11111111110000000000000"); // nan
testBits (floatNegQNan2(),
"1 11111 1010101010", // nan
"1 11111111 10101010100000000000000"); // nan
cout << "ok\n\n" << flush;
}

Some files were not shown because too many files have changed in this diff Show More