⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imftiledinputfile.cpp

📁 image converter source code
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2004, Industrial Light & Magic, a division of Lucas// Digital Ltd. LLC// // All rights reserved.// // Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:// *       Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// *       Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.// *       Neither the name of Industrial Light & Magic nor the names of// its contributors may be used to endorse or promote products derived// from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.///////////////////////////////////////////////////////////////////////////////-----------------------------------------------------------------------------////	class TiledInputFile////-----------------------------------------------------------------------------#include <ImfTiledInputFile.h>#include <ImfTileDescriptionAttribute.h>#include <ImfChannelList.h>#include <ImfMisc.h>#include <ImfTiledMisc.h>#include <ImfStdIO.h>#include <ImfCompressor.h>#include "ImathBox.h"#include <ImfXdr.h>#include <ImfConvert.h>#include <ImfVersion.h>#include <ImfTileOffsets.h>#include <ImfThreading.h>#include "IlmThreadPool.h"#include "IlmThreadSemaphore.h"#include "IlmThreadMutex.h"#include "ImathVec.h"#include "Iex.h"#include <string>#include <vector>#include <algorithm>#include <assert.h>namespace Imf {using Imath::Box2i;using Imath::V2i;using std::string;using std::vector;using std::min;using std::max;using IlmThread::Mutex;using IlmThread::Lock;using IlmThread::Semaphore;using IlmThread::Task;using IlmThread::TaskGroup;using IlmThread::ThreadPool;namespace {struct TInSliceInfo{    PixelType   typeInFrameBuffer;    PixelType   typeInFile;    char *      base;    size_t      xStride;    size_t      yStride;    bool        fill;    bool        skip;    double      fillValue;    int         xTileCoords;    int         yTileCoords;    TInSliceInfo (PixelType typeInFrameBuffer = HALF,                  PixelType typeInFile = HALF,                  char *base = 0,                  size_t xStride = 0,                  size_t yStride = 0,                  bool fill = false,                  bool skip = false,                  double fillValue = 0.0,                  int xTileCoords = 0,                  int yTileCoords = 0);};TInSliceInfo::TInSliceInfo (PixelType tifb,                            PixelType tifl,                            char *b,                            size_t xs, size_t ys,                            bool f, bool s,                            double fv,                            int xtc,                            int ytc):    typeInFrameBuffer (tifb),    typeInFile (tifl),    base (b),    xStride (xs),    yStride (ys),    fill (f),    skip (s),    fillValue (fv),    xTileCoords (xtc),    yTileCoords (ytc){    // empty}struct TileBuffer{    const char *	uncompressedData;    char *		buffer;    int			dataSize;    Compressor *	compressor;    Compressor::Format	format;    int			dx;    int			dy;    int			lx;    int			ly;    bool		hasException;    string		exception;     TileBuffer (Compressor * const comp);    ~TileBuffer ();    inline void		wait () {_sem.wait();}    inline void		post () {_sem.post();} protected:    Semaphore _sem;};TileBuffer::TileBuffer (Compressor *comp):    uncompressedData (0),    dataSize (0),    compressor (comp),    format (defaultFormat (compressor)),    dx (-1),    dy (-1),    lx (-1),    ly (-1),    hasException (false),    exception (),    _sem (1){    // empty}TileBuffer::~TileBuffer (){    delete compressor;}} // namespace//// struct TiledInputFile::Data stores things that will be// needed between calls to readTile()//struct TiledInputFile::Data: public Mutex{    Header	    header;		    // the image header    TileDescription tileDesc;		    // describes the tile layout    int		    version;		    // file's version    FrameBuffer	    frameBuffer;	    // framebuffer to write into    LineOrder	    lineOrder;		    // the file's lineorder    int		    minX;		    // data window's min x coord    int		    maxX;		    // data window's max x coord    int		    minY;		    // data window's min y coord    int		    maxY;		    // data window's max x coord    int		    numXLevels;		    // number of x levels    int		    numYLevels;		    // number of y levels    int *	    numXTiles;		    // number of x tiles at a level    int *	    numYTiles;		    // number of y tiles at a level    TileOffsets	    tileOffsets;	    // stores offsets in file for					    // each tile    bool	    fileIsComplete;	    // True if no tiles are missing    					    // in the file    Int64	    currentPosition;        // file offset for current tile,					    // used to prevent unnecessary					    // seeking    vector<TInSliceInfo> slices;	    // info about channels in file    IStream *	    is;			    // file stream to read from    bool	    deleteStream;	    // should we delete the stream					    // ourselves? or does someone					    // else do it?    size_t	    bytesPerPixel;          // size of an uncompressed pixel    size_t	    maxBytesPerTileLine;    // combined size of a line					    // over all channels        vector<TileBuffer*> tileBuffers;        // each holds a single tile    size_t          tileBufferSize;	    // size of the tile buffers     Data (bool deleteStream, int numThreads);    ~Data ();    inline TileBuffer * getTileBuffer (int number);					    // hash function from tile indices					    // into our vector of tile buffers};TiledInputFile::Data::Data (bool del, int numThreads):    numXTiles (0),    numYTiles (0),    is (0),    deleteStream (del){    //    // We need at least one tileBuffer, but if threading is used,    // to keep n threads busy we need 2*n tileBuffers    //    tileBuffers.resize (max (1, 2 * numThreads));}TiledInputFile::Data::~Data (){    delete [] numXTiles;    delete [] numYTiles;    if (deleteStream)	delete is;    for (size_t i = 0; i < tileBuffers.size(); i++)        delete tileBuffers[i];}TileBuffer*TiledInputFile::Data::getTileBuffer (int number){    return tileBuffers[number % tileBuffers.size()];}namespace {voidreadTileData (TiledInputFile::Data *ifd,	      int dx, int dy,	      int lx, int ly,              char *&buffer,              int &dataSize){    //    // Read a single tile block from the file and into the array pointed    // to by buffer.  If the file is memory-mapped, then we change where    // buffer points instead of writing into the array (hence buffer needs    // to be a reference to a char *).    //    //    // Look up the location for this tile in the Index and    // seek to that position if necessary    //        Int64 tileOffset = ifd->tileOffsets (dx, dy, lx, ly);    if (tileOffset == 0)    {        THROW (Iex::InputExc, "Tile (" << dx << ", " << dy << ", " <<			      lx << ", " << ly << ") is missing.");    }    if (ifd->currentPosition != tileOffset)        ifd->is->seekg (tileOffset);    //    // Read the first few bytes of the tile (the header).    // Verify that the tile coordinates and the level number    // are correct.    //        int tileXCoord, tileYCoord, levelX, levelY;    Xdr::read <StreamIO> (*ifd->is, tileXCoord);    Xdr::read <StreamIO> (*ifd->is, tileYCoord);    Xdr::read <StreamIO> (*ifd->is, levelX);    Xdr::read <StreamIO> (*ifd->is, levelY);    Xdr::read <StreamIO> (*ifd->is, dataSize);    if (tileXCoord != dx)        throw Iex::InputExc ("Unexpected tile x coordinate.");    if (tileYCoord != dy)        throw Iex::InputExc ("Unexpected tile y coordinate.");    if (levelX != lx)        throw Iex::InputExc ("Unexpected tile x level number coordinate.");    if (levelY != ly)        throw Iex::InputExc ("Unexpected tile y level number coordinate.");    if (dataSize > (int) ifd->tileBufferSize)        throw Iex::InputExc ("Unexpected tile block length.");    //    // Read the pixel data.    //    if (ifd->is->isMemoryMapped ())        buffer = ifd->is->readMemoryMapped (dataSize);    else        ifd->is->read (buffer, dataSize);    //    // Keep track of which tile is the next one in    // the file, so that we can avoid redundant seekg()    // operations (seekg() can be fairly expensive).    //        ifd->currentPosition = tileOffset + 5 * Xdr::size<int>() + dataSize;}voidreadNextTileData (TiledInputFile::Data *ifd,		  int &dx, int &dy,		  int &lx, int &ly,                  char * & buffer,		  int &dataSize){    //    // Read the next tile block from the file    //    //    // Read the first few bytes of the tile (the header).    //    Xdr::read <StreamIO> (*ifd->is, dx);    Xdr::read <StreamIO> (*ifd->is, dy);    Xdr::read <StreamIO> (*ifd->is, lx);    Xdr::read <StreamIO> (*ifd->is, ly);    Xdr::read <StreamIO> (*ifd->is, dataSize);    if (dataSize > (int) ifd->tileBufferSize)        throw Iex::InputExc ("Unexpected tile block length.");        //    // Read the pixel data.    //    ifd->is->read (buffer, dataSize);        //    // Keep track of which tile is the next one in    // the file, so that we can avoid redundant seekg()    // operations (seekg() can be fairly expensive).    //    ifd->currentPosition += 5 * Xdr::size<int>() + dataSize;}//// A TileBufferTask encapsulates the task of uncompressing// a single tile and copying it into the frame buffer.//class TileBufferTask : public Task{  public:    TileBufferTask (TaskGroup *group,                    TiledInputFile::Data *ifd,		    TileBuffer *tileBuffer);                        virtual ~TileBufferTask ();    virtual void		execute ();      private:    TiledInputFile::Data *	_ifd;    TileBuffer *		_tileBuffer;};TileBufferTask::TileBufferTask    (TaskGroup *group,     TiledInputFile::Data *ifd,     TileBuffer *tileBuffer):    Task (group),    _ifd (ifd),    _tileBuffer (tileBuffer){    // empty}TileBufferTask::~TileBufferTask (){    //    // Signal that the tile buffer is now free

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -