|
Packit Service |
6754ca |
///////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Copyright (c) 2009-2014 DreamWorks Animation LLC.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// All rights reserved.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Redistribution and use in source and binary forms, with or without
|
|
Packit Service |
6754ca |
// modification, are permitted provided that the following conditions are
|
|
Packit Service |
6754ca |
// met:
|
|
Packit Service |
6754ca |
// * Redistributions of source code must retain the above copyright
|
|
Packit Service |
6754ca |
// notice, this list of conditions and the following disclaimer.
|
|
Packit Service |
6754ca |
// * Redistributions in binary form must reproduce the above
|
|
Packit Service |
6754ca |
// copyright notice, this list of conditions and the following disclaimer
|
|
Packit Service |
6754ca |
// in the documentation and/or other materials provided with the
|
|
Packit Service |
6754ca |
// distribution.
|
|
Packit Service |
6754ca |
// * Neither the name of DreamWorks Animation nor the names of
|
|
Packit Service |
6754ca |
// its contributors may be used to endorse or promote products derived
|
|
Packit Service |
6754ca |
// from this software without specific prior written permission.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit Service |
6754ca |
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit Service |
6754ca |
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit Service |
6754ca |
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit Service |
6754ca |
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit Service |
6754ca |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit Service |
6754ca |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit Service |
6754ca |
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit Service |
6754ca |
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit Service |
6754ca |
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit Service |
6754ca |
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
///////////////////////////////////////////////////////////////////////////
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// A program to generate various acceleration lookup tables
|
|
Packit Service |
6754ca |
// for Imf::DwaCompressor
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
#include <cstddef>
|
|
Packit Service |
6754ca |
#include <stdio.h>
|
|
Packit Service |
6754ca |
#include <stdlib.h>
|
|
Packit Service |
6754ca |
#include <math.h>
|
|
Packit Service |
6754ca |
#include <vector>
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
#include <OpenEXRConfig.h>
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
#ifdef OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN
|
|
Packit Service |
6754ca |
#include <unistd.h>
|
|
Packit Service |
6754ca |
#endif
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
#include <half.h>
|
|
Packit Service |
6754ca |
#include <IlmThread.h>
|
|
Packit Service |
6754ca |
#include <IlmThreadSemaphore.h>
|
|
Packit Service |
6754ca |
#include <ImfIO.h>
|
|
Packit Service |
6754ca |
#include <ImfXdr.h>
|
|
Packit Service |
6754ca |
#include "ImfNamespace.h"
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
using namespace OPENEXR_IMF_NAMESPACE;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
namespace {
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
class LutHeaderWorker
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
public:
|
|
Packit Service |
6754ca |
class Runner : public IlmThread::Thread
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
public:
|
|
Packit Service |
6754ca |
Runner(LutHeaderWorker &worker, bool output):
|
|
Packit Service |
6754ca |
IlmThread::Thread(),
|
|
Packit Service |
6754ca |
_worker(worker),
|
|
Packit Service |
6754ca |
_output(output)
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
start();
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
virtual ~Runner()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
_semaphore.wait();
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
virtual void run()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
_semaphore.post();
|
|
Packit Service |
6754ca |
_worker.run(_output);
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
private:
|
|
Packit Service |
6754ca |
LutHeaderWorker &_worker;
|
|
Packit Service |
6754ca |
bool _output;
|
|
Packit Service |
6754ca |
IlmThread::Semaphore _semaphore;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
}; // class LutHeaderWorker::Runner
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
LutHeaderWorker(size_t startValue,
|
|
Packit Service |
6754ca |
size_t endValue):
|
|
Packit Service |
6754ca |
_lastCandidateCount(0),
|
|
Packit Service |
6754ca |
_startValue(startValue),
|
|
Packit Service |
6754ca |
_endValue(endValue),
|
|
Packit Service |
6754ca |
_numElements(0),
|
|
Packit Service |
6754ca |
_offset(new size_t[numValues()]),
|
|
Packit Service |
6754ca |
_elements(new unsigned short[1024*1024*2])
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
~LutHeaderWorker()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
delete[] _offset;
|
|
Packit Service |
6754ca |
delete[] _elements;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
size_t lastCandidateCount() const
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
return _lastCandidateCount;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
size_t numValues() const
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
return _endValue - _startValue;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
size_t numElements() const
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
return _numElements;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
const size_t* offset() const
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
return _offset;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
const unsigned short* elements() const
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
return _elements;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
void run(bool outputProgress)
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
half candidate[16];
|
|
Packit Service |
6754ca |
int candidateCount = 0;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
for (size_t input=_startValue; input<_endValue; ++input) {
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (outputProgress) {
|
|
Packit Service |
6754ca |
#ifdef __GNUC__
|
|
Packit Service |
6754ca |
if (input % 100 == 0) {
|
|
Packit Service |
6754ca |
fprintf(stderr,
|
|
Packit Service |
6754ca |
" Building acceleration for DwaCompressor, %.2f %% %c",
|
|
Packit Service |
6754ca |
100.*(float)input/(float)numValues(), 13);
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
#else
|
|
Packit Service |
6754ca |
if (input % 1000 == 0) {
|
|
Packit Service |
6754ca |
fprintf(stderr,
|
|
Packit Service |
6754ca |
" Building acceleration for DwaCompressor, %.2f %%\n",
|
|
Packit Service |
6754ca |
100.*(float)input/(float)numValues());
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
#endif
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
int numSetBits = countSetBits(input);
|
|
Packit Service |
6754ca |
half inputHalf, closestHalf;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
inputHalf.setBits(input);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
_offset[input - _startValue] = _numElements;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
// Gather candidates
|
|
Packit Service |
6754ca |
candidateCount = 0;
|
|
Packit Service |
6754ca |
for (int targetNumSetBits=numSetBits-1; targetNumSetBits>=0;
|
|
Packit Service |
6754ca |
--targetNumSetBits) {
|
|
Packit Service |
6754ca |
bool valueFound = false;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
for (int i=0; i<65536; ++i) {
|
|
Packit Service |
6754ca |
if (countSetBits(i) != targetNumSetBits) continue;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (!valueFound) {
|
|
Packit Service |
6754ca |
closestHalf.setBits(i);
|
|
Packit Service |
6754ca |
valueFound = true;
|
|
Packit Service |
6754ca |
} else {
|
|
Packit Service |
6754ca |
half tmpHalf;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
tmpHalf.setBits(i);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (fabs((float)inputHalf - (float)tmpHalf) <
|
|
Packit Service |
6754ca |
fabs((float)inputHalf - (float)closestHalf)) {
|
|
Packit Service |
6754ca |
closestHalf = tmpHalf;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (valueFound == false) {
|
|
Packit Service |
6754ca |
fprintf(stderr, "bork bork bork!\n");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
candidate[candidateCount] = closestHalf;
|
|
Packit Service |
6754ca |
candidateCount++;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
// Sort candidates by increasing number of bits set
|
|
Packit Service |
6754ca |
for (int i=0; i
|
|
Packit Service |
6754ca |
for (int j=i+1; j
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
int iCnt = countSetBits(candidate[i].bits());
|
|
Packit Service |
6754ca |
int jCnt = countSetBits(candidate[j].bits());
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (jCnt < iCnt) {
|
|
Packit Service |
6754ca |
half tmp = candidate[i];
|
|
Packit Service |
6754ca |
candidate[i] = candidate[j];
|
|
Packit Service |
6754ca |
candidate[j] = tmp;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
// Copy candidates to the data buffer;
|
|
Packit Service |
6754ca |
for (int i=0; i
|
|
Packit Service |
6754ca |
_elements[_numElements] = candidate[i].bits();
|
|
Packit Service |
6754ca |
_numElements++;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (input == _endValue-1) {
|
|
Packit Service |
6754ca |
_lastCandidateCount = candidateCount;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
private:
|
|
Packit Service |
6754ca |
size_t _lastCandidateCount;
|
|
Packit Service |
6754ca |
size_t _startValue;
|
|
Packit Service |
6754ca |
size_t _endValue;
|
|
Packit Service |
6754ca |
size_t _numElements;
|
|
Packit Service |
6754ca |
size_t *_offset;
|
|
Packit Service |
6754ca |
unsigned short *_elements;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Precomputing the bit count runs faster than using
|
|
Packit Service |
6754ca |
// the builtin instruction, at least in one case..
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Precomputing 8-bits is no slower than 16-bits,
|
|
Packit Service |
6754ca |
// and saves a fair bit of overhead..
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
int countSetBits(unsigned short src)
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
static const unsigned short numBitsSet[256] =
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
|
Packit Service |
6754ca |
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
Packit Service |
6754ca |
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
Packit Service |
6754ca |
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
Packit Service |
6754ca |
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
Packit Service |
6754ca |
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
Packit Service |
6754ca |
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
Packit Service |
6754ca |
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
Packit Service |
6754ca |
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
|
Packit Service |
6754ca |
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
Packit Service |
6754ca |
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
Packit Service |
6754ca |
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
Packit Service |
6754ca |
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
|
|
Packit Service |
6754ca |
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
Packit Service |
6754ca |
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
|
|
Packit Service |
6754ca |
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
|
|
Packit Service |
6754ca |
};
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
return numBitsSet[src & 0xff] + numBitsSet[src >> 8];
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
}; // class LutHeaderWorker
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
} // namespace
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Generate a no-op LUT, to cut down in conditional branches
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
void
|
|
Packit Service |
6754ca |
generateNoop()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
printf("const unsigned short dwaCompressorNoOp[] = \n");
|
|
Packit Service |
6754ca |
printf("{");
|
|
Packit Service |
6754ca |
for (int i=0; i<65536; ++i) {
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (i % 8 == 0) {
|
|
Packit Service |
6754ca |
printf("\n ");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
unsigned short dst;
|
|
Packit Service |
6754ca |
char *tmp = (char *)(&dst);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
unsigned short src = (unsigned short)i;
|
|
Packit Service |
6754ca |
Xdr::write <CharPtrIO> (tmp, src);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("0x%04x, ", dst);
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("\n};\n");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Nonlinearly encode luminance. For values below 1.0, we want
|
|
Packit Service |
6754ca |
// to use a gamma 2.2 function to match what is fairly common
|
|
Packit Service |
6754ca |
// for storing output referred. However, > 1, gamma functions blow up,
|
|
Packit Service |
6754ca |
// and log functions are much better behaved. We could use a log
|
|
Packit Service |
6754ca |
// function everywhere, but it tends to over-sample dark
|
|
Packit Service |
6754ca |
// regions and undersample the brighter regions, when
|
|
Packit Service |
6754ca |
// compared to the way real devices reproduce values.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// So, above 1, use a log function which is a smooth blend
|
|
Packit Service |
6754ca |
// into the gamma function.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Nonlinear(linear) =
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// linear^(1./2.2) / linear <= 1.0
|
|
Packit Service |
6754ca |
// |
|
|
Packit Service |
6754ca |
// ln(linear)/ln(e^2.2) + 1 \ otherwise
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// toNonlinear[] needs to take in XDR format half float values,
|
|
Packit Service |
6754ca |
// and output NATIVE format float.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// toLinear[] does the opposite - takes in NATIVE half and
|
|
Packit Service |
6754ca |
// outputs XDR half values.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
void
|
|
Packit Service |
6754ca |
generateToLinear()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
unsigned short toLinear[65536];
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
toLinear[0] = 0;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
for (int i=1; i<65536; ++i) {
|
|
Packit Service |
6754ca |
half h;
|
|
Packit Service |
6754ca |
float sign = 1;
|
|
Packit Service |
6754ca |
float logBase = pow(2.7182818, 2.2);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
// map NaN and inf to 0
|
|
Packit Service |
6754ca |
if ((i & 0x7c00) == 0x7c00) {
|
|
Packit Service |
6754ca |
toLinear[i] = 0;
|
|
Packit Service |
6754ca |
continue;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// _toLinear - assume i is NATIVE, but our output needs
|
|
Packit Service |
6754ca |
// to get flipped to XDR
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
h.setBits(i);
|
|
Packit Service |
6754ca |
sign = 1;
|
|
Packit Service |
6754ca |
if ((float)h < 0) {
|
|
Packit Service |
6754ca |
sign = -1;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if ( fabs( (float)h) <= 1.0 ) {
|
|
Packit Service |
6754ca |
h = (half)(sign * pow((float)fabs((float)h), 2.2f));
|
|
Packit Service |
6754ca |
} else {
|
|
Packit Service |
6754ca |
h = (half)(sign * pow(logBase, (float)(fabs((float)h) - 1.0)));
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
char *tmp = (char *)(&toLinear[i]);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
Xdr::write <CharPtrIO> ( tmp, h.bits());
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("const unsigned short dwaCompressorToLinear[] = \n");
|
|
Packit Service |
6754ca |
printf("{");
|
|
Packit Service |
6754ca |
for (int i=0; i<65536; ++i) {
|
|
Packit Service |
6754ca |
if (i % 8 == 0) {
|
|
Packit Service |
6754ca |
printf("\n ");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("0x%04x, ", toLinear[i]);
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("\n};\n");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
void
|
|
Packit Service |
6754ca |
generateToNonlinear()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
unsigned short toNonlinear[65536];
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
toNonlinear[0] = 0;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
for (int i=1; i<65536; ++i) {
|
|
Packit Service |
6754ca |
unsigned short usNative, usXdr;
|
|
Packit Service |
6754ca |
half h;
|
|
Packit Service |
6754ca |
float sign = 1;
|
|
Packit Service |
6754ca |
float logBase = pow(2.7182818, 2.2);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
usXdr = i;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
const char *tmp = (char *)(&usXdr);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
Xdr::read<CharPtrIO>(tmp, usNative);
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
// map NaN and inf to 0
|
|
Packit Service |
6754ca |
if ((usNative & 0x7c00) == 0x7c00) {
|
|
Packit Service |
6754ca |
toNonlinear[i] = 0;
|
|
Packit Service |
6754ca |
continue;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// toNonlinear - assume i is XDR
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
h.setBits(usNative);
|
|
Packit Service |
6754ca |
sign = 1;
|
|
Packit Service |
6754ca |
if ((float)h < 0) {
|
|
Packit Service |
6754ca |
sign = -1;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if ( fabs( (float)h ) <= 1.0) {
|
|
Packit Service |
6754ca |
h = (half)(sign * pow(fabs((float)h), 1.f/2.2f));
|
|
Packit Service |
6754ca |
} else {
|
|
Packit Service |
6754ca |
h = (half)(sign * ( log(fabs((float)h)) / log(logBase) + 1.0) );
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
toNonlinear[i] = h.bits();
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("const unsigned short dwaCompressorToNonlinear[] = \n");
|
|
Packit Service |
6754ca |
printf("{");
|
|
Packit Service |
6754ca |
for (int i=0; i<65536; ++i) {
|
|
Packit Service |
6754ca |
if (i % 8 == 0) {
|
|
Packit Service |
6754ca |
printf("\n ");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("0x%04x, ", toNonlinear[i]);
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("\n};\n");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Attempt to get available CPUs in a somewhat portable way.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
int
|
|
Packit Service |
6754ca |
cpuCount()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
if (!IlmThread::supportsThreads()) return 1;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
int cpuCount = 1;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
#if defined (OPENEXR_IMF_HAVE_SYSCONF_NPROCESSORS_ONLN)
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
cpuCount = sysconf(_SC_NPROCESSORS_ONLN);
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
#elif defined (_WIN32)
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
SYSTEM_INFO sysinfo;
|
|
Packit Service |
6754ca |
GetSystemInfo( &sysinfo );
|
|
Packit Service |
6754ca |
cpuCount = sysinfo.dwNumberOfProcessors;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
#endif
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (cpuCount < 1) cpuCount = 1;
|
|
Packit Service |
6754ca |
return cpuCount;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// Generate acceleration luts for the quantization.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// For each possible input value, we want to find the closest numbers
|
|
Packit Service |
6754ca |
// which have one fewer bits set than before.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// This gives us num_bits(input)-1 values per input. If we alloc
|
|
Packit Service |
6754ca |
// space for everything, that's like a 2MB table. We can do better
|
|
Packit Service |
6754ca |
// by compressing all the values to be contigious and using offset
|
|
Packit Service |
6754ca |
// pointers.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
// After we've found the candidates with fewer bits set, sort them
|
|
Packit Service |
6754ca |
// based on increasing numbers of bits set. This way, on quantize(),
|
|
Packit Service |
6754ca |
// we can scan through the list and halt once we find the first
|
|
Packit Service |
6754ca |
// candidate within the error range. For small values that can
|
|
Packit Service |
6754ca |
// be quantized to 0, 0 is the first value tested and the search
|
|
Packit Service |
6754ca |
// can exit fairly quickly.
|
|
Packit Service |
6754ca |
//
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
void
|
|
Packit Service |
6754ca |
generateLutHeader()
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
std::vector<LutHeaderWorker*> workers;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
size_t numWorkers = cpuCount();
|
|
Packit Service |
6754ca |
size_t workerInterval = 65536 / numWorkers;
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
for (size_t i=0; i
|
|
Packit Service |
6754ca |
if (i != numWorkers-1) {
|
|
Packit Service |
6754ca |
workers.push_back( new LutHeaderWorker( i *workerInterval,
|
|
Packit Service |
6754ca |
(i+1)*workerInterval) );
|
|
Packit Service |
6754ca |
} else {
|
|
Packit Service |
6754ca |
workers.push_back( new LutHeaderWorker(i*workerInterval, 65536) );
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
if (IlmThread::supportsThreads()) {
|
|
Packit Service |
6754ca |
std::vector<LutHeaderWorker::Runner*> runners;
|
|
Packit Service |
6754ca |
for (size_t i=0; i
|
|
Packit Service |
6754ca |
runners.push_back( new LutHeaderWorker::Runner(*workers[i], (i==0)) );
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
for (size_t i=0; i
|
|
Packit Service |
6754ca |
delete runners[i];
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
} else {
|
|
Packit Service |
6754ca |
for (size_t i=0; i
|
|
Packit Service |
6754ca |
workers[i]->run(i == 0);
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("static unsigned int closestDataOffset[] = {\n");
|
|
Packit Service |
6754ca |
int offsetIdx = 0;
|
|
Packit Service |
6754ca |
int offsetPrev = 0;
|
|
Packit Service |
6754ca |
for (size_t i=0; i
|
|
Packit Service |
6754ca |
for (size_t value=0; value<workers[i]->numValues(); ++value) {
|
|
Packit Service |
6754ca |
if (offsetIdx % 8 == 0) {
|
|
Packit Service |
6754ca |
printf(" ");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("%6lu, ", workers[i]->offset()[value] + offsetPrev);
|
|
Packit Service |
6754ca |
if (offsetIdx % 8 == 7) {
|
|
Packit Service |
6754ca |
printf("\n");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
offsetIdx++;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
offsetPrev += workers[i]->offset()[workers[i]->numValues()-1] +
|
|
Packit Service |
6754ca |
workers[i]->lastCandidateCount();
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("};\n\n\n");
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("static unsigned short closestData[] = {\n");
|
|
Packit Service |
6754ca |
int elementIdx = 0;
|
|
Packit Service |
6754ca |
for (size_t i=0; i
|
|
Packit Service |
6754ca |
for (size_t element=0; element<workers[i]->numElements(); ++element) {
|
|
Packit Service |
6754ca |
if (elementIdx % 8 == 0) {
|
|
Packit Service |
6754ca |
printf(" ");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("%5d, ", workers[i]->elements()[element]);
|
|
Packit Service |
6754ca |
if (elementIdx % 8 == 7) {
|
|
Packit Service |
6754ca |
printf("\n");
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
elementIdx++;
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
printf("};\n\n\n");
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
for (size_t i=0; i
|
|
Packit Service |
6754ca |
delete workers[i];
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
}
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
int
|
|
Packit Service |
6754ca |
main(int argc, char **argv)
|
|
Packit Service |
6754ca |
{
|
|
Packit Service |
6754ca |
printf("#include <cstddef>\n");
|
|
Packit Service |
6754ca |
printf("\n\n\n");
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
generateNoop();
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("\n\n\n");
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
generateToLinear();
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("\n\n\n");
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
generateToNonlinear();
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
printf("\n\n\n");
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
generateLutHeader();
|
|
Packit Service |
6754ca |
|
|
Packit Service |
6754ca |
return 0;
|
|
Packit Service |
6754ca |
}
|