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

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,40 @@
ADD_EXECUTABLE ( playexr
main.cpp
playExr.cpp
playExr.h
fileNameForFrame.cpp
fileNameForFrame.h
FileReadingThread.cpp
FileReadingThread.h
ImageBuffers.cpp
ImageBuffers.h
Timer.cpp
Timer.h
ctlToLut.cpp
ctlToLut.h
osDependent.cpp
osDependent.h
)
INCLUDE_DIRECTORIES (
${CG_INCLUDE_PATH}
)
TARGET_LINK_LIBRARIES ( playexr
IlmImf${OPENEXR_LIBSUFFIX}
Iex${ILMBASE_LIBSUFFIX}
IlmThread${ILMBASE_LIBSUFFIX}
Half
${CG_LIBRARY}
${CG_GL_LIBRARY}
${OPENGL_LIBRARIES}
${GLUT_LIBRARY}
)
INSTALL ( TARGETS
playexr
DESTINATION
${CMAKE_INSTALL_PREFIX}/bin
)

View File

@ -0,0 +1,169 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class FileReadingThread
//
//-----------------------------------------------------------------------------
#include "FileReadingThread.h"
#include "fileNameForFrame.h"
#include "ImageBuffers.h"
#include <ImfInputFile.h>
#include <Iex.h>
#include <iostream>
using namespace OPENEXR_IMF_NAMESPACE;
using namespace ILMTHREAD_NAMESPACE;
using namespace IEX_NAMESPACE;
using namespace std;
FileReadingThread::FileReadingThread
(const char fileNameTemplate[],
int firstFrame,
int lastFrame,
ImageBuffers &imageBuffers)
:
Thread(),
_fileNameTemplate (fileNameTemplate),
_firstFrame (firstFrame),
_lastFrame (lastFrame),
_imageBuffers (imageBuffers)
{
start(); // start() calls run()
}
void
FileReadingThread::run ()
{
try
{
int i = 0; // index of the image buffer we will fill next
int frame = _firstFrame;
while (true)
{
//
// Check if the display thread wants us to exit.
//
if (_imageBuffers.exitSemaphore1.tryWait())
{
_imageBuffers.exitSemaphore2.post();
return;
}
//
// Wait for an image buffer to become available.
//
_imageBuffers.emptyBuffersSemaphore.wait();
//
// Generate the file name for this frame
// and open the corresponding OpenEXR file.
//
string fileName = fileNameForFrame (_fileNameTemplate, frame);
InputFile in (fileName.c_str());
//
// Verify that this frame has the same data window
// as all other frames. (We do not dynamically resize
// our image buffers.)
//
if (in.header().dataWindow() != _imageBuffers.dataWindow)
THROW (ArgExc,
"Data window of frame " << frame << " "
"differs from data window of "
"frame " << _firstFrame << ".");
//
// Read the OpenEXR file, storing the pixels in
// image buffer i.
//
in.setFrameBuffer (_imageBuffers.frameBuffer (i));
in.readPixels (_imageBuffers.dataWindow.min.y,
_imageBuffers.dataWindow.max.y);
//
// Mark the image buffer as full; the display
// thread can now display this frame.
//
_imageBuffers.frameNumber (i) = frame;
_imageBuffers.fullBuffersSemaphore.post();
//
// Advance to the next frame
//
if (_imageBuffers.forward)
{
if (frame >= _lastFrame)
frame = _firstFrame;
else
frame += 1;
}
else
{
if (frame <= _firstFrame)
frame = _lastFrame;
else
frame -= 1;
}
i = (i + 1) % _imageBuffers.numBuffers();
}
}
catch (const std::exception &exc)
{
//
// If anything goes wrong, print an eror message and exit.
//
cerr << exc.what() << endl;
_imageBuffers.exitSemaphore2.post();
_imageBuffers.fullBuffersSemaphore.post();
return;
}
}

View File

@ -0,0 +1,101 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_FILE_READING_THREAD_H
#define INCLUDED_FILE_READING_THREAD_H
//-----------------------------------------------------------------------------
//
// class FileReadingThread
//
// The file reading thread for the playExr application; reads
// image files and hands the pixels to the display thread.
//
//-----------------------------------------------------------------------------
#include <IlmThread.h>
#include <string>
class ImageBuffers;
class FileReadingThread: ILMTHREAD_NAMESPACE::Thread
{
public:
//----------------------------------------------------------------
// Constructor - stores the arguments passed by the caller,
// and starts the thread by calling run(), below. The caller
// must not destroy the FileReadingThread object while the
// thread is running.
//
// Arguments:
//
// fileNameTemplate The file name for frame f will
// be generated by calling
// fileNameForFrame (fileNameTemplate, f)
//
// firstFrame, lastFrame Range of frame numbers to be loaded.
// after loading the last frame, the
// file reading thread starts over with
// the first frame.
//
// imageBuffers A ring buffer for the pixel data
// loaded from the image files. The
// ring buffer has enough space for
// imageBuffers.numBuffers() images.
// Two semaphores track the number of
// empty and full image buffers.
// The file reading thread fills the
// buffers, and the display thread
// empties them.
//----------------------------------------------------------------
FileReadingThread
(const char fileNameTemplate[],
int firstFrame,
int lastFrame,
ImageBuffers &imageBuffers);
virtual void run();
private:
const std::string _fileNameTemplate;
int _firstFrame;
int _lastFrame;
ImageBuffers & _imageBuffers;
};
#endif

