Blame exrmaketiled/makeTiled.cpp

Packit Service 6754ca
///////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
//
Packit Service 6754ca
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
Packit Service 6754ca
// Digital Ltd. 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 Industrial Light & Magic 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
//----------------------------------------------------------------------------
Packit Service 6754ca
//
Packit Service 6754ca
//	Produce a tiled version of an OpenEXR image.
Packit Service 6754ca
//
Packit Service 6754ca
//----------------------------------------------------------------------------
Packit Service 6754ca
Packit Service 6754ca
#include "makeTiled.h"
Packit Service 6754ca
#include "Image.h"
Packit Service 6754ca
Packit Service 6754ca
#include "ImfTiledInputPart.h"
Packit Service 6754ca
#include "ImfTiledOutputPart.h"
Packit Service 6754ca
#include "ImfInputPart.h"
Packit Service 6754ca
#include "ImfOutputPart.h"
Packit Service 6754ca
#include "ImfDeepScanLineInputPart.h"
Packit Service 6754ca
#include "ImfDeepScanLineOutputPart.h"
Packit Service 6754ca
#include "ImfDeepTiledInputPart.h"
Packit Service 6754ca
#include "ImfDeepTiledOutputPart.h"
Packit Service 6754ca
#include "ImfChannelList.h"
Packit Service 6754ca
#include "ImfChannelList.h"
Packit Service 6754ca
#include "ImfFrameBuffer.h"
Packit Service 6754ca
#include "ImfStandardAttributes.h"
Packit Service 6754ca
#include "ImathFun.h"
Packit Service 6754ca
#include "Iex.h"
Packit Service 6754ca
#include "ImfMisc.h"
Packit Service 6754ca
Packit Service 6754ca
#include <map>
Packit Service 6754ca
#include <algorithm>
Packit Service 6754ca
#include <iostream>
Packit Service 6754ca
#include <vector>
Packit Service 6754ca
Packit Service 6754ca
#include "namespaceAlias.h"
Packit Service 6754ca
using namespace IMF;
Packit Service 6754ca
using namespace IMATH_NAMESPACE;
Packit Service 6754ca
using namespace std;
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
namespace {
Packit Service 6754ca
Packit Service 6754ca
string
Packit Service 6754ca
extToString (Extrapolation ext)
Packit Service 6754ca
{
Packit Service 6754ca
    string str;
Packit Service 6754ca
Packit Service 6754ca
    switch (ext)
Packit Service 6754ca
    {
Packit Service 6754ca
        case BLACK:
Packit Service 6754ca
            str = "black";
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case CLAMP:
Packit Service 6754ca
            str = "clamp";
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case PERIODIC:
Packit Service 6754ca
            str = "periodic";
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case MIRROR:
Packit Service 6754ca
            str = "mirror";
Packit Service 6754ca
            break;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return str;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
int
Packit Service 6754ca
mirror (int x, int w)
Packit Service 6754ca
{
Packit Service 6754ca
    int d = divp (x, w);
Packit Service 6754ca
    int m = modp (x, w);
Packit Service 6754ca
    return (d & 1)? w - 1 - m: m;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
template <class T>
Packit Service 6754ca
double
Packit Service 6754ca
sampleX (const TypedImageChannel<T> &channel,
Packit Service 6754ca
         int w,
Packit Service 6754ca
         double x,
Packit Service 6754ca
         int y,
Packit Service 6754ca
         Extrapolation ext)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Sample an image channel at location (x, y), where
Packit Service 6754ca
    // x is a floating point number, and y is an integer.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    int xs = IMATH_NAMESPACE::floor (x);
Packit Service 6754ca
    int xt = xs + 1;
Packit Service 6754ca
    double s = xt - x;
Packit Service 6754ca
    double t = 1 - s;
Packit Service 6754ca
    double vs=0.0;
Packit Service 6754ca
    double vt=0.0;
Packit Service 6754ca
Packit Service 6754ca
    switch (ext)
Packit Service 6754ca
    {
Packit Service 6754ca
        case BLACK:
Packit Service 6754ca
Packit Service 6754ca
            vs = (xs >= 0 && xs < w)? double (channel (xs, y)): 0.0;
Packit Service 6754ca
            vt = (xt >= 0 && xt < w)? double (channel (xt, y)): 0.0;
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case CLAMP:
Packit Service 6754ca
Packit Service 6754ca
            xs = clamp (xs, 0, w - 1);
Packit Service 6754ca
            xt = clamp (xt, 0, w - 1);
Packit Service 6754ca
            vs = channel (xs, y);
Packit Service 6754ca
            vt = channel (xt, y);
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case PERIODIC:
Packit Service 6754ca
Packit Service 6754ca
            xs = modp (xs, w);
Packit Service 6754ca
            xt = modp (xt, w);
Packit Service 6754ca
            vs = channel (xs, y);
Packit Service 6754ca
            vt = channel (xt, y);
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case MIRROR:
Packit Service 6754ca
Packit Service 6754ca
            xs = mirror (xs, w);
Packit Service 6754ca
            xt = mirror (xt, w);
Packit Service 6754ca
            vs = channel (xs, y);
Packit Service 6754ca
            vt = channel (xt, y);
Packit Service 6754ca
            break;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return s * vs + t * vt;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
template <class T>
Packit Service 6754ca
double
Packit Service 6754ca
sampleY (const TypedImageChannel<T> &channel,
Packit Service 6754ca
         int h,
Packit Service 6754ca
         int x,
Packit Service 6754ca
         double y,
Packit Service 6754ca
         Extrapolation ext)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Sample an image channel at location (x, y), where
Packit Service 6754ca
    // x is an integer, and y is a floating point number.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    int ys = IMATH_NAMESPACE::floor (y);
Packit Service 6754ca
    int yt = ys + 1;
Packit Service 6754ca
    double s = yt - y;
Packit Service 6754ca
    double t = 1 - s;
Packit Service 6754ca
    double vs=0.0;
Packit Service 6754ca
    double vt=0.0;
Packit Service 6754ca
Packit Service 6754ca
    switch (ext)
Packit Service 6754ca
    {
Packit Service 6754ca
        case BLACK:
Packit Service 6754ca
Packit Service 6754ca
            vs = (ys >= 0 && ys < h)? double (channel (x, ys)): 0.0;
Packit Service 6754ca
            vt = (yt >= 0 && yt < h)? double (channel (x, yt)): 0.0;
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case CLAMP:
Packit Service 6754ca
Packit Service 6754ca
            ys = clamp (ys, 0, h - 1);
Packit Service 6754ca
            yt = clamp (yt, 0, h - 1);
Packit Service 6754ca
            vs = channel (x, ys);
Packit Service 6754ca
            vt = channel (x, yt);
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case PERIODIC:
Packit Service 6754ca
Packit Service 6754ca
            ys = modp (ys, h);
Packit Service 6754ca
            yt = modp (yt, h);
Packit Service 6754ca
            vs = channel (x, ys);
Packit Service 6754ca
            vt = channel (x, yt);
Packit Service 6754ca
            break;
Packit Service 6754ca
Packit Service 6754ca
        case MIRROR:
Packit Service 6754ca
Packit Service 6754ca
            ys = mirror (ys, h);
Packit Service 6754ca
            yt = mirror (yt, h);
Packit Service 6754ca
            vs = channel (x, ys);
Packit Service 6754ca
            vt = channel (x, yt);
Packit Service 6754ca
            break;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    return s * vs + t * vt;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
template <class T>
Packit Service 6754ca
T
Packit Service 6754ca
filterX (const TypedImageChannel<T> &channel,
Packit Service 6754ca
         int w,
Packit Service 6754ca
         double x,
Packit Service 6754ca
         int y,
Packit Service 6754ca
         Extrapolation ext)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Horizontal four-tap filter, centered on pixel (x + 0.5, y)
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    return T (0.125 * sampleX (channel, w, x - 1, y, ext) +
Packit Service 6754ca
              0.375 * sampleX (channel, w, x,     y, ext) +
Packit Service 6754ca
              0.375 * sampleX (channel, w, x + 1, y, ext) +
Packit Service 6754ca
              0.125 * sampleX (channel, w, x + 2, y, ext));
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
template <class T>
Packit Service 6754ca
T
Packit Service 6754ca
filterY (const TypedImageChannel<T> &channel,
Packit Service 6754ca
         int h,
Packit Service 6754ca
         int x,
Packit Service 6754ca
         double y,
Packit Service 6754ca
         Extrapolation ext)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Vertical four-tap filter, centered on pixel (x, y + 0.5)
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    return T (0.125 * sampleY (channel, h, x, y - 1, ext) +
Packit Service 6754ca
              0.375 * sampleY (channel, h, x, y,     ext) +
Packit Service 6754ca
              0.375 * sampleY (channel, h, x, y + 1, ext) +
Packit Service 6754ca
              0.125 * sampleY (channel, h, x, y + 2, ext));
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
template <class T>
Packit Service 6754ca
void
Packit Service 6754ca
reduceX (const TypedImageChannel<T> &channel0,
Packit Service 6754ca
         TypedImageChannel<T> &channel1,
Packit Service 6754ca
         bool filter,
Packit Service 6754ca
         Extrapolation &ext,
Packit Service 6754ca
         bool odd)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Shrink an image channel, channel0, horizontally
Packit Service 6754ca
    // by a factor of 2, and store the result in channel1.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    int w0 = channel0.image().width();
Packit Service 6754ca
    int w1 = channel1.image().width();
Packit Service 6754ca
    int h1 = channel1.image().height();
Packit Service 6754ca
Packit Service 6754ca
    if (filter)
Packit Service 6754ca
    {
Packit Service 6754ca
        //
Packit Service 6754ca
        // Low-pass filter and resample.
Packit Service 6754ca
        // For pixels (0, y) and (w1 - 1, y) in channel 1,
Packit Service 6754ca
        // the low-pass filter in channel0 is centered on
Packit Service 6754ca
        // pixels (0.5, y) and (w0 - 1.5, y) respectively.
Packit Service 6754ca
        //
Packit Service 6754ca
Packit Service 6754ca
        double f = (w1 > 1)? double (w0 - 2) / (w1 - 1): 1;
Packit Service 6754ca
Packit Service 6754ca
        for (int y = 0; y < h1; ++y)
Packit Service 6754ca
            for (int x = 0; x < w1; ++x)
Packit Service 6754ca
                channel1 (x, y) = filterX (channel0, w0, x * f, y, ext);
Packit Service 6754ca
    }
Packit Service 6754ca
    else
Packit Service 6754ca
    {
Packit Service 6754ca
        //
Packit Service 6754ca
        // Resample, skipping every other pixel, without
Packit Service 6754ca
        // low-pass filtering.  In order to keep the image
Packit Service 6754ca
        // from sliding to the right if the channel is
Packit Service 6754ca
        // resampled repeatedly, we skip the rightmost
Packit Service 6754ca
        // pixel of every row on even passes, and the
Packit Service 6754ca
        // leftmost pixel on odd passes.
Packit Service 6754ca
        //
Packit Service 6754ca
Packit Service 6754ca
        int offset = odd? ((w0 - 1) - 2 * (w1 - 1)): 0;
Packit Service 6754ca
Packit Service 6754ca
        for (int y = 0; y < h1; ++y)
Packit Service 6754ca
            for (int x = 0; x < w1; ++x)
Packit Service 6754ca
                channel1 (x, y) = channel0 (2 * x + offset, y);
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
template <class T>
Packit Service 6754ca
void
Packit Service 6754ca
reduceY (const TypedImageChannel<T> &channel0,
Packit Service 6754ca
         TypedImageChannel<T> &channel1,
Packit Service 6754ca
         bool filter,
Packit Service 6754ca
         Extrapolation ext,
Packit Service 6754ca
         bool odd)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Shrink an image channel, channel0, vertically
Packit Service 6754ca
    // by a factor of 2, and store the result in channel1.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    int w1 = channel1.image().width();
Packit Service 6754ca
    int h0 = channel0.image().height();
Packit Service 6754ca
    int h1 = channel1.image().height();
Packit Service 6754ca
Packit Service 6754ca
    if (filter)
Packit Service 6754ca
    {
Packit Service 6754ca
        //
Packit Service 6754ca
        // Low-pass filter and resample.
Packit Service 6754ca
        // For pixels (x, 0) and (x, h1 - 1) in channel 1,
Packit Service 6754ca
        // the low-pass filter in channel0 is centered on
Packit Service 6754ca
        // pixels (x, 0.5) and (x, h0 - 1.5) respectively.
Packit Service 6754ca
        //
Packit Service 6754ca
Packit Service 6754ca
        double f = (h1 > 1)? double (h0 - 2) / (h1 - 1): 1;
Packit Service 6754ca
Packit Service 6754ca
        for (int y = 0; y < h1; ++y)
Packit Service 6754ca
            for (int x = 0; x < w1; ++x)
Packit Service 6754ca
                channel1 (x, y) = filterY (channel0, h0, x, y * f, ext);
Packit Service 6754ca
    }
Packit Service 6754ca
    else
Packit Service 6754ca
    {
Packit Service 6754ca
        //
Packit Service 6754ca
        // Resample, skipping every other pixel, without
Packit Service 6754ca
        // low-pass filtering.  In order to keep the image
Packit Service 6754ca
        // from sliding towards the top if the channel is
Packit Service 6754ca
        // resampled repeatedly, we skip the top pixel of
Packit Service 6754ca
        // every column on even passes, and the bottom pixel
Packit Service 6754ca
        // on odd passes.
Packit Service 6754ca
        //
Packit Service 6754ca
Packit Service 6754ca
        int offset = odd? ((h0 - 1) - 2 * (h1 - 1)): 0;
Packit Service 6754ca
Packit Service 6754ca
        for (int y = 0; y < h1; ++y)
Packit Service 6754ca
            for (int x = 0; x < w1; ++x)
Packit Service 6754ca
                channel1 (x, y) = channel0 (x, 2 * y + offset);
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
reduceX (const ChannelList &channels,
Packit Service 6754ca
         const set<string> &doNotFilter,
Packit Service 6754ca
         Extrapolation ext,
Packit Service 6754ca
         bool odd,
Packit Service 6754ca
         const Image &image0,
Packit Service 6754ca
         Image &image1)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Shrink image image0 horizontally by a factor of 2,
Packit Service 6754ca
    // and store the result in image image1.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    for (ChannelList::ConstIterator i = channels.begin();
Packit Service 6754ca
         i != channels.end();
Packit Service 6754ca
         ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
        const char *name = i.name();
Packit Service 6754ca
        const Channel &channel = i.channel();
Packit Service 6754ca
        bool filter = (doNotFilter.find (name) == doNotFilter.end());
Packit Service 6754ca
Packit Service 6754ca
        switch (channel.type)
Packit Service 6754ca
        {
Packit Service 6754ca
            case IMF::HALF:
Packit Service 6754ca
Packit Service 6754ca
                reduceX (image0.typedChannel<half> (name),
Packit Service 6754ca
                         image1.typedChannel<half> (name),
Packit Service 6754ca
                         filter, ext, odd);
Packit Service 6754ca
                break;
Packit Service 6754ca
Packit Service 6754ca
            case IMF::FLOAT:
Packit Service 6754ca
Packit Service 6754ca
                reduceX (image0.typedChannel<float> (name),
Packit Service 6754ca
                         image1.typedChannel<float> (name),
Packit Service 6754ca
                         filter, ext, odd);
Packit Service 6754ca
                break;
Packit Service 6754ca
Packit Service 6754ca
            case IMF::UINT:
Packit Service 6754ca
Packit Service 6754ca
                reduceX (image0.typedChannel<unsigned int> (name),
Packit Service 6754ca
                         image1.typedChannel<unsigned int> (name),
Packit Service 6754ca
                         filter, ext, odd);
Packit Service 6754ca
                break;
Packit Service 6754ca
            default : 
Packit Service 6754ca
                break;
Packit Service 6754ca
           
Packit Service 6754ca
        }
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
reduceY (const ChannelList &channels,
Packit Service 6754ca
         const set<string> &doNotFilter,
Packit Service 6754ca
         Extrapolation ext,
Packit Service 6754ca
         bool odd,
Packit Service 6754ca
         const Image &image0,
Packit Service 6754ca
         Image &image1)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Shrink image image0 vertically by a factor of 2,
Packit Service 6754ca
    // and store the result in image image1.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    for (ChannelList::ConstIterator i = channels.begin();
Packit Service 6754ca
         i != channels.end();
Packit Service 6754ca
         ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
        const char *name = i.name();
Packit Service 6754ca
        const Channel &channel = i.channel();
Packit Service 6754ca
        bool filter = (doNotFilter.find (name) == doNotFilter.end());
Packit Service 6754ca
Packit Service 6754ca
        switch (channel.type)
Packit Service 6754ca
        {
Packit Service 6754ca
            case IMF::HALF:
Packit Service 6754ca
Packit Service 6754ca
                reduceY (image0.typedChannel<half> (name),
Packit Service 6754ca
                         image1.typedChannel<half> (name),
Packit Service 6754ca
                         filter, ext, odd);
Packit Service 6754ca
                break;
Packit Service 6754ca
Packit Service 6754ca
            case IMF::FLOAT:
Packit Service 6754ca
Packit Service 6754ca
                reduceY (image0.typedChannel<float> (name),
Packit Service 6754ca
                         image1.typedChannel<float> (name),
Packit Service 6754ca
                         filter, ext, odd);
Packit Service 6754ca
                break;
Packit Service 6754ca
Packit Service 6754ca
            case IMF::UINT:
Packit Service 6754ca
Packit Service 6754ca
                reduceY (image0.typedChannel<unsigned int> (name),
Packit Service 6754ca
                         image1.typedChannel<unsigned int> (name),
Packit Service 6754ca
                         filter, ext, odd);
Packit Service 6754ca
                break;
Packit Service 6754ca
            default : 
Packit Service 6754ca
                break;
Packit Service 6754ca
                
Packit Service 6754ca
        }
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
storeLevel (TiledOutputPart &out,
Packit Service 6754ca
            const ChannelList &channels,
Packit Service 6754ca
            int lx,
Packit Service 6754ca
            int ly,
Packit Service 6754ca
            const Image &image)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Store the pixels for level (lx, ly) in output file out.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    FrameBuffer fb;
Packit Service 6754ca
Packit Service 6754ca
    for (ChannelList::ConstIterator i = channels.begin();
Packit Service 6754ca
         i != channels.end();
Packit Service 6754ca
         ++i)
Packit Service 6754ca
    {
Packit Service 6754ca
        const char *name = i.name();
Packit Service 6754ca
        fb.insert (name, image.channel(name).slice());
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    out.setFrameBuffer (fb);
Packit Service 6754ca
Packit Service 6754ca
    for (int y = 0; y < out.numYTiles (ly); ++y)
Packit Service 6754ca
        for (int x = 0; x < out.numXTiles (lx); ++x)
Packit Service 6754ca
            out.writeTile (x, y, lx, ly);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
} // namespace
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
makeTiled (const char inFileName[],
Packit Service 6754ca
           const char outFileName[],
Packit Service 6754ca
           int partnum,
Packit Service 6754ca
           LevelMode mode,
Packit Service 6754ca
           LevelRoundingMode roundingMode,
Packit Service 6754ca
           Compression compression,
Packit Service 6754ca
           int tileSizeX,
Packit Service 6754ca
           int tileSizeY,
Packit Service 6754ca
           const set<string> &doNotFilter,
Packit Service 6754ca
           Extrapolation extX,
Packit Service 6754ca
           Extrapolation extY,
Packit Service 6754ca
           bool verbose)
Packit Service 6754ca
{
Packit Service 6754ca
    Image image0;
Packit Service 6754ca
    Image image1;
Packit Service 6754ca
    Image image2;
Packit Service 6754ca
    Header header;
Packit Service 6754ca
    FrameBuffer fb;
Packit Service 6754ca
    vector<Header> headers;
Packit Service 6754ca
Packit Service 6754ca
    //
Packit Service 6754ca
    // Load the input image
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    MultiPartInputFile input (inFileName);
Packit Service 6754ca
    int parts = input.parts();
Packit Service 6754ca
Packit Service 6754ca
    for (int p = 0 ; p < parts; p++)
Packit Service 6754ca
    {
Packit Service 6754ca
        if (verbose)
Packit Service 6754ca
            cout << "reading file " << inFileName << endl;
Packit Service 6754ca
Packit Service 6754ca
        if(p == partnum)
Packit Service 6754ca
        {
Packit Service 6754ca
            InputPart in (input, p);
Packit Service 6754ca
            header = in.header();
Packit Service 6754ca
            if (hasEnvmap (header) && mode != ONE_LEVEL)
Packit Service 6754ca
            {
Packit Service 6754ca
                //
Packit Service 6754ca
                // Proper low-pass filtering and subsampling
Packit Service 6754ca
                // of environment maps is not implemented in
Packit Service 6754ca
                // this program.
Packit Service 6754ca
                //
Packit Service 6754ca
Packit Service 6754ca
                throw IEX_NAMESPACE::NoImplExc ("This program cannot generate "
Packit Service 6754ca
                                      "multiresolution environment maps.  "
Packit Service 6754ca
                                      "Use exrenvmap instead.");
Packit Service 6754ca
            }
Packit Service 6754ca
Packit Service 6754ca
            image0.resize (header.dataWindow());
Packit Service 6754ca
Packit Service 6754ca
            for (ChannelList::ConstIterator i = header.channels().begin();
Packit Service 6754ca
                            i != header.channels().end();
Packit Service 6754ca
                            ++i)
Packit Service 6754ca
            {
Packit Service 6754ca
                const char *name = i.name();
Packit Service 6754ca
                const Channel &channel = i.channel();
Packit Service 6754ca
Packit Service 6754ca
                if (channel.xSampling != 1 || channel.ySampling != 1)
Packit Service 6754ca
                {
Packit Service 6754ca
                    throw IEX_NAMESPACE::InputExc ("Sub-sampled image channels are "
Packit Service 6754ca
                                         "not supported in tiled files.");
Packit Service 6754ca
                }
Packit Service 6754ca
Packit Service 6754ca
                image0.addChannel (name, channel.type);
Packit Service 6754ca
                image1.addChannel (name, channel.type);
Packit Service 6754ca
                image2.addChannel (name, channel.type);
Packit Service 6754ca
                fb.insert (name, image0.channel(name).slice());
Packit Service 6754ca
            }
Packit Service 6754ca
Packit Service 6754ca
            in.setFrameBuffer (fb);
Packit Service 6754ca
            in.readPixels (header.dataWindow().min.y, header.dataWindow().max.y);
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
            //
Packit Service 6754ca
            // Generate the header for the output file by modifying
Packit Service 6754ca
            // the input file's header
Packit Service 6754ca
            //
Packit Service 6754ca
Packit Service 6754ca
            header.setTileDescription (TileDescription (tileSizeX, tileSizeY,
Packit Service 6754ca
                                                        mode, roundingMode));
Packit Service 6754ca
Packit Service 6754ca
            header.compression() = compression;
Packit Service 6754ca
            header.lineOrder() = INCREASING_Y;
Packit Service 6754ca
Packit Service 6754ca
            if (mode != ONE_LEVEL)
Packit Service 6754ca
                addWrapmodes (header, extToString (extX) + "," + extToString (extY));
Packit Service 6754ca
Packit Service 6754ca
            //
Packit Service 6754ca
            // set tileDescription, type, and chunckcount for multipart
Packit Service 6754ca
            //
Packit Service 6754ca
            header.setType(TILEDIMAGE);
Packit Service 6754ca
            int chunkcount = getChunkOffsetTableSize(header, true);
Packit Service 6754ca
            header.setChunkCount(chunkcount);
Packit Service 6754ca
Packit Service 6754ca
            headers.push_back(header);
Packit Service 6754ca
        }
Packit Service 6754ca
        else
Packit Service 6754ca
        {
Packit Service 6754ca
            Header h = input.header(p);
Packit Service 6754ca
            headers.push_back(h);
Packit Service 6754ca
        }
Packit Service 6754ca
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    //
Packit Service 6754ca
    // Store the highest-resolution level of the image in the output file
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    MultiPartOutputFile output (outFileName, &headers[0], headers.size());
Packit Service 6754ca
Packit Service 6754ca
    for(int p = 0 ; p < parts; p++)
Packit Service 6754ca
    {
Packit Service 6754ca
        if (p == partnum)
Packit Service 6754ca
        {
Packit Service 6754ca
            try
Packit Service 6754ca
            {
Packit Service 6754ca
                TiledOutputPart out (output, partnum);
Packit Service 6754ca
            //    TiledOutputFile out (outFileName, header);
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
                out.setFrameBuffer (fb);
Packit Service 6754ca
Packit Service 6754ca
                if (verbose)
Packit Service 6754ca
                    cout << "writing file " << outFileName << "\n"
Packit Service 6754ca
                            "level (0, 0)" << endl;
Packit Service 6754ca
Packit Service 6754ca
                for (int y = 0; y < out.numYTiles (0); ++y)
Packit Service 6754ca
                    for (int x = 0; x < out.numXTiles (0); ++x)
Packit Service 6754ca
                        out.writeTile (x, y, 0);
Packit Service 6754ca
Packit Service 6754ca
                //
Packit Service 6754ca
                // If necessary, generate the lower-resolution mipmap
Packit Service 6754ca
                // or ripmap levels, and store them in the output file.
Packit Service 6754ca
                //
Packit Service 6754ca
Packit Service 6754ca
                if (mode == MIPMAP_LEVELS)
Packit Service 6754ca
                {
Packit Service 6754ca
                    for (int l = 1; l < out.numLevels(); ++l)
Packit Service 6754ca
                    {
Packit Service 6754ca
                        image1.resize (out.dataWindowForLevel (l, l - 1));
Packit Service 6754ca
Packit Service 6754ca
                        reduceX (header.channels(),
Packit Service 6754ca
                                 doNotFilter,
Packit Service 6754ca
                                 extX,
Packit Service 6754ca
                                 l & 1,
Packit Service 6754ca
                                 image0,
Packit Service 6754ca
                                 image1);
Packit Service 6754ca
Packit Service 6754ca
                        image0.resize (out.dataWindowForLevel (l, l));
Packit Service 6754ca
Packit Service 6754ca
                        reduceY (header.channels(),
Packit Service 6754ca
                                 doNotFilter,
Packit Service 6754ca
                                 extY,
Packit Service 6754ca
                                 l & 1,
Packit Service 6754ca
                                 image1,
Packit Service 6754ca
                                 image0);
Packit Service 6754ca
Packit Service 6754ca
                        if (verbose)
Packit Service 6754ca
                            cout << "level (" << l << ", " << l << ")" << endl;
Packit Service 6754ca
Packit Service 6754ca
                        storeLevel (out, header.channels(), l, l, image0);
Packit Service 6754ca
                    }
Packit Service 6754ca
                }
Packit Service 6754ca
Packit Service 6754ca
                if (mode == RIPMAP_LEVELS)
Packit Service 6754ca
                {
Packit Service 6754ca
                    Image *iptr0 = &image0;
Packit Service 6754ca
                    Image *iptr1 = &image1;
Packit Service 6754ca
                    Image *iptr2 = &image2;
Packit Service 6754ca
Packit Service 6754ca
                    for (int ly = 0; ly < out.numYLevels(); ++ly)
Packit Service 6754ca
                    {
Packit Service 6754ca
                        if (ly < out.numYLevels() - 1)
Packit Service 6754ca
                        {
Packit Service 6754ca
                            iptr2->resize (out.dataWindowForLevel (0, ly + 1));
Packit Service 6754ca
Packit Service 6754ca
                            reduceY (header.channels(),
Packit Service 6754ca
                                     doNotFilter,
Packit Service 6754ca
                                     extY,
Packit Service 6754ca
                                     ly & 1,
Packit Service 6754ca
                                     *iptr0,
Packit Service 6754ca
                                     *iptr2);
Packit Service 6754ca
                        }
Packit Service 6754ca
Packit Service 6754ca
                        for (int lx = 0; lx < out.numXLevels(); ++lx)
Packit Service 6754ca
                        {
Packit Service 6754ca
                            if (lx != 0 || ly != 0)
Packit Service 6754ca
                            {
Packit Service 6754ca
                                if (verbose)
Packit Service 6754ca
                                    cout << "level (" << lx << ", " << ly << ")" << endl;
Packit Service 6754ca
Packit Service 6754ca
                                storeLevel (out, header.channels(), lx, ly, *iptr0);
Packit Service 6754ca
                            }
Packit Service 6754ca
Packit Service 6754ca
                            if (lx < out.numXLevels() - 1)
Packit Service 6754ca
                            {
Packit Service 6754ca
                                iptr1->resize (out.dataWindowForLevel (lx + 1, ly));
Packit Service 6754ca
Packit Service 6754ca
                                reduceX (header.channels(),
Packit Service 6754ca
                                         doNotFilter,
Packit Service 6754ca
                                         extX,
Packit Service 6754ca
                                         lx & 1,
Packit Service 6754ca
                                         *iptr0,
Packit Service 6754ca
                                         *iptr1);
Packit Service 6754ca
Packit Service 6754ca
                                swap (iptr0, iptr1);
Packit Service 6754ca
                            }
Packit Service 6754ca
                        }
Packit Service 6754ca
Packit Service 6754ca
                        swap (iptr2, iptr0);
Packit Service 6754ca
                    }
Packit Service 6754ca
                }
Packit Service 6754ca
            }
Packit Service 6754ca
            catch (const exception &e)
Packit Service 6754ca
            {
Packit Service 6754ca
                cerr << e.what() << endl;
Packit Service 6754ca
            }
Packit Service 6754ca
        }
Packit Service 6754ca
        else
Packit Service 6754ca
        {
Packit Service 6754ca
            Header header = headers[p];
Packit Service 6754ca
            std::string type = header.type();
Packit Service 6754ca
            if (type == TILEDIMAGE)
Packit Service 6754ca
            {
Packit Service 6754ca
                TiledInputPart in (input, p);
Packit Service 6754ca
                TiledOutputPart out (output, p);
Packit Service 6754ca
                out.copyPixels (in);
Packit Service 6754ca
            }
Packit Service 6754ca
            else if (type == SCANLINEIMAGE)
Packit Service 6754ca
            {
Packit Service 6754ca
                using std::max;  InputPart in (input, p);
Packit Service 6754ca
                OutputPart out (output, p);
Packit Service 6754ca
                out.copyPixels (in);
Packit Service 6754ca
            }
Packit Service 6754ca
            else if (type == DEEPSCANLINE)
Packit Service 6754ca
            {
Packit Service 6754ca
                DeepScanLineInputPart in (input,p);
Packit Service 6754ca
                DeepScanLineOutputPart out (output,p);
Packit Service 6754ca
                out.copyPixels (in);
Packit Service 6754ca
            }
Packit Service 6754ca
            else if (type == DEEPTILE)
Packit Service 6754ca
            {
Packit Service 6754ca
                DeepTiledInputPart in (input,p);
Packit Service 6754ca
                DeepTiledOutputPart out (output,p);
Packit Service 6754ca
                out.copyPixels (in);
Packit Service 6754ca
            }
Packit Service 6754ca
        }
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    if (verbose)
Packit Service 6754ca
	cout << "done." << endl;
Packit Service 6754ca
}
Packit Service 6754ca