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 : * SPDX-License-Identifier: MIT
12 : ****************************************************************************/
13 :
14 : #include "gtiffrgbaband.h"
15 : #include "gtiffdataset.h"
16 :
17 : #include "tiffio.h"
18 :
19 : /************************************************************************/
20 : /* GTiffRGBABand() */
21 : /************************************************************************/
22 :
23 127 : GTiffRGBABand::GTiffRGBABand(GTiffDataset *poDSIn, int nBandIn)
24 127 : : GTiffRasterBand(poDSIn, nBandIn)
25 : {
26 127 : eDataType = GDT_Byte;
27 127 : }
28 :
29 : /************************************************************************/
30 : /* IGetDataCoverageStatus() */
31 : /************************************************************************/
32 :
33 0 : int GTiffRGBABand::IGetDataCoverageStatus(int, int, int, int, int, double *)
34 : {
35 : return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
36 0 : GDAL_DATA_COVERAGE_STATUS_DATA;
37 : }
38 :
39 : /************************************************************************/
40 : /* IWriteBlock() */
41 : /************************************************************************/
42 :
43 0 : CPLErr GTiffRGBABand::IWriteBlock(int, int, void *)
44 :
45 : {
46 0 : ReportError(CE_Failure, CPLE_AppDefined,
47 : "RGBA interpreted raster bands are read-only.");
48 0 : return CE_Failure;
49 : }
50 :
51 : /************************************************************************/
52 : /* IReadBlock() */
53 : /************************************************************************/
54 :
55 221 : CPLErr GTiffRGBABand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
56 :
57 : {
58 221 : m_poGDS->Crystalize();
59 :
60 221 : const auto nBlockBufSize =
61 221 : 4 * static_cast<GPtrDiff_t>(nBlockXSize) * nBlockYSize;
62 221 : const int nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
63 :
64 221 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE)
65 : {
66 56 : for (int iBand = 0; iBand < m_poGDS->m_nSamplesPerPixel; iBand++)
67 : {
68 40 : int nBlockIdBand = nBlockId + iBand * m_poGDS->m_nBlocksPerBand;
69 40 : if (!m_poGDS->IsBlockAvailable(nBlockIdBand))
70 0 : return CE_Failure;
71 : }
72 : }
73 : else
74 : {
75 205 : if (!m_poGDS->IsBlockAvailable(nBlockId))
76 0 : return CE_Failure;
77 : }
78 :
79 : /* -------------------------------------------------------------------- */
80 : /* Allocate a temporary buffer for this strip. */
81 : /* -------------------------------------------------------------------- */
82 221 : if (m_poGDS->m_pabyBlockBuf == nullptr)
83 : {
84 54 : m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
85 27 : VSI_MALLOC3_VERBOSE(4, nBlockXSize, nBlockYSize));
86 27 : if (m_poGDS->m_pabyBlockBuf == nullptr)
87 0 : return CE_Failure;
88 : }
89 :
90 : /* -------------------------------------------------------------------- */
91 : /* Read the strip */
92 : /* -------------------------------------------------------------------- */
93 221 : CPLErr eErr = CE_None;
94 :
95 221 : if (m_poGDS->m_nLoadedBlock != nBlockId)
96 : {
97 63 : if (TIFFIsTiled(m_poGDS->m_hTIFF))
98 : {
99 12 : if (TIFFReadRGBATileExt(
100 4 : m_poGDS->m_hTIFF, nBlockXOff * nBlockXSize,
101 4 : nBlockYOff * nBlockYSize,
102 4 : reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
103 5 : !m_poGDS->m_bIgnoreReadErrors) == 0 &&
104 1 : !m_poGDS->m_bIgnoreReadErrors)
105 : {
106 : // Once TIFFError() is properly hooked, this can go away.
107 1 : ReportError(CE_Failure, CPLE_AppDefined,
108 : "TIFFReadRGBATile() failed.");
109 :
110 1 : memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
111 :
112 1 : eErr = CE_Failure;
113 : }
114 : }
115 : else
116 : {
117 177 : if (TIFFReadRGBAStripExt(
118 59 : m_poGDS->m_hTIFF, nBlockId * nBlockYSize,
119 59 : reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
120 65 : !m_poGDS->m_bIgnoreReadErrors) == 0 &&
121 6 : !m_poGDS->m_bIgnoreReadErrors)
122 : {
123 : // Once TIFFError() is properly hooked, this can go away.
124 6 : ReportError(CE_Failure, CPLE_AppDefined,
125 : "TIFFReadRGBAStrip() failed.");
126 :
127 6 : memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
128 :
129 6 : eErr = CE_Failure;
130 : }
131 : }
132 : }
133 :
134 221 : m_poGDS->m_nLoadedBlock = eErr == CE_None ? nBlockId : -1;
135 :
136 : /* -------------------------------------------------------------------- */
137 : /* Handle simple case of eight bit data, and pixel interleaving. */
138 : /* -------------------------------------------------------------------- */
139 221 : int nThisBlockYSize = nBlockYSize;
140 :
141 253 : if (nBlockYOff * nBlockYSize > GetYSize() - nBlockYSize &&
142 32 : !TIFFIsTiled(m_poGDS->m_hTIFF))
143 20 : nThisBlockYSize = GetYSize() - nBlockYOff * nBlockYSize;
144 :
145 : #ifdef CPL_LSB
146 221 : const int nBO = nBand - 1;
147 : #else
148 : const int nBO = 4 - nBand;
149 : #endif
150 :
151 7550 : for (int iDestLine = 0; iDestLine < nThisBlockYSize; ++iDestLine)
152 : {
153 7329 : const auto nSrcOffset =
154 7329 : static_cast<GPtrDiff_t>(nThisBlockYSize - iDestLine - 1) *
155 7329 : nBlockXSize * 4;
156 :
157 7329 : GDALCopyWords(m_poGDS->m_pabyBlockBuf + nBO + nSrcOffset, GDT_Byte, 4,
158 : static_cast<GByte *>(pImage) +
159 7329 : static_cast<GPtrDiff_t>(iDestLine) * nBlockXSize,
160 : GDT_Byte, 1, nBlockXSize);
161 : }
162 :
163 221 : if (eErr == CE_None)
164 214 : eErr = FillCacheForOtherBands(nBlockXOff, nBlockYOff);
165 :
166 221 : return eErr;
167 : }
168 :
169 : /************************************************************************/
170 : /* GetColorInterpretation() */
171 : /************************************************************************/
172 :
173 9 : GDALColorInterp GTiffRGBABand::GetColorInterpretation()
174 :
175 : {
176 9 : if (nBand == 1)
177 2 : return GCI_RedBand;
178 7 : if (nBand == 2)
179 1 : return GCI_GreenBand;
180 6 : if (nBand == 3)
181 1 : return GCI_BlueBand;
182 :
183 5 : return GCI_AlphaBand;
184 : }
|