Blame IlmImfTest/testScanLineApi.cpp

Packit 0d464f
///////////////////////////////////////////////////////////////////////////
Packit 0d464f
//
Packit 0d464f
// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
Packit 0d464f
// Digital Ltd. LLC
Packit 0d464f
// 
Packit 0d464f
// All rights reserved.
Packit 0d464f
// 
Packit 0d464f
// Redistribution and use in source and binary forms, with or without
Packit 0d464f
// modification, are permitted provided that the following conditions are
Packit 0d464f
// met:
Packit 0d464f
// *       Redistributions of source code must retain the above copyright
Packit 0d464f
// notice, this list of conditions and the following disclaimer.
Packit 0d464f
// *       Redistributions in binary form must reproduce the above
Packit 0d464f
// copyright notice, this list of conditions and the following disclaimer
Packit 0d464f
// in the documentation and/or other materials provided with the
Packit 0d464f
// distribution.
Packit 0d464f
// *       Neither the name of Industrial Light & Magic nor the names of
Packit 0d464f
// its contributors may be used to endorse or promote products derived
Packit 0d464f
// from this software without specific prior written permission. 
Packit 0d464f
// 
Packit 0d464f
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Packit 0d464f
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Packit 0d464f
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Packit 0d464f
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
Packit 0d464f
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
Packit 0d464f
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
Packit 0d464f
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
Packit 0d464f
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
Packit 0d464f
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
Packit 0d464f
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
Packit 0d464f
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Packit 0d464f
//
Packit 0d464f
///////////////////////////////////////////////////////////////////////////
Packit 0d464f
Packit 0d464f
Packit 0d464f
#include <ImfTiledOutputFile.h>
Packit 0d464f
#include <ImfTiledInputFile.h>
Packit 0d464f
#include <ImfInputFile.h>
Packit 0d464f
#include <ImfTiledRgbaFile.h>
Packit 0d464f
#include <ImfRgbaFile.h>
Packit 0d464f
#include <ImfArray.h>
Packit 0d464f
#include <ImfChannelList.h>
Packit 0d464f
#include <ImfThreading.h>
Packit 0d464f
#include "IlmThread.h"
Packit 0d464f
#include "ImathRandom.h"
Packit 0d464f
#include <string>
Packit 0d464f
#include <stdio.h>
Packit 0d464f
#include <assert.h>
Packit 0d464f
#include <vector>
Packit 0d464f
#include <math.h>
Packit 0d464f
#include <ImfTileDescriptionAttribute.h>
Packit 0d464f
Packit 0d464f
Packit 0d464f
namespace IMF = OPENEXR_IMF_NAMESPACE;
Packit 0d464f
using namespace IMF;
Packit 0d464f
using namespace std;
Packit 0d464f
using namespace IMATH_NAMESPACE;
Packit 0d464f
Packit 0d464f
namespace {
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
fillPixels (Array2D<unsigned int> &pi,
Packit 0d464f
            Array2D<half> &ph,
Packit 0d464f
            Array2D<float> &pf,
Packit 0d464f
            int width,
Packit 0d464f
            int height)
Packit 0d464f
{
Packit 0d464f
    for (int y = 0; y < height; ++y)
Packit 0d464f
        for (int x = 0; x < width; ++x)
Packit 0d464f
        {
Packit 0d464f
            pi[y][x] = x % 100 + 100 * (y % 100);
Packit 0d464f
            ph[y][x] = sin (double (x)) + sin (y * 0.5);
Packit 0d464f
            pf[y][x] = sin (double (y)) + sin (x * 0.5);
Packit 0d464f
        }
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
writeRead (const Array2D<unsigned int> &pi1,
Packit 0d464f
           const Array2D<half> &ph1,
Packit 0d464f
           const Array2D<float> &pf1,
Packit 0d464f
           const char fileName[],
Packit 0d464f
           LineOrder lorder,
Packit 0d464f
           int width,
Packit 0d464f
           int height,
Packit 0d464f
           int xSize,
Packit 0d464f
           int ySize,
Packit 0d464f
           int xOffset,
Packit 0d464f
           int yOffset,
Packit 0d464f
           Compression comp,
Packit 0d464f
           LevelMode mode,
Packit 0d464f
	   LevelRoundingMode rmode)
Packit 0d464f
{
Packit 0d464f
    //
Packit 0d464f
    // Write the pixel data in pi1, ph1 and ph2 to a tiled
Packit 0d464f
    // image file using the specified parameters.
Packit 0d464f
    // Read the pixel data back from the file using the scanline
Packit 0d464f
    // interface one scanline at a time, and verify that the data did
Packit 0d464f
    // not change.
Packit 0d464f
    // For MIPMAP and RIPMAP_LEVELS, the lower levels of the images
Packit 0d464f
    // are filled in cropped versions of the level(0,0) image,
Packit 0d464f
    // i.e. no filtering is done.
Packit 0d464f
    //
Packit 0d464f
Packit 0d464f
    cout << "levelMode " << mode <<
Packit 0d464f
	    ", roundingMode " << rmode <<
Packit 0d464f
            ", line order " << lorder <<
Packit 0d464f
            ",\ntileSize " << xSize << "x" << ySize <<
Packit 0d464f
            ", xOffset " << xOffset <<
Packit 0d464f
            ", yOffset "<< yOffset << endl;
Packit 0d464f
Packit 0d464f
    Header hdr ((Box2i (V2i (0, 0),                     // display window
Packit 0d464f
                        V2i (width - 1, height -1))),
Packit 0d464f
                (Box2i (V2i (xOffset, yOffset),         // data window
Packit 0d464f
                        V2i (xOffset + width - 1, yOffset + height - 1))));
Packit 0d464f
    hdr.lineOrder() = lorder;
Packit 0d464f
    hdr.compression() = comp;
Packit 0d464f
Packit 0d464f
    hdr.channels().insert ("I", Channel (IMF::UINT));
Packit 0d464f
    hdr.channels().insert ("H", Channel (IMF::HALF));
Packit 0d464f
    hdr.channels().insert ("F", Channel (IMF::FLOAT));
Packit 0d464f
    
Packit 0d464f
    hdr.setTileDescription(TileDescription(xSize, ySize, mode, rmode));
Packit 0d464f
    {
Packit 0d464f
        FrameBuffer fb; 
Packit 0d464f
Packit 0d464f
        fb.insert ("I",                                       // name
Packit 0d464f
                   Slice (IMF::UINT,                          // type
Packit 0d464f
                          (char *) &pi1[-yOffset][-xOffset],  // base
Packit 0d464f
                          sizeof (pi1[0][0]),                 // xStride
Packit 0d464f
                          sizeof (pi1[0][0]) * width)         // yStride
Packit 0d464f
                  );
Packit 0d464f
                  
Packit 0d464f
        fb.insert ("H",                                       // name
Packit 0d464f
                   Slice (IMF::HALF,                          // type
Packit 0d464f
                          (char *) &ph1[-yOffset][-xOffset],  // base
Packit 0d464f
                          sizeof (ph1[0][0]),                 // xStride
Packit 0d464f
                          sizeof (ph1[0][0]) * width)         // yStride
Packit 0d464f
                  );
Packit 0d464f
                  
Packit 0d464f
        fb.insert ("F",                                       // name
Packit 0d464f
                   Slice (IMF::FLOAT,                              // type
Packit 0d464f
                          (char *) &pf1[-yOffset][-xOffset],  // base
Packit 0d464f
                          sizeof (pf1[0][0]),                 // xStride
Packit 0d464f
                          sizeof (pf1[0][0]) * width)         // yStride
Packit 0d464f
                  );
Packit 0d464f
Packit 0d464f
        cout << " writing" << flush;
Packit 0d464f
Packit 0d464f
        remove (fileName);
Packit 0d464f
        TiledOutputFile out (fileName, hdr);
Packit 0d464f
        out.setFrameBuffer (fb);
Packit 0d464f
        
Packit 0d464f
        int startTileY = -1;
Packit 0d464f
	int endTileY = -1;
Packit 0d464f
        int dy;
Packit 0d464f
Packit 0d464f
        switch (mode)
Packit 0d464f
        {
Packit 0d464f
          case ONE_LEVEL:
Packit 0d464f
          {
Packit 0d464f
            if (lorder == DECREASING_Y)
Packit 0d464f
            {
Packit 0d464f
                startTileY = out.numYTiles() - 1;
Packit 0d464f
                endTileY = -1;
Packit 0d464f
Packit 0d464f
                dy = -1;
Packit 0d464f
            }        
Packit 0d464f
            else
Packit 0d464f
            {
Packit 0d464f
                startTileY = 0;
Packit 0d464f
                endTileY = out.numYTiles();
Packit 0d464f
Packit 0d464f
                dy = 1;
Packit 0d464f
            }
Packit 0d464f
Packit 0d464f
            for (int tileY = startTileY; tileY != endTileY; tileY += dy)
Packit 0d464f
                for (int tileX = 0; tileX < out.numXTiles(); ++tileX)         
Packit 0d464f
                    out.writeTile (tileX, tileY);
Packit 0d464f
          }
Packit 0d464f
          break;
Packit 0d464f
Packit 0d464f
          case MIPMAP_LEVELS:
Packit 0d464f
          {
Packit 0d464f
            if (lorder == DECREASING_Y)
Packit 0d464f
            {
Packit 0d464f
                endTileY = -1;
Packit 0d464f
                dy = -1;
Packit 0d464f
            }        
Packit 0d464f
            else
Packit 0d464f
            {
Packit 0d464f
                startTileY = 0;
Packit 0d464f
                dy = 1;
Packit 0d464f
            }
Packit 0d464f
Packit 0d464f
            for (int level = 0; level < out.numLevels(); ++level)
Packit 0d464f
            {
Packit 0d464f
                if (lorder == DECREASING_Y)
Packit 0d464f
                    startTileY = out.numYTiles(level) - 1;
Packit 0d464f
                else
Packit 0d464f
                    endTileY = out.numYTiles(level);
Packit 0d464f
Packit 0d464f
                for (int tileY = startTileY; tileY != endTileY; tileY += dy)
Packit 0d464f
                    for (int tileX = 0; tileX < out.numXTiles(level); ++tileX)
Packit 0d464f
                        out.writeTile (tileX, tileY, level);
Packit 0d464f
            }
Packit 0d464f
          }
Packit 0d464f
          break;
Packit 0d464f
          
Packit 0d464f
          case RIPMAP_LEVELS:
Packit 0d464f
          {
Packit 0d464f
            for (int ylevel = 0; ylevel < out.numYLevels(); ++ylevel)
Packit 0d464f
            {               
Packit 0d464f
                if (lorder == DECREASING_Y)
Packit 0d464f
                {
Packit 0d464f
                    startTileY = out.numYTiles(ylevel) - 1;
Packit 0d464f
                    endTileY = -1;
Packit 0d464f
Packit 0d464f
                    dy = -1;
Packit 0d464f
                }        
Packit 0d464f
                else
Packit 0d464f
                {
Packit 0d464f
                    startTileY = 0;
Packit 0d464f
                    endTileY = out.numYTiles(ylevel);
Packit 0d464f
Packit 0d464f
                    dy = 1;
Packit 0d464f
                }
Packit 0d464f
Packit 0d464f
                for (int xlevel = 0; xlevel < out.numXLevels(); ++xlevel)
Packit 0d464f
                {
Packit 0d464f
                    for (int tileY = startTileY; tileY != endTileY;
Packit 0d464f
                         tileY += dy)
Packit 0d464f
                        for (int tileX = 0; tileX < out.numXTiles (xlevel);
Packit 0d464f
                             ++tileX)
Packit 0d464f
                            out.writeTile (tileX, tileY, xlevel, ylevel);
Packit 0d464f
                }
Packit 0d464f
            }
Packit 0d464f
          }
Packit 0d464f
          break;
Packit 0d464f
        }
Packit 0d464f
    }
Packit 0d464f
Packit 0d464f
    {
Packit 0d464f
        cout << " reading INCREASING_Y" << flush;
Packit 0d464f
Packit 0d464f
        InputFile in (fileName);
Packit 0d464f
Packit 0d464f
        const Box2i &dw = in.header().dataWindow();
Packit 0d464f
        int w = dw.max.x - dw.min.x + 1;
Packit 0d464f
        int h = dw.max.y - dw.min.y + 1;
Packit 0d464f
        int dwx = dw.min.x;
Packit 0d464f
        int dwy = dw.min.y;
Packit 0d464f
Packit 0d464f
        Array2D<unsigned int> pi2 (h, w);
Packit 0d464f
        Array2D<half>         ph2 (h, w);
Packit 0d464f
        Array2D<float>        pf2 (h, w);
Packit 0d464f
Packit 0d464f
        FrameBuffer fb;
Packit 0d464f
Packit 0d464f
        fb.insert ("I",                             // name
Packit 0d464f
                   Slice (IMF::UINT,                // type
Packit 0d464f
                          (char *) &pi2[-dwy][-dwx],// base
Packit 0d464f
                          sizeof (pi2[0][0]),       // xStride
Packit 0d464f
                          sizeof (pi2[0][0]) * w)   // yStride
Packit 0d464f
                  );
Packit 0d464f
Packit 0d464f
        fb.insert ("H",                             // name
Packit 0d464f
                   Slice (IMF::HALF,                // type
Packit 0d464f
                          (char *) &ph2[-dwy][-dwx],// base
Packit 0d464f
                          sizeof (ph2[0][0]),       // xStride
Packit 0d464f
                          sizeof (ph2[0][0]) * w)   // yStride
Packit 0d464f
                  );
Packit 0d464f
Packit 0d464f
        fb.insert ("F",                             // name
Packit 0d464f
                   Slice (IMF::FLOAT,               // type
Packit 0d464f
                          (char *) &pf2[-dwy][-dwx],// base
Packit 0d464f
                          sizeof (pf2[0][0]),       // xStride
Packit 0d464f
                          sizeof (pf2[0][0]) * w)   // yStride
Packit 0d464f
                  );
Packit 0d464f
Packit 0d464f
        in.setFrameBuffer (fb);
Packit 0d464f
        for (int y = dw.min.y; y <= dw.max.y; ++y)
Packit 0d464f
            in.readPixels (y);
Packit 0d464f
Packit 0d464f
        cout << " comparing" << flush;
Packit 0d464f
Packit 0d464f
        assert (in.header().displayWindow() == hdr.displayWindow());
Packit 0d464f
        assert (in.header().dataWindow() == hdr.dataWindow());
Packit 0d464f
        assert (in.header().pixelAspectRatio() == hdr.pixelAspectRatio());
Packit 0d464f
        assert (in.header().screenWindowCenter() == hdr.screenWindowCenter());
Packit 0d464f
        assert (in.header().screenWindowWidth() == hdr.screenWindowWidth());
Packit 0d464f
        assert (in.header().lineOrder() == hdr.lineOrder());
Packit 0d464f
        assert (in.header().compression() == hdr.compression());
Packit 0d464f
Packit 0d464f
        ChannelList::ConstIterator hi = hdr.channels().begin();
Packit 0d464f
        ChannelList::ConstIterator ii = in.header().channels().begin();
Packit 0d464f
Packit 0d464f
        while (hi != hdr.channels().end())
Packit 0d464f
        {
Packit 0d464f
            assert (!strcmp (hi.name(), ii.name()));
Packit 0d464f
            assert (hi.channel().type == ii.channel().type);
Packit 0d464f
            assert (hi.channel().xSampling == ii.channel().xSampling);
Packit 0d464f
            assert (hi.channel().ySampling == ii.channel().ySampling);
Packit 0d464f
Packit 0d464f
            ++hi;
Packit 0d464f
            ++ii;
Packit 0d464f
        }
Packit 0d464f
Packit 0d464f
        assert (ii == in.header().channels().end());
Packit 0d464f
Packit 0d464f
        for (int y = 0; y < h; ++y)
Packit 0d464f
        {
Packit 0d464f
            for (int x = 0; x < w; ++x)
Packit 0d464f
            {
Packit 0d464f
                assert (pi1[y][x] == pi2[y][x]);
Packit 0d464f
                assert (ph1[y][x] == ph2[y][x]);
Packit 0d464f
                assert (pf1[y][x] == pf2[y][x]);
Packit 0d464f
            }
Packit 0d464f
        }    
Packit 0d464f
    }
Packit 0d464f
Packit 0d464f
    {
Packit 0d464f
        cout << endl << "         reading DECREASING_Y" << flush;
Packit 0d464f
Packit 0d464f
        InputFile in (fileName);
Packit 0d464f
Packit 0d464f
        const Box2i &dw = in.header().dataWindow();
Packit 0d464f
        int w = dw.max.x - dw.min.x + 1;
Packit 0d464f
        int h = dw.max.y - dw.min.y + 1;
Packit 0d464f
        int dwx = dw.min.x;
Packit 0d464f
        int dwy = dw.min.y;
Packit 0d464f
Packit 0d464f
        Array2D<unsigned int> pi2 (h, w);
Packit 0d464f
        Array2D<half>         ph2 (h, w);
Packit 0d464f
        Array2D<float>        pf2 (h, w);
Packit 0d464f
Packit 0d464f
        FrameBuffer fb;
Packit 0d464f
Packit 0d464f
        fb.insert ("I",                             // name
Packit 0d464f
                   Slice (IMF::UINT,                // type
Packit 0d464f
                          (char *) &pi2[-dwy][-dwx],// base
Packit 0d464f
                          sizeof (pi2[0][0]),       // xStride
Packit 0d464f
                          sizeof (pi2[0][0]) * w)   // yStride
Packit 0d464f
                  );
Packit 0d464f
Packit 0d464f
        fb.insert ("H",                             // name
Packit 0d464f
                   Slice (IMF::HALF,                // type
Packit 0d464f
                          (char *) &ph2[-dwy][-dwx],// base
Packit 0d464f
                          sizeof (ph2[0][0]),       // xStride
Packit 0d464f
                          sizeof (ph2[0][0]) * w)   // yStride
Packit 0d464f
                  );
Packit 0d464f
Packit 0d464f
        fb.insert ("F",                             // name
Packit 0d464f
                   Slice (IMF::FLOAT,               // type
Packit 0d464f
                          (char *) &pf2[-dwy][-dwx],// base
Packit 0d464f
                          sizeof (pf2[0][0]),       // xStride
Packit 0d464f
                          sizeof (pf2[0][0]) * w)   // yStride
Packit 0d464f
                  );
Packit 0d464f
Packit 0d464f
        in.setFrameBuffer (fb);
Packit 0d464f
        for (int y = dw.max.y; y >= dw.min.y; --y)
Packit 0d464f
            in.readPixels (y);
Packit 0d464f
Packit 0d464f
        cout << " comparing" << flush;
Packit 0d464f
Packit 0d464f
        assert (in.header().displayWindow() == hdr.displayWindow());
Packit 0d464f
        assert (in.header().dataWindow() == hdr.dataWindow());
Packit 0d464f
        assert (in.header().pixelAspectRatio() == hdr.pixelAspectRatio());
Packit 0d464f
        assert (in.header().screenWindowCenter() == hdr.screenWindowCenter());
Packit 0d464f
        assert (in.header().screenWindowWidth() == hdr.screenWindowWidth());
Packit 0d464f
        assert (in.header().lineOrder() == hdr.lineOrder());
Packit 0d464f
        assert (in.header().compression() == hdr.compression());
Packit 0d464f
Packit 0d464f
        ChannelList::ConstIterator hi = hdr.channels().begin();
Packit 0d464f
        ChannelList::ConstIterator ii = in.header().channels().begin();
Packit 0d464f
Packit 0d464f
        while (hi != hdr.channels().end())
Packit 0d464f
        {
Packit 0d464f
            assert (!strcmp (hi.name(), ii.name()));
Packit 0d464f
            assert (hi.channel().type == ii.channel().type);
Packit 0d464f
            assert (hi.channel().xSampling == ii.channel().xSampling);
Packit 0d464f
            assert (hi.channel().ySampling == ii.channel().ySampling);
Packit 0d464f
Packit 0d464f
            ++hi;
Packit 0d464f
            ++ii;
Packit 0d464f
        }
Packit 0d464f
Packit 0d464f
        assert (ii == in.header().channels().end());
Packit 0d464f
Packit 0d464f
        for (int y = 0; y < h; ++y)
Packit 0d464f
        {
Packit 0d464f
            for (int x = 0; x < w; ++x)
Packit 0d464f
            {
Packit 0d464f
                assert (pi1[y][x] == pi2[y][x]);
Packit 0d464f
                assert (ph1[y][x] == ph2[y][x]);
Packit 0d464f
                assert (pf1[y][x] == pf2[y][x]);
Packit 0d464f
            }
Packit 0d464f
        }
Packit 0d464f
    }
Packit 0d464f
Packit 0d464f
    {
Packit 0d464f
        cout << endl << "         reading INCREASING_Y "
Packit 0d464f
		        "(new frame buffer on every line)" << flush;
Packit 0d464f
Packit 0d464f
        InputFile in (fileName);
Packit 0d464f
Packit 0d464f
        const Box2i &dw = in.header().dataWindow();
Packit 0d464f
        int w = dw.max.x - dw.min.x + 1;
Packit 0d464f
        int h = dw.max.y - dw.min.y + 1;
Packit 0d464f
        int dwx = dw.min.x;
Packit 0d464f
        int dwy = dw.min.y;
Packit 0d464f
Packit 0d464f
        Array2D<unsigned int> pi2 (h, w);
Packit 0d464f
        Array2D<half>         ph2 (h, w);
Packit 0d464f
        Array2D<float>        pf2 (h, w);
Packit 0d464f
Packit 0d464f
        for (int y = dw.min.y; y <= dw.max.y; ++y)
Packit 0d464f
	{
Packit 0d464f
	    FrameBuffer fb;
Packit 0d464f
Packit 0d464f
	    fb.insert ("I",					// name
Packit 0d464f
		       Slice (IMF::UINT,			// type
Packit 0d464f
			      (char *) &pi2[y - dwy][-dwx],	// base
Packit 0d464f
			      sizeof (pi2[0][0]),		// xStride
Packit 0d464f
			      0)				// yStride
Packit 0d464f
		      );
Packit 0d464f
Packit 0d464f
	    fb.insert ("H",					// name
Packit 0d464f
		       Slice (IMF::HALF,			// type
Packit 0d464f
			      (char *) &ph2[y - dwy][-dwx],	// base
Packit 0d464f
			      sizeof (ph2[0][0]),		// xStride
Packit 0d464f
			      0)				// yStride
Packit 0d464f
		      );
Packit 0d464f
Packit 0d464f
	    fb.insert ("F",                     	        // name
Packit 0d464f
		       Slice (IMF::FLOAT,			// type
Packit 0d464f
			      (char *) &pf2[y - dwy][-dwx],	// base
Packit 0d464f
			      sizeof (pf2[0][0]),		// xStride
Packit 0d464f
			      0)				// yStride
Packit 0d464f
		      );
Packit 0d464f
Packit 0d464f
	    in.setFrameBuffer (fb);
Packit 0d464f
            in.readPixels (y);
Packit 0d464f
	}
Packit 0d464f
Packit 0d464f
        cout << " comparing" << flush;
Packit 0d464f
Packit 0d464f
        assert (in.header().displayWindow() == hdr.displayWindow());
Packit 0d464f
        assert (in.header().dataWindow() == hdr.dataWindow());
Packit 0d464f
        assert (in.header().pixelAspectRatio() == hdr.pixelAspectRatio());
Packit 0d464f
        assert (in.header().screenWindowCenter() == hdr.screenWindowCenter());
Packit 0d464f
        assert (in.header().screenWindowWidth() == hdr.screenWindowWidth());
Packit 0d464f
        assert (in.header().lineOrder() == hdr.lineOrder());
Packit 0d464f
        assert (in.header().compression() == hdr.compression());
Packit 0d464f
Packit 0d464f
        ChannelList::ConstIterator hi = hdr.channels().begin();
Packit 0d464f
        ChannelList::ConstIterator ii = in.header().channels().begin();
Packit 0d464f
Packit 0d464f
        while (hi != hdr.channels().end())
Packit 0d464f
        {
Packit 0d464f
            assert (!strcmp (hi.name(), ii.name()));
Packit 0d464f
            assert (hi.channel().type == ii.channel().type);
Packit 0d464f
            assert (hi.channel().xSampling == ii.channel().xSampling);
Packit 0d464f
            assert (hi.channel().ySampling == ii.channel().ySampling);
Packit 0d464f
Packit 0d464f
            ++hi;
Packit 0d464f
            ++ii;
Packit 0d464f
        }
Packit 0d464f
Packit 0d464f
        assert (ii == in.header().channels().end());
Packit 0d464f
Packit 0d464f
        for (int y = 0; y < h; ++y)
Packit 0d464f
        {
Packit 0d464f
            for (int x = 0; x < w; ++x)
Packit 0d464f
            {
Packit 0d464f
                assert (pi1[y][x] == pi2[y][x]);
Packit 0d464f
                assert (ph1[y][x] == ph2[y][x]);
Packit 0d464f
                assert (pf1[y][x] == pf2[y][x]);
Packit 0d464f
            }
Packit 0d464f
        }    
Packit 0d464f
    }
Packit 0d464f
Packit 0d464f
    remove (fileName);
Packit 0d464f
    cout << endl;
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
writeRead (const std::string &tempDir,
Packit 0d464f
           const Array2D<unsigned int> &pi,
Packit 0d464f
           const Array2D<half> &ph,
Packit 0d464f
           const Array2D<float> &pf,
Packit 0d464f
           int W,
Packit 0d464f
           int H,
Packit 0d464f
           LineOrder lorder,
Packit 0d464f
           Compression comp,
Packit 0d464f
	   LevelRoundingMode rmode,
Packit 0d464f
           int dx, int dy,
Packit 0d464f
           int xSize, int ySize)
Packit 0d464f
{
Packit 0d464f
    std::string filename = tempDir + "imf_test_scanline_api.exr";
Packit 0d464f
Packit 0d464f
    writeRead (pi, ph, pf, filename.c_str(), lorder, W, H,
Packit 0d464f
               xSize, ySize, dx, dy, comp, ONE_LEVEL, rmode);
Packit 0d464f
    writeRead (pi, ph, pf, filename.c_str(), lorder, W, H,
Packit 0d464f
               xSize, ySize, dx, dy, comp, MIPMAP_LEVELS, rmode);
Packit 0d464f
    writeRead (pi, ph, pf, filename.c_str(), lorder, W, H,
Packit 0d464f
               xSize, ySize, dx, dy, comp, RIPMAP_LEVELS, rmode);
Packit 0d464f
}
Packit 0d464f
Packit 0d464f
} // namespace
Packit 0d464f
Packit 0d464f
Packit 0d464f
void
Packit 0d464f
testScanLineApi (const std::string &tempDir)
Packit 0d464f
{
Packit 0d464f
    try
Packit 0d464f
    {
Packit 0d464f
        cout << "Testing the scanline API for tiled files" << endl;
Packit 0d464f
Packit 0d464f
        const int W = 48;
Packit 0d464f
        const int H = 81;
Packit 0d464f
        const int DX = -17;
Packit 0d464f
        const int DY = -29;
Packit 0d464f
        
Packit 0d464f
        Array2D<unsigned int> pi (H, W);
Packit 0d464f
        Array2D<half> ph (H, W);
Packit 0d464f
        Array2D<float> pf (H, W);
Packit 0d464f
        fillPixels (pi, ph, pf, W, H);
Packit 0d464f
Packit 0d464f
	int maxThreads = ILMTHREAD_NAMESPACE::supportsThreads()? 3: 0;
Packit 0d464f
Packit 0d464f
	for (int n = 0; n <= maxThreads; ++n)
Packit 0d464f
	{
Packit 0d464f
	    if (ILMTHREAD_NAMESPACE::supportsThreads())
Packit 0d464f
	    {
Packit 0d464f
		setGlobalThreadCount (n);
Packit 0d464f
		cout << "\nnumber of threads: " << globalThreadCount() << endl;
Packit 0d464f
	    }
Packit 0d464f
Packit 0d464f
	    for (int lorder = 0; lorder < NUM_LINEORDERS; ++lorder)
Packit 0d464f
	    {
Packit 0d464f
		for (int rmode = 0; rmode < NUM_ROUNDINGMODES; ++rmode)
Packit 0d464f
		{
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf,  W, H, 
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       0, 0, 1, 1);
Packit 0d464f
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf, W, H, 
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       DX, DY, 1, 1);
Packit 0d464f
		    
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf, W, H,
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       0, 0, 24, 26);
Packit 0d464f
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf, W, H,
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       DX, DY, 24, 26);
Packit 0d464f
		    
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf, W, H,
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       0, 0, 48, 81);
Packit 0d464f
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf, W, H,
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       DX, DY, 48, 81);
Packit 0d464f
			       
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf, W, H,
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       0, 0, 128, 96);
Packit 0d464f
Packit 0d464f
		    writeRead (tempDir, pi, ph, pf, W, H,
Packit 0d464f
			       LineOrder (lorder),
Packit 0d464f
			       ZIP_COMPRESSION,
Packit 0d464f
			       LevelRoundingMode (rmode),
Packit 0d464f
			       DX, DY, 128, 96);
Packit 0d464f
		}
Packit 0d464f
	    }
Packit 0d464f
	}
Packit 0d464f
Packit 0d464f
        cout << "ok\n" << endl;
Packit 0d464f
    }
Packit 0d464f
    catch (const std::exception &e)
Packit 0d464f
    {
Packit 0d464f
        cerr << "ERROR -- caught exception: " << e.what() << endl;
Packit 0d464f
        assert (false);
Packit 0d464f
    }
Packit 0d464f
}