View File

@ -0,0 +1,90 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class ImageBuffers
//
//-----------------------------------------------------------------------------
#include "ImageBuffers.h"
#include <assert.h>
using namespace OPENEXR_IMF_NAMESPACE;
using namespace ILMTHREAD_NAMESPACE;
using namespace IMATH_NAMESPACE;
ImageBuffers::ImageBuffers ():
forward (true),
rgbMode (false),
emptyBuffersSemaphore (NUM_BUFFERS),
fullBuffersSemaphore (0),
exitSemaphore1 (0),
exitSemaphore2 (0)
{
// empty
}
int
ImageBuffers::numBuffers ()
{
return NUM_BUFFERS;
}
OPENEXR_IMF_NAMESPACE::FrameBuffer &
ImageBuffers::frameBuffer (int i)
{
assert (i >= 0 && i < NUM_BUFFERS);
return _frameBuffers[i];
}
char * &
ImageBuffers::pixels (int i, int channel)
{
assert (i >= 0 && i < NUM_BUFFERS && channel >= 0 && channel < 3);
return _pixels[i][channel];
}
int &
ImageBuffers::frameNumber (int i)
{
assert (i >= 0 && i < NUM_BUFFERS);
return _frameNumbers[i];
}

View File

@ -0,0 +1,167 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMAGE_BUFFERS_H
#define INCLUDED_IMAGE_BUFFERS_H
//-----------------------------------------------------------------------------
//
// class ImageBuffers
//
// This class implements a ring buffer for a fixed number frames
// of an image sequence. The playExr program uses this ring buffer
// to transport images from the file reading thread to the display
// thread. For each frame, the ImageBuffer contains:
//
// * buffers for the pixels in the frame's thee channels,
// either R, G, B or Y, RY, BY
//
// * An Imf::FrameBuffer object that describes the layout of
// the pixel buffers. This is used by the file reading thread.
//
// The ImageBuffer also stores the data window of the frames in
// the image sequence, and a flag that indicates if the frames
// contain RGB or luminance/chroma (Y, RY, BY) data.
//
// Two semaphores indicate which frames in the ring buffer are
// empty and how many are full. The file reading thread fills
// frames and the display thread empties them.
//
// The file reading thread executes a loop that looks like this:
//
// int i = 0;
//
// while (true)
// {
// emptyBuffersSemaphore.wait();
// read next frame from a file, store it in buffer i;
// fullBuffersSemaphore.post();
// i = (i + 1) % numBuffers();
// }
//
// The corresponding loop in the display thread looks like this:
//
// int i = 0;
//
// while (true)
// {
// fullBuffersSemaphore.wait();
// display the image in buffer i;
// emptyBuffersSemaphore.post();
// i = (i + 1) % numBuffers();
// }
//
//-----------------------------------------------------------------------------
#include <ImfFrameBuffer.h>
#include <ImathBox.h>
#include <IlmThreadSemaphore.h>
class ImageBuffers
{
public:
ImageBuffers ();
//----------------------------------------------------------
// Flag that indicates if we are playing forward or backward
//----------------------------------------------------------
bool forward;
//-----------------------------------------------------------------------
// Flag that indicates if the frames contain RGB or luminance/chroma data
//-----------------------------------------------------------------------
bool rgbMode;
//------------------------------------
// Number of frames in the ring buffer
//------------------------------------
int numBuffers ();
//------------------------------------------------
// Access to the Imf::FrameBuffers
// i must be in the range from 0 to numBuffers()-1
//------------------------------------------------
OPENEXR_IMF_NAMESPACE::FrameBuffer & frameBuffer (int i);
//------------------------------------------------
// Access to the pixel buffers
// i must be in the range from 0 to numBuffers()-1
// channel must be in the range from 0 to 2
//------------------------------------------------
char * & pixels (int i, int channel);
//-----------------------------------------------------------
// Access to frame numbers that correspond the pixel buffers.
// i must be in the range from 0 to numBuffers()-1
//-----------------------------------------------------------
int & frameNumber (int i);
//---------------------------
// Data window for all frames
//---------------------------
IMATH_NAMESPACE::Box2i dataWindow;
//-----------
// Semaphores
//-----------
ILMTHREAD_NAMESPACE::Semaphore emptyBuffersSemaphore;
ILMTHREAD_NAMESPACE::Semaphore fullBuffersSemaphore;
ILMTHREAD_NAMESPACE::Semaphore exitSemaphore1;
ILMTHREAD_NAMESPACE::Semaphore exitSemaphore2;
private:
static const int NUM_BUFFERS = 3;
OPENEXR_IMF_NAMESPACE::FrameBuffer _frameBuffers[NUM_BUFFERS];
char * _pixels[NUM_BUFFERS][3];
int _frameNumbers[NUM_BUFFERS];
};
#endif

View File

@ -0,0 +1,52 @@
## Process this file with automake to produce Makefile.in
if HAVE_CG
bin_PROGRAMS = playexr
playexr_CPPFLAGS = $(AM_CPPFLAGS)
INCLUDES = \
@OPENEXR_CTL_CXXFLAGS@ \
@GL_CXXFLAGS@ \
@CG_CXXFLAGS@
LDADD = \
@OPENEXR_CTL_LDFLAGS@ \
@CG_LDFLAGS@ \
@OPENEXR_CTL_LIBS@
playexr_SOURCES = \
main.cpp \
playExr.cpp \
playExr.h \
fileNameForFrame.cpp \
fileNameForFrame.h \
FileReadingThread.cpp \
FileReadingThread.h \
ImageBuffers.cpp \
ImageBuffers.h \
Timer.cpp \
Timer.h \
ctlToLut.cpp \
ctlToLut.h \
osDependent.cpp \
osDependent.h
endif
noinst_HEADERS = \
playExr.h \
fileNameForFrame.h \
FileReadingThread.h \
ImageBuffers.h \
Timer.h \
ctlToLut.cpp \
ctlToLut.h \
osDependent.h
EXTRA_DIST = \
$(playexr_SOURCES)

View File

@ -0,0 +1,182 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Timing control for the display thread of the playExr prgram
//
//----------------------------------------------------------------------------
#include "Timer.h"
#include <time.h>
#ifdef _WIN32
#include <windows.h>
static int
gettimeofday (struct timeval *tv, void *tz)
{
union
{
ULONGLONG ns100; // time since 1 Jan 1601 in 100ns units
FILETIME ft;
} now;
GetSystemTimeAsFileTime (&now.ft);
tv->tv_usec = long ((now.ns100 / 10LL) % 1000000LL);
tv->tv_sec = long ((now.ns100 - 116444736000000000LL) / 10000000LL);
return 0;
}
#endif
Timer::Timer ():
playState (RUNNING),
_spf (1 / 24.0),
_timingError (0),
_framesSinceLastFpsFrame (0),
_actualFrameRate (0)
{
gettimeofday (&_lastFrameTime, 0);
_lastFpsFrameTime = _lastFrameTime;
}
void
Timer::waitUntilNextFrameIsDue ()
{
if (playState != RUNNING)
{
//
// If we are not running, reset all timing state
// variables and return without waiting.
//
gettimeofday (&_lastFrameTime, 0);
_timingError = 0;
_lastFpsFrameTime = _lastFrameTime;
_framesSinceLastFpsFrame = 0;
return;
}
//
// If less than _spf seconds have passed since the last frame
// was displayed, sleep until exactly _spf seconds have gone by.
//
timeval now;
gettimeofday (&now, 0);
float timeSinceLastFrame = now.tv_sec - _lastFrameTime.tv_sec +
(now.tv_usec - _lastFrameTime.tv_usec) * 1e-6f;
float timeToSleep = _spf - timeSinceLastFrame - _timingError;
#ifdef _WIN32
if (timeToSleep > 0)
Sleep (int (timeToSleep * 1000.0f));
#else
if (timeToSleep > 0)
{
timespec ts;
ts.tv_sec = (time_t) timeToSleep;
ts.tv_nsec = (long) ((timeToSleep - ts.tv_sec) * 1e9f);
nanosleep (&ts, 0);
}
#endif
//
// If we slept, it is possible that we woke up a little too early
// or a little too late. Keep track of the difference between
// now and the exact time when we wanted to wake up; next time
// we'll try sleep that much longer or shorter. This should
// keep our average frame rate close to one fame every _spf seconds.
//
gettimeofday (&now, 0);
timeSinceLastFrame = now.tv_sec - _lastFrameTime.tv_sec +
(now.tv_usec - _lastFrameTime.tv_usec) * 1e-6f;
_timingError += timeSinceLastFrame - _spf;
if (_timingError < -2 * _spf)
_timingError = -2 * _spf;
if (_timingError > 2 * _spf)
_timingError = 2 * _spf;
_lastFrameTime = now;
//
// Calculate our actual frame rate, averaged over several frames.
//
if (_framesSinceLastFpsFrame >= 24)
{
float t = now.tv_sec - _lastFpsFrameTime.tv_sec +
(now.tv_usec - _lastFpsFrameTime.tv_usec) * 1e-6f;
if (t > 0)
_actualFrameRate = _framesSinceLastFpsFrame / t;
_framesSinceLastFpsFrame = 0;
}
if (_framesSinceLastFpsFrame == 0)
_lastFpsFrameTime = now;
_framesSinceLastFpsFrame += 1;
}
void
Timer::setDesiredFrameRate (float fps)
{
_spf = 1 / fps;
}
float
Timer::actualFrameRate ()
{
return _actualFrameRate;
}

View File

