Blame IlmImf/ImfTileOffsets.cpp

Packit Service 6754ca
///////////////////////////////////////////////////////////////////////////
Packit Service 6754ca
//
Packit Service 6754ca
// Copyright (c) 2004, 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
//	class TileOffsets
Packit Service 6754ca
//
Packit Service 6754ca
//-----------------------------------------------------------------------------
Packit Service 6754ca
Packit Service 6754ca
#include <ImfTileOffsets.h>
Packit Service 6754ca
#include <ImfXdr.h>
Packit Service 6754ca
#include <ImfIO.h>
Packit Service 6754ca
#include "Iex.h"
Packit Service 6754ca
#include "ImfNamespace.h"
Packit Service 6754ca
#include <algorithm>
Packit Service 6754ca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_ENTER
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
TileOffsets::TileOffsets (LevelMode mode,
Packit Service 6754ca
			  int numXLevels, int numYLevels,
Packit Service 6754ca
			  const int *numXTiles, const int *numYTiles)
Packit Service 6754ca
:
Packit Service 6754ca
    _mode (mode),
Packit Service 6754ca
    _numXLevels (numXLevels),
Packit Service 6754ca
    _numYLevels (numYLevels)
Packit Service 6754ca
{
Packit Service 6754ca
    switch (_mode)
Packit Service 6754ca
    {
Packit Service 6754ca
      case ONE_LEVEL:
Packit Service 6754ca
      case MIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        _offsets.resize (_numXLevels);
Packit Service 6754ca
Packit Service 6754ca
        for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
        {
Packit Service 6754ca
            _offsets[l].resize (numYTiles[l]);
Packit Service 6754ca
Packit Service 6754ca
            for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
	    {
Packit Service 6754ca
                _offsets[l][dy].resize (numXTiles[l]);
Packit Service 6754ca
            }
Packit Service 6754ca
        }
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case RIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        _offsets.resize (_numXLevels * _numYLevels);
Packit Service 6754ca
Packit Service 6754ca
        for (int ly = 0; ly < _numYLevels; ++ly)
Packit Service 6754ca
        {
Packit Service 6754ca
            for (int lx = 0; lx < _numXLevels; ++lx)
Packit Service 6754ca
            {
Packit Service 6754ca
                int l = ly * _numXLevels + lx;
Packit Service 6754ca
                _offsets[l].resize (numYTiles[ly]);
Packit Service 6754ca
Packit Service 6754ca
                for (size_t dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
                {
Packit Service 6754ca
                    _offsets[l][dy].resize (numXTiles[lx]);
Packit Service 6754ca
                }
Packit Service 6754ca
            }
Packit Service 6754ca
        }
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case NUM_LEVELMODES :
Packit Service 6754ca
          throw IEX_NAMESPACE::ArgExc("Bad initialisation of TileOffsets object");
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
bool
Packit Service 6754ca
TileOffsets::anyOffsetsAreInvalid () const
Packit Service 6754ca
{
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
	for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
	    for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
Packit Service 6754ca
		if (_offsets[l][dy][dx] <= 0)
Packit Service 6754ca
		    return true;
Packit Service 6754ca
    
Packit Service 6754ca
    return false;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
TileOffsets::findTiles (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool isMultiPartFile, bool isDeep, bool skipOnly)
Packit Service 6754ca
{
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
    {
Packit Service 6754ca
	for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
	{
Packit Service 6754ca
	    for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
Packit Service 6754ca
	    {
Packit Service 6754ca
		Int64 tileOffset = is.tellg();
Packit Service 6754ca
Packit Service 6754ca
		if (isMultiPartFile)
Packit Service 6754ca
		{
Packit Service 6754ca
		    int partNumber;
Packit Service 6754ca
		    OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, partNumber);
Packit Service 6754ca
		}
Packit Service 6754ca
Packit Service 6754ca
		int tileX;
Packit Service 6754ca
		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tileX);
Packit Service 6754ca
Packit Service 6754ca
		int tileY;
Packit Service 6754ca
		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, tileY);
Packit Service 6754ca
Packit Service 6754ca
		int levelX;
Packit Service 6754ca
		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelX);
Packit Service 6754ca
Packit Service 6754ca
		int levelY;
Packit Service 6754ca
		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, levelY);
Packit Service 6754ca
Packit Service 6754ca
                if(isDeep)
Packit Service 6754ca
                {
Packit Service 6754ca
                     Int64 packed_offset_table_size;
Packit Service 6754ca
                     Int64 packed_sample_size;
Packit Service 6754ca
                     
Packit Service 6754ca
                     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_offset_table_size);
Packit Service 6754ca
                     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, packed_sample_size);
Packit Service 6754ca
                     
Packit Service 6754ca
                     // next Int64 is unpacked sample size - skip that too
Packit Service 6754ca
                     Xdr::skip <StreamIO> (is, packed_offset_table_size+packed_sample_size+8);
Packit Service 6754ca
                    
Packit Service 6754ca
                }else{
Packit Service 6754ca
                    
Packit Service 6754ca
		     int dataSize;
Packit Service 6754ca
		     OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, dataSize);
Packit Service 6754ca
Packit Service 6754ca
		     Xdr::skip <StreamIO> (is, dataSize);
Packit Service 6754ca
                }
