~ubuntu-branches/ubuntu/quantal/aqsis/quantal

« back to all changes in this revision

Viewing changes to libs/tex/io/tiledtiffinputfile.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2009-08-06 04:53:26 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806045326-z6xeaaao62idxcc6
Tags: 1.6.0-0ubuntu1
* New upstream release
* debian/control:
  - changed name of lib package to libaqsis1 instead of aqsis-libsc2a
  - changed name of dev package to libaqsis-dev instead of aqsis-libs-dev
  - Added aqsis-data package
  - Revised summary text according to that specified by the RISpec (Pixar)
* Moved examples installation from aqsis.install to aqsis-data.install
* debian/rules: 
  - added content to binary-indep target
* debian/rules: added explicit name of mime file to force dh_installmime
  to generate postinst and prerm scripts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Aqsis
 
2
// Copyright (C) 1997 - 2007, Paul C. Gregory
 
3
//
 
4
// Contact: pgregory@aqsis.org
 
5
//
 
6
// This library is free software; you can redistribute it and/or
 
7
// modify it under the terms of the GNU General Public
 
8
// License as published by the Free Software Foundation; either
 
9
// version 2 of the License, or (at your option) any later version.
 
10
//
 
11
// This library is distributed in the hope that it will be useful,
 
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
// General Public License for more details.
 
15
//
 
16
// You should have received a copy of the GNU General Public
 
17
// License along with this library; if not, write to the Free Software
 
18
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 
 
20
/** \file
 
21
 *
 
22
 * \brief Tiled TIFF input interface.
 
23
 *
 
24
 * \author Chris Foster [chris42f (at) gmail (d0t) com]
 
25
 */
 
26
 
 
27
#include "tiledtiffinputfile.h"
 
28
 
 
29
#include <boost/scoped_array.hpp>
 
30
 
 
31
#include <aqsis/tex/texexception.h>
 
32
 
 
33
namespace Aqsis {
 
34
 
 
35
CqTiledTiffInputFile::CqTiledTiffInputFile(const boostfs::path& fileName)
 
36
        : m_headers(),
 
37
        m_fileHandle(new CqTiffFileHandle(fileName, "r")),
 
38
        m_numDirs(m_fileHandle->numDirectories()),
 
39
        m_tileInfo(0,0),
 
40
        m_widths(),
 
41
        m_heights()
 
42
{
 
43
        m_headers.reserve(m_numDirs);
 
44
        m_widths.reserve(m_numDirs);
 
45
        m_heights.reserve(m_numDirs);
 
46
        // Iterate through all subimages and check some conditions which will
 
47
        // become assumptions in the rest of the code.
 
48
        for(TqInt i = 0; i < m_numDirs; ++i)
 
49
        {
 
50
                CqTiffDirHandle dirHandle(m_fileHandle, i);
 
51
                boost::shared_ptr<CqTexFileHeader> tmpHeader(new CqTexFileHeader);
 
52
                dirHandle.fillHeader(*tmpHeader);
 
53
                // Check that the subimage is tiled.
 
54
                SqTileInfo* tileInfo= tmpHeader->findPtr<Attr::TileInfo>();
 
55
                if(!tileInfo)
 
56
                {
 
57
                        AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile, "TIFF file \""
 
58
                                << fileName << "\" has non-tiled sub-image " << i);
 
59
                }
 
60
                // Check that we can natively read the pixel format held in the TIFF.
 
61
                if(tmpHeader->find<Attr::TiffUseGenericRGBA>())
 
62
                {
 
63
                        AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile,
 
64
                                "Unsupported TIFF pixel format");
 
65
                }
 
66
                if(i == 0)
 
67
                {
 
68
                        // Store the tile info from the first sub-image only.  We force the
 
69
                        // tile sizes for other sub-images to match this.
 
70
                        m_tileInfo = *tileInfo;
 
71
                }
 
72
                else
 
73
                {
 
74
                        // Check that the tile size is the same as the first image.
 
75
                        if(m_tileInfo.width != tileInfo->width
 
76
                                        || m_tileInfo.height != tileInfo->height)
 
77
                        {
 
78
                                AQSIS_THROW_XQERROR(XqBadTexture, EqE_BadFile, "TIFF file \""
 
79
                                                << fileName << "\" has unequal tile sizes for sub-images");
 
80
                        }
 
81
                }
 
82
                // Grab store the width and height of the current subimage.
 
83
                m_widths.push_back(tmpHeader->width());
 
84
                m_heights.push_back(tmpHeader->height());
 
85
                // Store the header itself.  Sometimes we really do need access to the
 
86
                // extra attributes (eg, matrices for occlusion sampling).  We could
 
87
                // define special extra methods for these, but it bloats up the
 
88
                // interface a bit.
 
89
                m_headers.push_back(tmpHeader);
 
90
        }
 