@ -0,0 +1,115 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_TIMER_H
#define INCLUDED_TIMER_H
//----------------------------------------------------------------------------
//
// Timing control for the display thread of the playExr prgram
//
//----------------------------------------------------------------------------
#ifdef _WIN32
#include <windows.h>
#else
#include <sys/time.h>
#endif
enum PlayState
{
PREPARE_TO_RUN,
RUNNING,
PREPARE_TO_PAUSE,
PAUSE,
};
class Timer
{
public:
//------------
// Constructor
//------------
Timer ();
//--------------------------------------------------------
// Timing control to maintain the desired frame rate:
// the redrawWindow() function in the display thread calls
// waitUntilNextFrameIsDue() before displaying each frame.
//
// If playState == RUNNING, then waitUntilNextFrameIsDue()
// sleeps until the apropriate amount of time has elapsed
// since the last call to waitUntilNextFrameIsDue().
// If playState != RUNNING, then waitUntilNextFrameIsDue()
// returns immediately.
//--------------------------------------------------------
void waitUntilNextFrameIsDue ();
//-------------------------------------------------
// Set and get the frame rate, in frames per second
//-------------------------------------------------
void setDesiredFrameRate (float fps);
float actualFrameRate ();
//-------------------
// Current play state
//-------------------
PlayState playState;
private:
float _spf; // desired frame rate,
// in seconds per frame
timeval _lastFrameTime; // time when we displayed the
// last frame
float _timingError; // cumulative timing error
timeval _lastFpsFrameTime; // state to keep track of the
int _framesSinceLastFpsFrame; // actual frame trate, averaged
float _actualFrameRate; // over several frames
};
#endif

View File

