This source file includes following definitions.
- _numYLevels
 
- anyOffsetsAreInvalid
 
- findTiles
 
- reconstructFromFile
 
- readFrom
 
- writeTo
 
- isEmpty
 
- isValidTile
 
#include <ImfTileOffsets.h>
#include <ImfXdr.h>
#include <ImfIO.h>
#include "Iex.h"
namespace Imf {
TileOffsets::TileOffsets (LevelMode mode,
              int numXLevels, int numYLevels,
              const int *numXTiles, const int *numYTiles)
:
    _mode (mode),
    _numXLevels (numXLevels),
    _numYLevels (numYLevels)
{
    switch (_mode)
    {
      case ONE_LEVEL:
      case MIPMAP_LEVELS:
        _offsets.resize (_numXLevels);
        for (unsigned int l = 0; l < _offsets.size(); ++l)
        {
            _offsets[l].resize (numYTiles[l]);
            for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
        {
                _offsets[l][dy].resize (numXTiles[l]);
            }
        }
        break;
      case RIPMAP_LEVELS:
        _offsets.resize (_numXLevels * _numYLevels);
        for (unsigned int ly = 0; ly < _numYLevels; ++ly)
        {
            for (unsigned int lx = 0; lx < _numXLevels; ++lx)
            {
                int l = ly * _numXLevels + lx;
                _offsets[l].resize (numYTiles[ly]);
                for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
                {
                    _offsets[l][dy].resize (numXTiles[lx]);
                }
            }
        }
        break;
    }
}
bool
TileOffsets::anyOffsetsAreInvalid () const
{
    for (unsigned int l = 0; l < _offsets.size(); ++l)
    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
        if (_offsets[l][dy][dx] <= 0)
            return true;
    return false;
}
void
TileOffsets::findTiles (IStream &is)
{
    for (unsigned int l = 0; l < _offsets.size(); ++l)
    {
    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
    {
        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
        {
        Int64 tileOffset = is.tellg();
        int tileX;
        Xdr::read <StreamIO> (is, tileX);
        int tileY;
        Xdr::read <StreamIO> (is, tileY);
        int levelX;
        Xdr::read <StreamIO> (is, levelX);
        int levelY;
        Xdr::read <StreamIO> (is, levelY);
        int dataSize;
        Xdr::read <StreamIO> (is, dataSize);
        Xdr::skip <StreamIO> (is, dataSize);
        if (!isValidTile(tileX, tileY, levelX, levelY))
            return;
        operator () (tileX, tileY, levelX, levelY) = tileOffset;
        }
    }
    }
}
void
TileOffsets::reconstructFromFile (IStream &is)
{
    
    
    
    
    
    Int64 position = is.tellg();
    try
    {
    findTiles (is);
    }
    catch (...)
    {
        
        
    
    
        
    }
    is.clear();
    is.seekg (position);
}
void
TileOffsets::readFrom (IStream &is, bool &complete)
{
    
    
    
    for (unsigned int l = 0; l < _offsets.size(); ++l)
    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
        Xdr::read <StreamIO> (is, _offsets[l][dy][dx]);
    
    
    
    
    
    
    
    
    
    
    
    
    
    if (anyOffsetsAreInvalid())
    {
    complete = false;
    reconstructFromFile (is);
    }
    else
    {
    complete = true;
    }
}
Int64
TileOffsets::writeTo (OStream &os) const
{
    
    
    
    
    
    Int64 pos = os.tellp();
    if (pos == -1)
    Iex::throwErrnoExc ("Cannot determine current file position (%T).");
    for (unsigned int l = 0; l < _offsets.size(); ++l)
    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
        Xdr::write <StreamIO> (os, _offsets[l][dy][dx]);
    return pos;
}
bool
TileOffsets::isEmpty () const
{
    for (unsigned int l = 0; l < _offsets.size(); ++l)
    for (unsigned int dy = 0; dy < _offsets[l].size(); ++dy)
        for (unsigned int dx = 0; dx < _offsets[l][dy].size(); ++dx)
        if (_offsets[l][dy][dx] != 0)
            return false;
    return true;
}
bool
TileOffsets::isValidTile (int dx, int dy, int lx, int ly) const
{
    switch (_mode)
    {
      case ONE_LEVEL:
        if (lx == 0 &&
        ly == 0 &&
        _offsets.size() > 0 &&
            _offsets[0].size() > dy &&
            _offsets[0][dy].size() > dx)
    {
            return true;
    }
        break;
      case MIPMAP_LEVELS:
        if (lx < _numXLevels &&
        ly < _numYLevels &&
            _offsets.size() > lx &&
            _offsets[lx].size() > dy &&
            _offsets[lx][dy].size() > dx)
    {
            return true;
    }
        break;
      case RIPMAP_LEVELS:
        if (lx < _numXLevels &&
        ly < _numYLevels &&
            _offsets.size() > lx + ly * _numXLevels &&
            _offsets[lx + ly * _numXLevels].size() > dy &&
            _offsets[lx + ly * _numXLevels][dy].size() > dx)
    {
            return true;
    }
        break;
      default:
        return false;
    }
    return false;
}
Int64 &
TileOffsets::operator () (int dx, int dy, int lx, int ly)
{
    
    
    
    
    
    switch (_mode)
    {
      case ONE_LEVEL:
        return _offsets[0][dy][dx];
        break;
      case MIPMAP_LEVELS:
        return _offsets[lx][dy][dx];
        break;
      case RIPMAP_LEVELS:
        return _offsets[lx + ly * _numXLevels][dy][dx];
        break;
      default:
        throw Iex::ArgExc ("Unknown LevelMode format.");
    }
}
Int64 &
TileOffsets::operator () (int dx, int dy, int l)
{
    return operator () (dx, dy, l, l);
}
const Int64 &
TileOffsets::operator () (int dx, int dy, int lx, int ly) const
{
    
    
    
    
    
    switch (_mode)
    {
      case ONE_LEVEL:
        return _offsets[0][dy][dx];
        break;
      case MIPMAP_LEVELS:
        return _offsets[lx][dy][dx];
        break;
      case RIPMAP_LEVELS:
        return _offsets[lx + ly * _numXLevels][dy][dx];
        break;
      default:
        throw Iex::ArgExc ("Unknown LevelMode format.");
    }
}
const Int64 &
TileOffsets::operator () (int dx, int dy, int l) const
{
    return operator () (dx, dy, l, l);
}
}