91
}
 
92
 
 
93
boostfs::path CqTiledTiffInputFile::fileName() const
 
94
{
 
95
        return m_fileHandle->fileName();
 
96
}
 
97
 
 
98
EqImageFileType CqTiledTiffInputFile::fileType() const
 
99
{
 
100
        return ImageFile_Tiff;
 
101
}
 
102
 
 
103
const CqTexFileHeader& CqTiledTiffInputFile::header(TqInt index) const
 
104
{
 
105
        if(index >= 0 && index < m_numDirs)
 
106
                return *m_headers[index];
 
107
        else
 
108
                return *m_headers[0];
 
109
}
 
110
 
 
111
SqTileInfo CqTiledTiffInputFile::tileInfo() const
 
112
{
 
113
        return m_tileInfo;
 
114
}
 
115
 
 
116
TqInt CqTiledTiffInputFile::numSubImages() const
 
117
{
 
118
        return m_numDirs;
 
119
}
 
120
 
 
121
TqInt CqTiledTiffInputFile::width(TqInt index) const
 
122
{
 
123
        assert(index < m_numDirs);
 
124
        return m_widths[index];
 
125
}
 
126
 
 
127
TqInt CqTiledTiffInputFile::height(TqInt index) const
 
128
{
 
129
        assert(index < m_numDirs);
 
130
        return m_heights[index];
 
131
}
 
132
 
 
133
void CqTiledTiffInputFile::readTileImpl(TqUint8* buffer, TqInt x, TqInt y,
 
134
                TqInt subImageIdx, const SqTileInfo tileSize) const
 
135
{
 
136
        CqTiffDirHandle dirHandle(m_fileHandle, subImageIdx);
 
137
        if((x+1)*m_tileInfo.width > m_widths[subImageIdx]
 
138
                        || (y+1)*m_tileInfo.height > m_heights[subImageIdx])
 
139
        {
 
140
                // Here we handle a special case where the tile overlaps either the
 
141
                // right or bottom edge of the image.  In this case, libtiff reads in
 
142
                // the tile as the same size as all other tiles, not touching the parts
 
143
                // of buffer outside the image.  We want to truncate the tile instead.
 
144
                boost::scoped_array<TqUint8> tmpBuf(
 
145
                                new TqUint8[TIFFTileSize(dirHandle.tiffPtr())]);
 
146
                TIFFReadTile(dirHandle.tiffPtr(), static_cast<tdata_t>(tmpBuf.get()),
 
147
                                x*m_tileInfo.width, y*m_tileInfo.height, 0, 0);
 
148
                TqInt bytesPerPixel = m_headers[subImageIdx]->channelList().bytesPerPixel();
 
149
                stridedCopy(buffer, tileSize.width*bytesPerPixel, tmpBuf.get(),
 
150
                                m_tileInfo.width*bytesPerPixel, tileSize.height,
 
151
                                tileSize.width*bytesPerPixel);
 
152
        }
 
153
        else
 
154
        {
 
155
                // Simple case for wholly contained buffers - the provided buffer is
 
156
                // the correct size, and we get libtiff to read directly into it.
 
157
                TIFFReadTile(dirHandle.tiffPtr(), static_cast<tdata_t>(buffer),
 
158
                                x*m_tileInfo.width, y*m_tileInfo.height, 0, 0);
 
159
        }
 
160
}
 
161
 
 
162
} // namespace Aqsis