@ -0,0 +1,465 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// Run a set of CTL transforms to generate a color lookup table.
//
//-----------------------------------------------------------------------------
#include <stdio.h>
#include "ctlToLut.h"
#if HAVE_CTL_INTERPRETER
#include <ImfCtlApplyTransforms.h>
#include <CtlSimdInterpreter.h>
#include <ImfStandardAttributes.h>
#include <ImfHeader.h>
#include <stdlib.h>
#include <ImfFrameBuffer.h>
#include <cassert>
#include <iostream>
using namespace std;
using namespace Ctl;
using namespace OPENEXR_IMF_NAMESPACE;
using namespace IMATH_NAMESPACE;
#else
#include <ImfStandardAttributes.h>
#include <ImfHeader.h>
#include <stdlib.h>
#include <cassert>
#include <iostream>
using namespace std;
using namespace OPENEXR_IMF_NAMESPACE;
using namespace IMATH_NAMESPACE;
#endif
#define WARNING(message) (cerr << "Warning: " << message << endl)
float
displayVideoGamma ()
{
//
// Get the display's video gamma from an environment variable.
// If this fails, use a default value (1/2.2).
//
const char gammaEnv[] = "EXR_DISPLAY_VIDEO_GAMMA";
float g = 2.2f;
if (const char *gamma = getenv (gammaEnv))
{
float tmp;
int n = sscanf (gamma, " %f", &tmp);
if (n != 1)
WARNING ("Cannot parse environment variable " << gammaEnv << "; "
"using default value (" << g << ").");
else if (tmp < 1.f)
WARNING ("Display video gamma, specified in environment "
"variable " << gammaEnv << " is out of range; "
"using default value (" << g << ").");
else
g = tmp;
}
else
{
WARNING ("Environment variable " << gammaEnv << " is not set; "
"using default value (" << g << ").");
}
return 1.f / g;
}
#if HAVE_CTL_INTERPRETER
namespace {
void
initializeEnvHeader (Header &envHeader)
{
//
// Initialize the "environment header" for the CTL
// transforms by adding displayChromaticities,
// displayWhiteLuminance and displaySurroundLuminance
// attributes.
//
//
// Get the chromaticities of the display's primaries and
// white point from an environment variable. If this fails,
// assume chromaticities according to Rec. ITU-R BT.709.
//
static const char chromaticitiesEnv[] = "CTL_DISPLAY_CHROMATICITIES";
Chromaticities c; // default-initialized according to Rec. 709
if (const char *chromaticities = getenv (chromaticitiesEnv))
{
Chromaticities tmp;
int n = sscanf (chromaticities,
" red %f %f green %f %f blue %f %f white %f %f",
&tmp.red.x, &tmp.red.y,
&tmp.green.x, &tmp.green.y,
&tmp.blue.x, &tmp.blue.y,
&tmp.white.x, &tmp.white.y);
if (n == 8)
c = tmp;
else
WARNING ("Cannot parse environment variable " <<
chromaticitiesEnv << "; using default value "
"(chromaticities according to Rec. ITU-R BT.709).");
}
else
{
WARNING ("Environment variable " << chromaticitiesEnv << " is "
"not set; using default value (chromaticities according "
"to Rec. ITU-R BT.709).");
}
envHeader.insert ("displayChromaticities", ChromaticitiesAttribute (c));
//
// Get the display's white luminance from an environment variable.
// If this fails, assume 120 candelas per square meter.
// (Screen aim luminance according to SMPTE RP 166.)
//
static const char whiteLuminanceEnv[] = "CTL_DISPLAY_WHITE_LUMINANCE";
static const float whiteLuminanceDefault = 120.0;
float wl = whiteLuminanceDefault;
if (const char *whiteLuminance = getenv (whiteLuminanceEnv))
{
int n = sscanf (whiteLuminance, " %f", &wl);
if (n != 1)
WARNING ("Cannot parse environment variable " <<
whiteLuminanceEnv << "; using default value "
"(" << wl << " candelas per square meter).");
}
else
{
WARNING ("Environment variable " << whiteLuminanceEnv << " is "
"is not set; using default value (" << wl << " candelas "
"per square meter).");
}
envHeader.insert ("displayWhiteLuminance", FloatAttribute (wl));
//
// Get the display's surround luminance from an environment variable.
// If this fails, assume 10% of the display's white luminance.
// (Recommended setup according to SMPTE RP 166.)
//
static const char surroundLuminanceEnv[] = "CTL_DISPLAY_SURROUND_LUMINANCE";
float sl = wl * 0.1f;
if (const char *surroundLuminance = getenv (surroundLuminanceEnv))
{
int n = sscanf (surroundLuminance, " %f", &sl);
if (n != 1)
WARNING ("Cannot parse environment variable " <<
surroundLuminanceEnv << "; using default value "
"(" << sl << " candelas per square meter).");
}
else
{
WARNING ("Environment variable " << surroundLuminanceEnv << " is "
"is not set; using default value (" << sl << " candelas "
"per square meter).");
}
envHeader.insert ("displaySurroundLuminance", FloatAttribute (sl));
}
string
displayTransformName ()
{
//
// Get the name of the display transform from an environment
// variable. If this fails, use a default name.
//
static const char displayTransformEnv[] = "CTL_DISPLAY_TRANSFORM";
static const char displayTransformDefault[] = "transform_display_video";
const char *displayTransform = getenv (displayTransformEnv);
if (!displayTransform)
{
displayTransform = displayTransformDefault;
WARNING ("Environment variable " << displayTransformEnv << " "
"is not set; using default value "
"(\"" << displayTransform << "\").");
}
return displayTransform;
}
} // namespace
void
ctlToLut (vector<string> transformNames,
Header inHeader,
size_t lutSize,
const half pixelValues[/*lutSize*/],
half lut[/*lutSize*/])
{
//
// If we do not have an explicit set of transform names
// then find suitable look modification, rendering and
// display transforms.
//
if (transformNames.empty())
{
if (hasLookModTransform (inHeader))
transformNames.push_back (lookModTransform (inHeader));
if (hasRenderingTransform (inHeader))
transformNames.push_back (renderingTransform (inHeader));
else
transformNames.push_back ("transform_RRT");
transformNames.push_back (displayTransformName());
}
//
// Initialize an input and an environment header:
// Make sure that the headers contain information about the primaries
// and the white point of the image files an the display, and about
// the display's white luminance and surround luminance.
//
Header envHeader;
Header outHeader;
if (!hasChromaticities (inHeader))
addChromaticities (inHeader, Chromaticities());
if (!hasAdoptedNeutral (inHeader))
addAdoptedNeutral (inHeader, chromaticities(inHeader).white);
initializeEnvHeader (envHeader);
//
// Set up input and output FrameBuffer objects for the CTL transforms.
//
assert (lutSize % 4 == 0);
FrameBuffer inFb;
inFb.insert ("R",
Slice (HALF, // type
(char *)pixelValues, // base
4 * sizeof (half), // xStride
0)); // yStride
inFb.insert ("G",
Slice (HALF, // type
(char *)(pixelValues + 1), // base
4 * sizeof (half), // xStride
0)); // yStride
inFb.insert ("B",
Slice (HALF, // type
(char *)(pixelValues + 2), // base
4 * sizeof (half), // xStride
0)); // yStride
FrameBuffer outFb;
outFb.insert ("R_display",
Slice (HALF, // type
(char *)lut, // base
4 * sizeof (half), // xStride
0)); // yStride
outFb.insert ("G_display",
Slice (HALF, // type
(char *)(lut + 1), // base
4 * sizeof (half), // xStride
0)); // yStride
outFb.insert ("B_display",
Slice (HALF, // type
(char *)(lut + 2), // base
4 * sizeof (half), // xStride
0)); // yStride
//
// Run the CTL transforms.
//
SimdInterpreter interpreter;
#ifdef CTL_MODULE_BASE_PATH
//
// The configuration scripts has defined a default
// location for CTL modules. Include this location
// in the CTL module search path.
//
vector<string> paths = interpreter.modulePaths();
paths.push_back (CTL_MODULE_BASE_PATH);
interpreter.setModulePaths (paths);
#endif
ImfCtl::applyTransforms (interpreter,
transformNames,
Box2i (V2i (0, 0), V2i (lutSize / 4 - 1, 0)),
envHeader,
inHeader,
inFb,
outHeader,
outFb);
}
#else
#include <ImfStandardAttributes.h>
#include <ImfHeader.h>
#include <cassert>
#include <iostream>
using namespace std;
using namespace OPENEXR_IMF_NAMESPACE;
using namespace IMATH_NAMESPACE;
#define WARNING(message) (cerr << "Warning: " << message << endl)
void
ctlToLut (vector<string> transformNames,
Header inHeader,
size_t lutSize,
const half pixelValues[/*lutSize*/],
half lut[/*lutSize*/])
{
//
// This program has been compiled without CTL support.
//
// Our fallback solution is to build a lookup table that
// performs a coordinate transform from the primaries and
// white point of the input files to the primaries and
// white point of the display.
//
//
// Get the input file chromaticities
//
Chromaticities fileChroma;
if (hasChromaticities (inHeader))
fileChroma = chromaticities (inHeader);
//
// Get the display chromaticities
//
static const char chromaticitiesEnv[] = "CTL_DISPLAY_CHROMATICITIES";
Chromaticities displayChroma;
if (const char *chromaticities = getenv (chromaticitiesEnv))
{
Chromaticities tmp;
int n = sscanf (chromaticities,
" red %f %f green %f %f blue %f %f white %f %f",
&tmp.red.x, &tmp.red.y,
&tmp.green.x, &tmp.green.y,
&tmp.blue.x, &tmp.blue.y,
&tmp.white.x, &tmp.white.y);
if (n == 8)
displayChroma = tmp;
else
WARNING ("Cannot parse environment variable " <<
chromaticitiesEnv << "; using default value "
"(chromaticities according to Rec. ITU-R BT.709).");
}
else
{
WARNING ("Environment variable " << chromaticitiesEnv << " is "
"not set; using default value (chromaticities according "
"to Rec. ITU-R BT.709).");
}
//
// Do the coordinate transform
//
M44f M = RGBtoXYZ (fileChroma, 1) * XYZtoRGB (displayChroma, 1);
assert (lutSize % 4 == 0);
for (int i = 0; i < lutSize; i += 4)
{
V3f rgb (pixelValues[i], pixelValues[i + 1], pixelValues[i + 2]);
rgb = rgb * M;
lut[i + 0] = rgb[0];
lut[i + 1] = rgb[1];
lut[i + 2] = rgb[2];
lut[i + 3] = 0;
}
}
#endif

