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