Packit Service 6754ca
		if (skipOnly) continue;
Packit Service 6754ca
Packit Service 6754ca
		if (!isValidTile(tileX, tileY, levelX, levelY))
Packit Service 6754ca
		    return;
Packit Service 6754ca
Packit Service 6754ca
		operator () (tileX, tileY, levelX, levelY) = tileOffset;
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
TileOffsets::reconstructFromFile (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is,bool isMultiPart,bool isDeep)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Try to reconstruct a missing tile offset table by sequentially
Packit Service 6754ca
    // scanning through the file, and recording the offsets in the file
Packit Service 6754ca
    // of the tiles we find.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    Int64 position = is.tellg();
Packit Service 6754ca
Packit Service 6754ca
    try
Packit Service 6754ca
    {
Packit Service 6754ca
	findTiles (is,isMultiPart,isDeep,false);
Packit Service 6754ca
    }
Packit Service 6754ca
    catch (...)
Packit Service 6754ca
    {
Packit Service 6754ca
        //
Packit Service 6754ca
        // Suppress all exceptions.  This function is called only to
Packit Service 6754ca
	// reconstruct the tile offset table for incomplete files,
Packit Service 6754ca
	// and exceptions are likely.
Packit Service 6754ca
        //
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    is.clear();
Packit Service 6754ca
    is.seekg (position);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
TileOffsets::readFrom (OPENEXR_IMF_INTERNAL_NAMESPACE::IStream &is, bool &complete,bool isMultiPartFile, bool isDeep)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Read in the tile offsets from the file's tile offset table
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
	for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
	    for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
Packit Service 6754ca
		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::read <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (is, _offsets[l][dy][dx]);
Packit Service 6754ca
Packit Service 6754ca
    //
Packit Service 6754ca
    // Check if any tile offsets are invalid.
Packit Service 6754ca
    //
Packit Service 6754ca
    // Invalid offsets mean that the file is probably incomplete
Packit Service 6754ca
    // (the offset table is the last thing written to the file).
Packit Service 6754ca
    // Either some process is still busy writing the file, or
Packit Service 6754ca
    // writing the file was aborted.
Packit Service 6754ca
    //
Packit Service 6754ca
    // We should still be able to read the existing parts of the
Packit Service 6754ca
    // file.  In order to do this, we have to make a sequential
Packit Service 6754ca
    // scan over the scan tile to reconstruct the tile offset
Packit Service 6754ca
    // table.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    if (anyOffsetsAreInvalid())
Packit Service 6754ca
    {
Packit Service 6754ca
	complete = false;
Packit Service 6754ca
	reconstructFromFile (is,isMultiPartFile,isDeep);
Packit Service 6754ca
    }
Packit Service 6754ca
    else
Packit Service 6754ca
    {
Packit Service 6754ca
	complete = true;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
void
Packit Service 6754ca
TileOffsets::readFrom (std::vector<Int64> chunkOffsets,bool &complete)
Packit Service 6754ca
{
Packit Service 6754ca
    size_t totalSize = 0;
Packit Service 6754ca
 
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
            totalSize += _offsets[l][dy].size();
Packit Service 6754ca
Packit Service 6754ca
    if (chunkOffsets.size() != totalSize)
Packit Service 6754ca
        throw IEX_NAMESPACE::ArgExc ("Wrong offset count, not able to read from this array");
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
    int pos = 0;
Packit Service 6754ca
    for (size_t l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
        for (size_t dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
            for (size_t dx = 0; dx < _offsets[l][dy].size(); ++dx)
Packit Service 6754ca
            {
Packit Service 6754ca
                _offsets[l][dy][dx] = chunkOffsets[pos];
Packit Service 6754ca
                pos++;
Packit Service 6754ca
            }
Packit Service 6754ca
Packit Service 6754ca
    complete = !anyOffsetsAreInvalid();
Packit Service 6754ca
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Int64
Packit Service 6754ca
TileOffsets::writeTo (OPENEXR_IMF_INTERNAL_NAMESPACE::OStream &os) const
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Write the tile offset table to the file, and
Packit Service 6754ca
    // return the position of the start of the table
Packit Service 6754ca
    // in the file.
Packit Service 6754ca
    //
Packit Service 6754ca
    
Packit Service 6754ca
    Int64 pos = os.tellp();
Packit Service 6754ca
Packit Service 6754ca
    if (pos == -1)
Packit Service 6754ca
	IEX_NAMESPACE::throwErrnoExc ("Cannot determine current file position (%T).");
Packit Service 6754ca
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
	for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
	    for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
Packit Service 6754ca
		OPENEXR_IMF_INTERNAL_NAMESPACE::Xdr::write <OPENEXR_IMF_INTERNAL_NAMESPACE::StreamIO> (os, _offsets[l][dy][dx]);
Packit Service 6754ca
Packit Service 6754ca
    return pos;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
namespace {
Packit Service 6754ca
struct tilepos{
Packit Service 6754ca
    Int64 filePos;
Packit Service 6754ca
    int dx;
Packit Service 6754ca
    int dy;
Packit Service 6754ca
    int l;
Packit Service 6754ca
    bool operator <(const tilepos & other) const
Packit Service 6754ca
    {
Packit Service 6754ca
        return filePos < other.filePos;
Packit Service 6754ca
    }
Packit Service 6754ca
};
Packit Service 6754ca
}
Packit Service 6754ca
//-------------------------------------
Packit Service 6754ca
// fill array with tile coordinates in the order they appear in the file
Packit Service 6754ca
//
Packit Service 6754ca
// each input array must be of size (totalTiles)
Packit Service 6754ca
// 
Packit Service 6754ca
//
Packit Service 6754ca
// if the tile order is not RANDOM_Y, it is more efficient to compute the
Packit Service 6754ca
// tile ordering rather than using this function
Packit Service 6754ca
//
Packit Service 6754ca
//-------------------------------------
Packit Service 6754ca
void TileOffsets::getTileOrder(int dx_table[],int dy_table[],int lx_table[],int ly_table[]) const
Packit Service 6754ca
{
Packit Service 6754ca
    // 
Packit Service 6754ca
    // helper class
Packit Service 6754ca
    // 
Packit Service 6754ca
Packit Service 6754ca
    // how many entries?
Packit Service 6754ca
    size_t entries=0;
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
           entries+=_offsets[l][dy].size();
Packit Service 6754ca
        
Packit Service 6754ca
    std::vector<struct tilepos> table(entries);
Packit Service 6754ca
    
Packit Service 6754ca
    size_t i = 0;
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
        for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
            for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
Packit Service 6754ca
            {
Packit Service 6754ca
                table[i].filePos = _offsets[l][dy][dx];
Packit Service 6754ca
                table[i].dx = dx;
Packit Service 6754ca
                table[i].dy = dy;
Packit Service 6754ca
                table[i].l = l;
Packit Service 6754ca
Packit Service 6754ca
                ++i;
Packit Service 6754ca
                
Packit Service 6754ca
            }
Packit Service 6754ca
              
Packit Service 6754ca
    std::sort(table.begin(),table.end());
Packit Service 6754ca
    
Packit Service 6754ca
    //
Packit Service 6754ca
    // write out the values
Packit Service 6754ca
    //
Packit Service 6754ca
    
Packit Service 6754ca
    // pass 1: write out dx and dy, since these are independent of level mode
Packit Service 6754ca
    
Packit Service 6754ca
    for(size_t i=0;i
Packit Service 6754ca
    {
Packit Service 6754ca
        dx_table[i] = table[i].dx;
Packit Service 6754ca
        dy_table[i] = table[i].dy;
Packit Service 6754ca
    }
Packit Service 6754ca
Packit Service 6754ca
    // now write out the levels, which depend on the level mode
Packit Service 6754ca
    
Packit Service 6754ca
    switch (_mode)
Packit Service 6754ca
    {
Packit Service 6754ca
        case ONE_LEVEL:
Packit Service 6754ca
        {
Packit Service 6754ca
            for(size_t i=0;i
Packit Service 6754ca
            {
Packit Service 6754ca
                lx_table[i] = 0;
Packit Service 6754ca
                ly_table[i] = 0;               
Packit Service 6754ca
            }
Packit Service 6754ca
            break;            
Packit Service 6754ca
        }
Packit Service 6754ca
        case MIPMAP_LEVELS:
Packit Service 6754ca
        {
Packit Service 6754ca
            for(size_t i=0;i
Packit Service 6754ca
            {
Packit Service 6754ca
                lx_table[i]= table[i].l;
Packit Service 6754ca
                ly_table[i] =table[i].l;               
Packit Service 6754ca
                
Packit Service 6754ca
            }
Packit Service 6754ca
            break;
Packit Service 6754ca
        }
Packit Service 6754ca
            
Packit Service 6754ca
        case RIPMAP_LEVELS:
Packit Service 6754ca
        {
Packit Service 6754ca
            for(size_t i=0;i
Packit Service 6754ca
            {
Packit Service 6754ca
                lx_table[i]= table[i].l % _numXLevels;
Packit Service 6754ca
                ly_table[i] = table[i].l / _numXLevels; 
Packit Service 6754ca
                
Packit Service 6754ca
            }
Packit Service 6754ca
            break;
Packit Service 6754ca
        }
Packit Service 6754ca
        case NUM_LEVELMODES :
Packit Service 6754ca
            throw IEX_NAMESPACE::LogicExc("Bad level mode getting tile order");
Packit Service 6754ca
    }
Packit Service 6754ca
    
Packit Service 6754ca
    
Packit Service 6754ca
    
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
bool
Packit Service 6754ca
TileOffsets::isEmpty () const
Packit Service 6754ca
{
Packit Service 6754ca
    for (unsigned int l = 0; l < _offsets.size(); ++l)
Packit Service 6754ca
	for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
Packit Service 6754ca
	    for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
Packit Service 6754ca
		if (_offsets[l][dy][dx] != 0)
Packit Service 6754ca
		    return false;
Packit Service 6754ca
    return true;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
bool
Packit Service 6754ca
TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
Packit Service 6754ca
{
Packit Service 6754ca
    if(lx<0 || ly < 0 || dx<0 || dy < 0) return false;
Packit Service 6754ca
    switch (_mode)
Packit Service 6754ca
    {
Packit Service 6754ca
      case ONE_LEVEL:
Packit Service 6754ca
Packit Service 6754ca
        if (lx == 0 &&
Packit Service 6754ca
	    ly == 0 &&
Packit Service 6754ca
	    _offsets.size() > 0 &&
Packit Service 6754ca
            int(_offsets[0].size()) > dy &&
Packit Service 6754ca
            int(_offsets[0][dy].size()) > dx)
Packit Service 6754ca
	{
Packit Service 6754ca
            return true;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case MIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        if (lx < _numXLevels &&
Packit Service 6754ca
	    ly < _numYLevels &&
Packit Service 6754ca
            int(_offsets.size()) > lx &&
Packit Service 6754ca
            int(_offsets[lx].size()) > dy &&
Packit Service 6754ca
            int(_offsets[lx][dy].size()) > dx)
Packit Service 6754ca
	{
Packit Service 6754ca
            return true;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case RIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        if (lx < _numXLevels &&
Packit Service 6754ca
	    ly < _numYLevels &&
Packit Service 6754ca
	    (_offsets.size() > (size_t) lx+  ly *  (size_t) _numXLevels) &&
Packit Service 6754ca
            int(_offsets[lx + ly * _numXLevels].size()) > dy &&
Packit Service 6754ca
            int(_offsets[lx + ly * _numXLevels][dy].size()) > dx)
Packit Service 6754ca
	{
Packit Service 6754ca
            return true;
Packit Service 6754ca
	}
Packit Service 6754ca
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      default:
Packit Service 6754ca
Packit Service 6754ca
        return false;
Packit Service 6754ca
    }
Packit Service 6754ca
    
Packit Service 6754ca
    return false;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Int64 &
Packit Service 6754ca
TileOffsets::operator () (int dx, int dy, int lx, int ly)
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Looks up the value of the tile with tile coordinate (dx, dy)
Packit Service 6754ca
    // and level number (lx, ly) in the _offsets array, and returns
Packit Service 6754ca
    // the cooresponding offset.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    switch (_mode)
Packit Service 6754ca
    {
Packit Service 6754ca
      case ONE_LEVEL:
Packit Service 6754ca
Packit Service 6754ca
        return _offsets[0][dy][dx];
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case MIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        return _offsets[lx][dy][dx];
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case RIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        return _offsets[lx + ly * _numXLevels][dy][dx];
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      default:
Packit Service 6754ca
Packit Service 6754ca
        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
Int64 &
Packit Service 6754ca
TileOffsets::operator () (int dx, int dy, int l)
Packit Service 6754ca
{
Packit Service 6754ca
    return operator () (dx, dy, l, l);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
const Int64 &
Packit Service 6754ca
TileOffsets::operator () (int dx, int dy, int lx, int ly) const
Packit Service 6754ca
{
Packit Service 6754ca
    //
Packit Service 6754ca
    // Looks up the value of the tile with tile coordinate (dx, dy)
Packit Service 6754ca
    // and level number (lx, ly) in the _offsets array, and returns
Packit Service 6754ca
    // the cooresponding offset.
Packit Service 6754ca
    //
Packit Service 6754ca
Packit Service 6754ca
    switch (_mode)
Packit Service 6754ca
    {
Packit Service 6754ca
      case ONE_LEVEL:
Packit Service 6754ca
Packit Service 6754ca
        return _offsets[0][dy][dx];
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case MIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        return _offsets[lx][dy][dx];
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      case RIPMAP_LEVELS:
Packit Service 6754ca
Packit Service 6754ca
        return _offsets[lx + ly * _numXLevels][dy][dx];
Packit Service 6754ca
        break;
Packit Service 6754ca
Packit Service 6754ca
      default:
Packit Service 6754ca
Packit Service 6754ca
        throw IEX_NAMESPACE::ArgExc ("Unknown LevelMode format.");
Packit Service 6754ca
    }
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
const Int64 &
Packit Service 6754ca
TileOffsets::operator () (int dx, int dy, int l) const
Packit Service 6754ca
{
Packit Service 6754ca
    return operator () (dx, dy, l, l);
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
const std::vector<std::vector<std::vector <Int64> > >&
Packit Service 6754ca
TileOffsets::getOffsets() const
Packit Service 6754ca
{
Packit Service 6754ca
    return _offsets;
Packit Service 6754ca
}
Packit Service 6754ca
Packit Service 6754ca
Packit Service 6754ca
OPENEXR_IMF_INTERNAL_NAMESPACE_SOURCE_EXIT