View File

@ -0,0 +1,107 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_CTL_TO_LUT_H
#define INCLUDED_CTL_TO_LUT_H
//-----------------------------------------------------------------------------
//
// Run a set of CTL transforms to generate a color lookup table.
//
// Function ctlToLut() applies a series of CTL transforms to a
// set of input pixel values, pixelValues, producing a color lookup
// table, lut. A Cg shader in the display thread of the playexr
// program will use this lookup table to approximate the effect
// of applying the CTL transforms directly to the displayed images.
//
// Parameters:
//
// transformNames A list of the names of the CTL transforms that will
// be applied to the input pixel values. If this list
// is empty, ctlToLut() looks for a rendering transform
// and a display transform:
//
// If inHeader contains a string attribute called
// "renderingTransform" then the value of this attribute
// is the name of the rendering transform.
// If inHeader contains no such attribute, then the
// name of the rendering transform is "transform_RRT".
//
// If the environment variable CTL_DISPLAY_TRANSFORM
// is set, the value of the environment variable is
// the name of the display transform.
// If the environment variable is not set, then the name
// of the display transform is "transform_display_video".
//
// inHeader The header of the first frame of the image sequence
// displayed by playexr. The attributes in the header
// can be read by the CTL transforms.
//
// lutSize Number of elements in the pixelValues and lut arrays.
//
// pixelValues,
// lut Input and output pixel data arrays. Four channels
// R, G, B and A are interleaved: RGBARGBARGBA...
// The A channel is only for padding; it cannot be
// accessed by the CTL transforms.
//
//
// Function displayVideoGamma() returns 1/g, where g is the display's
// video gamma. The value of g is read from the environment variable
// EXR_DISPLAY_VIDEO_GAMMA. If the environment variable is not set,
// then displayVideoGamma() returns 1 / 2.2.
//
//-----------------------------------------------------------------------------
#include <ImfHeader.h>
#include <string>
#include <vector>
#include <half.h>
#include <cstdlib>
void
ctlToLut (std::vector<std::string> transformNames,
OPENEXR_IMF_NAMESPACE::Header inHeader,
size_t lutSize,
const half pixelValues[/*lutSize*/],
half lut[/*lutSize*/]);
float
displayVideoGamma ();
#endif

View File

@ -0,0 +1,72 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// function fileNameForFrame
//
//-----------------------------------------------------------------------------
#include "fileNameForFrame.h"
#include <sstream>
using namespace std;
string
fileNameForFrame (const string &fileNameTemplate, int frame)
{
//
// Generate the file name for the specified frame by replacing
// the first '%' character in the file name template with the
// frame number.
//
string::size_type i = fileNameTemplate.find ('%');
if (i != string::npos)
{
stringstream ss;
ss << fileNameTemplate.substr (0, i) <<
frame <<
fileNameTemplate.substr (i + 1);
return ss.str();
}
else
{
return fileNameTemplate;
}
}

View File

@ -0,0 +1,55 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_FILE_NAME_FOR_FRAME_H
#define INCLUDED_FILE_NAME_FOR_FRAME_H
//-----------------------------------------------------------------------------
//
// function fileNameForFrame
//
// Generate the file name for a given frame by replacing
// the first '%' character in a file name template with the
// frame number.
//
//-----------------------------------------------------------------------------
#include <string>
std::string
fileNameForFrame (const std::string &fileNameTemplate, int frame);
#endif

View File

