Line data Source code
1 : /******************************************************************************
2 : *
3 : * Project: GeoTIFF Driver
4 : * Purpose: GDAL GeoTIFF support.
5 : * Author: Frank Warmerdam, warmerdam@pobox.com
6 : *
7 : ******************************************************************************
8 : * Copyright (c) 1998, 2002, Frank Warmerdam <warmerdam@pobox.com>
9 : * Copyright (c) 2007-2015, Even Rouault <even dot rouault at spatialys dot com>
10 : *
11 : * Permission is hereby granted, free of charge, to any person obtaining a
12 : * copy of this software and associated documentation files (the "Software"),
13 : * to deal in the Software without restriction, including without limitation
14 : * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 : * and/or sell copies of the Software, and to permit persons to whom the
16 : * Software is furnished to do so, subject to the following conditions:
17 : *
18 : * The above copyright notice and this permission notice shall be included
19 : * in all copies or substantial portions of the Software.
20 : *
21 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
24 : * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
26 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
27 : * DEALINGS IN THE SOFTWARE.
28 : ****************************************************************************/
29 :
30 : #include "gtiffrgbaband.h"
31 : #include "gtiffdataset.h"
32 :
33 : #include "tiffio.h"
34 :
35 : /************************************************************************/
36 : /* GTiffRGBABand() */
37 : /************************************************************************/
38 :
39 127 : GTiffRGBABand::GTiffRGBABand(GTiffDataset *poDSIn, int nBandIn)
40 127 : : GTiffRasterBand(poDSIn, nBandIn)
41 : {
42 127 : eDataType = GDT_Byte;
43 127 : }
44 :
45 : /************************************************************************/
46 : /* IGetDataCoverageStatus() */
47 : /************************************************************************/
48 :
49 0 : int GTiffRGBABand::IGetDataCoverageStatus(int, int, int, int, int, double *)
50 : {
51 : return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
52 0 : GDAL_DATA_COVERAGE_STATUS_DATA;
53 : }
54 :
55 : /************************************************************************/
56 : /* IWriteBlock() */
57 : /************************************************************************/
58 :
59 0 : CPLErr GTiffRGBABand::IWriteBlock(int, int, void *)
60 :
61 : {
62 0 : ReportError(CE_Failure, CPLE_AppDefined,
63 : "RGBA interpreted raster bands are read-only.");
64 0 : return CE_Failure;
65 : }
66 :
67 : /************************************************************************/
68 : /* IReadBlock() */
69 : /************************************************************************/
70 :
71 221 : CPLErr GTiffRGBABand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
72 :
73 : {
74 221 : m_poGDS->Crystalize();
75 :
76 221 : const auto nBlockBufSize =
77 221 : 4 * static_cast<GPtrDiff_t>(nBlockXSize) * nBlockYSize;
78 221 : const int nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
79 :
80 221 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE)
81 : {
82 56 : for (int iBand = 0; iBand < m_poGDS->m_nSamplesPerPixel; iBand++)
83 : {
84 40 : int nBlockIdBand = nBlockId + iBand * m_poGDS->m_nBlocksPerBand;
85 40 : if (!m_poGDS->IsBlockAvailable(nBlockIdBand))
86 0 : return CE_Failure;
87 : }
88 : }
89 : else
90 : {
91 205 : if (!m_poGDS->IsBlockAvailable(nBlockId))
92 0 : return CE_Failure;
93 : }
94 :
95 : /* -------------------------------------------------------------------- */
96 : /* Allocate a temporary buffer for this strip. */
97 : /* -------------------------------------------------------------------- */
98 221 : if (m_poGDS->m_pabyBlockBuf == nullptr)
99 : {
100 54 : m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
101 27 : VSI_MALLOC3_VERBOSE(4, nBlockXSize, nBlockYSize));
102 27 : if (m_poGDS->m_pabyBlockBuf == nullptr)
103 0 : return CE_Failure;
104 : }
105 :
106 : /* -------------------------------------------------------------------- */
107 : /* Read the strip */
108 : /* -------------------------------------------------------------------- */
109 221 : CPLErr eErr = CE_None;
110 :
111 221 : if (m_poGDS->m_nLoadedBlock != nBlockId)
112 : {
113 63 : if (TIFFIsTiled(m_poGDS->m_hTIFF))
114 : {
115 12 : if (TIFFReadRGBATileExt(
116 4 : m_poGDS->m_hTIFF, nBlockXOff * nBlockXSize,
117 4 : nBlockYOff * nBlockYSize,
118 4 : reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
119 5 : !m_poGDS->m_bIgnoreReadErrors) == 0 &&
120 1 : !m_poGDS->m_bIgnoreReadErrors)
121 : {
122 : // Once TIFFError() is properly hooked, this can go away.
123 1 : ReportError(CE_Failure, CPLE_AppDefined,
124 : "TIFFReadRGBATile() failed.");
125 :
126 1 : memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
127 :
128 1 : eErr = CE_Failure;
129 : }
130 : }
131 : else
132 : {
133 177 : if (TIFFReadRGBAStripExt(
134 59 : m_poGDS->m_hTIFF, nBlockId * nBlockYSize,
135 59 : reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
136 65 : !m_poGDS->m_bIgnoreReadErrors) == 0 &&
137 6 : !m_poGDS->m_bIgnoreReadErrors)
138 : {
139 : // Once TIFFError() is properly hooked, this can go away.
140 6 : ReportError(CE_Failure, CPLE_AppDefined,
141 : "TIFFReadRGBAStrip() failed.");
142 :
143 6 : memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
144 :
145 6 : eErr = CE_Failure;
146 : }
147 : }
148 : }
149 :
150 221 : m_poGDS->m_nLoadedBlock = eErr == CE_None ? nBlockId : -1;
151 :
152 : /* -------------------------------------------------------------------- */
153 : /* Handle simple case of eight bit data, and pixel interleaving. */
154 : /* -------------------------------------------------------------------- */
155 221 : int nThisBlockYSize = nBlockYSize;
156 :
157 253 : if (nBlockYOff * nBlockYSize > GetYSize() - nBlockYSize &&
158 32 : !TIFFIsTiled(m_poGDS->m_hTIFF))
159 20 : nThisBlockYSize = GetYSize() - nBlockYOff * nBlockYSize;
160 :
161 : #ifdef CPL_LSB
162 221 : const int nBO = nBand - 1;
163 : #else
164 : const int nBO = 4 - nBand;
165 : #endif
166 :
167 7550 : for (int iDestLine = 0; iDestLine < nThisBlockYSize; ++iDestLine)
168 : {
169 7329 : const auto nSrcOffset =
170 7329 : static_cast<GPtrDiff_t>(nThisBlockYSize - iDestLine - 1) *
171 7329 : nBlockXSize * 4;
172 :
173 7329 : GDALCopyWords(m_poGDS->m_pabyBlockBuf + nBO + nSrcOffset, GDT_Byte, 4,
174 : static_cast<GByte *>(pImage) +
175 7329 : static_cast<GPtrDiff_t>(iDestLine) * nBlockXSize,
176 : GDT_Byte, 1, nBlockXSize);
177 : }
178 :
179 221 : if (eErr == CE_None)
180 214 : eErr = FillCacheForOtherBands(nBlockXOff, nBlockYOff);
181 :
182 221 : return eErr;
183 : }
184 :
185 : /************************************************************************/
186 : /* GetColorInterpretation() */
187 : /************************************************************************/
188 :
189 9 : GDALColorInterp GTiffRGBABand::GetColorInterpretation()
190 :
191 : {
192 9 : if (nBand == 1)
193 2 : return GCI_RedBand;
194 7 : if (nBand == 2)
195 1 : return GCI_GreenBand;
196 6 : if (nBand == 3)
197 1 : return GCI_BlueBand;
198 :
199 5 : return GCI_AlphaBand;
200 : }
|