@ -0,0 +1,375 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * 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.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// playexr -- a program that plays back an
// OpenEXR image sequence directly from disk.
//
//-----------------------------------------------------------------------------
#include "playExr.h"
#include "osDependent.h"
#include <IlmThread.h>
#include <iostream>
#include <exception>
#include <vector>
#include <string>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <cstring>
using namespace std;
namespace {
void
usageMessage (const char argv0[], bool verbose = false)
{
cerr << "usage: " << argv0 << " "
"[options] fileName [firstFrame lastFrame]" << endl;
if (verbose)
{
cerr << "\n"
"Plays back a sequence of OpenEXR files. All files must\n"
"have the same data window and the same set of channels.\n"
"The names of the files are constructed by substituting\n"
"the first '%' in fileName with firstFrame, firstFrame+1,\n"
"firstFrame+2, ... lastFrame. For example,\n"
"\n"
" " << argv0 << " image.%.exr 1 100\n"
"\n"
"plays back image.1.exr, image.2.exr ... image.100.exr.\n"
"\n"
"Options:\n"
"\n"
"-t n read the images using n parallel threads\n"
"\n"
"-f n images will be played back at a rate of n frames\n"
" per second (assuming that reading and displaying\n"
" an individual image file takes no more than 1/n\n"
" seconds).\n"
"\n"
"-S n images will be displayed at n times their original\n"
" width and height. n must be in the range from 0.1\n"
" to 2.0.\n"
"\n"
#if HAVE_CTL_INTERPRETER
"-C s CTL transform s is applied to each image before it\n"
" is displayed. Option -C can be specified multiple\n"
" times to apply a series of transforms to each image.\n"
" The transforms are applied in the order in which\n"
" they appear on the command line.\n"
"\n"
"-i On machines where the graphics hardware does not\n"
" directly support interpolation between texture map\n"
" pixels images with smooth color gradients will\n"
" exhibit contouring artifacts. Option -i selects\n"
" software-based texture pixel interpolation. This\n"
" avoids contouring but may slow down image playback.\n"
"\n"
#endif
"-h prints this message\n"
"\n"
#if HAVE_CTL_INTERPRETER
"CTL transforms:\n"
"\n"
" If one or more CTL transforms are specified on\n"
" the command line (using the -C flag), then those\n"
" transforms are applied to the images.\n"
" If no CTL transforms are specified on the command\n"
" line then an optional look modification transform\n"
" is applied, followed by a rendering transform and\n"
" a display transform.\n"
" The name of the look modification transform is\n"
" taken from the lookModTransform attribute in the\n"
" header of the first frame of the image sequence.\n"
" If the header contains no such attribute, then no\n"
" look modification transform is applied. The name\n"
" of the rendering transform is taken from the\n"
" renderingTransform attribute in the header of the\n"
" first frame of the image sequence. If the header\n"
" contains no such attribute, then the name of the\n"
" rendering transform is \"transform_RRT.\" The\n"
" name of the display transform is taken from the\n"
" environment variable CTL_DISPLAY_TRANSFORM. If this\n"
" environment variable is not set, then the name of\n"
" the display transform is \"transform_display_video.\"\n"
" The files that contain the CTL code for the\n"
" transforms are located using the CTL_MODULE_PATH\n"
" environment variable.\n"
"\n"
#endif
"Playback frame rate:\n"
"\n"
" If the frame rate is not specified on the command\n"
" line (using the -f flag), then the frame rate is\n"
" determined by the framesPerSecond attribute in the\n"
" header of the first frame of the image sequence.\n"
" If the header contains no framesPerSecond attribute\n"
" then the frame rate is set to 24 frames per second.\n"
"\n"
"Keyboard commands:\n"
"\n"
" L or P play forward / pause\n"
" H play backward / pause\n"
" K step one frame forward\n"
" J step one frame backward\n"
" > or . increase exposure\n"
" < or , decrease exposure\n"
#if HAVE_CTL_INTERPRETER
" C CTL transforms on/off\n"
#endif
" O text overlay on/off\n"
" F full-screen mode on/off\n"
" Q or ESC quit\n"
"\n";
cerr << endl;
}
exit (1);
}
int exitStatus = 0;
void
quickexit ()
{
//
// Hack to avoid crashes when someone presses the close or 'X'
// button in the title bar of our window. Something GLUT does
// while shutting down the program does not play well with
// multiple threads. Bypassing GLUT's orderly shutdown by
// calling _exit immediately avoids crashes.
//
_exit (exitStatus);
}
} // namespace
int
main(int argc, char **argv)
{
glutInit (&argc, argv);
const char *fileNameTemplate = 0;
int firstFrame = 1;
int lastFrame = 1;
int numThreads = 0;
float fps = -1;
float xyScale = 1;
vector<string> transformNames;
bool useHwTexInterpolation = true;
//
// Parse the command line.
//
if (argc < 2)
usageMessage (argv[0], true);
int i = 1;
int j = 0;
while (i < argc)
{
if (!strcmp (argv[i], "-t"))
{
//
// Set number of threads
//
if (i > argc - 2)
usageMessage (argv[0]);
numThreads = strtol (argv[i + 1], 0, 0);
if (numThreads < 0)
{
cerr << "Number of threads cannot be negative." << endl;
return 1;
}
i += 2;
}
else if (!strcmp (argv[i], "-f"))
{
//
// Set frame rate
//
if (i > argc - 2)
usageMessage (argv[0]);
fps = strtod (argv[i + 1], 0);
if (fps < 1 || fps > 1000)
{
cerr << "Playback speed must be between "
"1 and 1000 frames per second." << endl;
return 1;
}
i += 2;
}
else if (!strcmp (argv[i], "-S"))
{
//
// Set image scale factor
//
if (i > argc - 2)
usageMessage (argv[0]);
xyScale = strtod (argv[i + 1], 0);
if (xyScale < 0.1 || xyScale > 2.0)
{
cerr << "Scale factor must be between 0.1 and 2.0." << endl;
return 1;
}
i += 2;
}
else if (!strcmp (argv[i], "-C"))
{
//
// Apply a CTL transform
//
if (i > argc - 2)
usageMessage (argv[0]);
transformNames.push_back (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-i"))
{
//
// Use software-based texture map interpolation
//
useHwTexInterpolation = false;
i += 1;
}
else if (!strcmp (argv[i], "-h"))
{
//
// Print help message
//
usageMessage (argv[0], true);
}
else
{
//
// Image file name or frame number
//
switch (j)
{
case 0:
fileNameTemplate = argv[i];
break;
case 1:
firstFrame = strtol (argv[i], 0, 0);
break;
case 2:
lastFrame = strtol (argv[i], 0, 0);
break;
default:
break;
}
i += 1;
j += 1;
}
}
if (j != 1 && j != 3)
usageMessage (argv[0]);
if (firstFrame > lastFrame)
{
cerr << "Frame number of first frame is greater than "
"frame number of last frame." << endl;
return 1;
}
//
// Make sure that we have threading support.
//
if (!ILMTHREAD_NAMESPACE::supportsThreads())
{
cerr << "This program requires multi-threading support.\n" << endl;
return 1;
}
//
// Play the image sequence.
//
atexit (quickexit);
try
{
playExr (fileNameTemplate,
firstFrame,
lastFrame,
numThreads,
fps,
xyScale,
transformNames,
useHwTexInterpolation);
}
catch (const exception &e)
{
cerr << e.what() << endl;
exitStatus = 1;
}
return exitStatus;
}

View File

@ -0,0 +1,92 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * 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.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// OpenGL related code and definitions
// that depend on the operating system.
//
//----------------------------------------------------------------------------
#include "osDependent.h"
#include <stdlib.h>
#include <iostream>
using namespace std;
void
initAndCheckGlExtensions ()
{
#ifdef PLAYEXR_USE_APPLE_FLOAT_PIXELS
if (!glutExtensionSupported ("GL_APPLE_float_pixels"))
{
cerr << "This program requires OpenGL support for "
"16-bit floating-point textures." << endl;
exit (1);
}
#else
if (!glutExtensionSupported ("GL_ARB_texture_float") ||
!glutExtensionSupported ("GL_ARB_half_float_pixel"))
{
cerr << "This program requires OpenGL support for "
"16-bit floating-point textures." << endl;
exit (1);
}
#endif
if (!glutExtensionSupported ("GL_ARB_fragment_shader"))
{
cerr << "This program requires OpenGL support for "
"fragment shaders and the Cg shading language." << endl;
exit (1);
}
#ifdef WIN32
GLenum err = glewInit();
if (GLEW_OK != err)
{
cerr << "Cannot initialize "
"glew: " << glewGetErrorString (err) << endl;
exit (1);
}
#endif
}

View File

@ -0,0 +1,86 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2007, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_OS_DEPENDENT_H
#define INCLUDED_OS_DEPENDENT_H
//----------------------------------------------------------------------------
//
// OpenGL related code and definitions
// that depend on the operating system.
//
//----------------------------------------------------------------------------
#ifdef WIN32
#include <GL/glew.h>
#else
#define GL_GLEXT_PROTOTYPES
#endif
#if defined __APPLE__
#include <GLUT/glut.h>
#include <OpenGL/gl.h>
#include <Cg/cgGL.h>
#ifndef GL_HALF_FLOAT_ARB
#define PLAYEXR_USE_APPLE_FLOAT_PIXELS
#endif
#ifndef GL_LUMINANCE16F_ARB
#define GL_LUMINANCE16F_ARB GL_LUMINANCE_FLOAT16_APPLE
#endif
#ifndef GL_RGBA16F_ARB
#define GL_RGBA16F_ARB GL_RGBA_FLOAT16_APPLE
#endif
#ifndef GL_HALF_FLOAT_ARB
#define GL_HALF_FLOAT_ARB GL_HALF_APPLE
#endif
#else
#include <GL/glut.h>
#include <GL/gl.h>
#include <Cg/cgGL.h>
#endif
void initAndCheckGlExtensions ();
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_PLAY_EXR_H
#define INCLUDED_PLAY_EXR_H
//----------------------------------------------------------------------------
//
// Play an OpenEXR image sequence.
//
//----------------------------------------------------------------------------
#include <vector>
#include <string>
void
playExr (const char fileNameTemplate[],
int firstFrame,
int lastFrame,
int numThreads,
float fps,
float xyScale,
const std::vector<std::string> &transformNames,
bool useHwTexInterpolation);
#endif