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, nullptr, nullptr,
70 : nullptr))
71 0 : return CE_Failure;
72 : }
73 : }
74 : else
75 : {
76 205 : if (!m_poGDS->IsBlockAvailable(nBlockId, nullptr, nullptr, nullptr))
77 0 : return CE_Failure;
78 : }
79 :
80 : /* -------------------------------------------------------------------- */
81 : /* Allocate a temporary buffer for this strip. */
82 : /* -------------------------------------------------------------------- */
83 221 : if (m_poGDS->m_pabyBlockBuf == nullptr)
84 : {
85 54 : m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
86 27 : VSI_MALLOC3_VERBOSE(4, nBlockXSize, nBlockYSize));
87 27 : if (m_poGDS->m_pabyBlockBuf == nullptr)
88 0 : return CE_Failure;
89 : }
90 :
91 : /* -------------------------------------------------------------------- */
92 : /* Read the strip */
93 : /* -------------------------------------------------------------------- */
94 221 : CPLErr eErr = CE_None;
95 :
96 221 : if (m_poGDS->m_nLoadedBlock != nBlockId)
97 : {
98 63 : if (TIFFIsTiled(m_poGDS->m_hTIFF))
99 : {
100 12 : if (TIFFReadRGBATileExt(
101 4 : m_poGDS->m_hTIFF, nBlockXOff * nBlockXSize,
102 4 : nBlockYOff * nBlockYSize,
103 4 : reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
104 5 : !m_poGDS->m_bIgnoreReadErrors) == 0 &&
105 1 : !m_poGDS->m_bIgnoreReadErrors)
106 : {
107 : // Once TIFFError() is properly hooked, this can go away.
108 1 : ReportError(CE_Failure, CPLE_AppDefined,
109 : "TIFFReadRGBATile() failed.");
110 :
111 1 : memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
112 :
113 1 : eErr = CE_Failure;
114 : }
115 : }
116 : else
117 : {
118 177 : if (TIFFReadRGBAStripExt(
119 59 : m_poGDS->m_hTIFF, nBlockId * nBlockYSize,
120 59 : reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
121 65 : !m_poGDS->m_bIgnoreReadErrors) == 0 &&
122 6 : !m_poGDS->m_bIgnoreReadErrors)
123 : {
124 : // Once TIFFError() is properly hooked, this can go away.
125 6 : ReportError(CE_Failure, CPLE_AppDefined,
126 : "TIFFReadRGBAStrip() failed.");
127 :
128 6 : memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
129 :
130 6 : eErr = CE_Failure;
131 : }
132 : }
133 : }
134 :
135 221 : m_poGDS->m_nLoadedBlock = eErr == CE_None ? nBlockId : -1;
136 :
137 : /* -------------------------------------------------------------------- */
138 : /* Handle simple case of eight bit data, and pixel interleaving. */
139 : /* -------------------------------------------------------------------- */
140 221 : int nThisBlockYSize = nBlockYSize;
141 :
142 253 : if (nBlockYOff * nBlockYSize > GetYSize() - nBlockYSize &&
143 32 : !TIFFIsTiled(m_poGDS->m_hTIFF))
144 20 : nThisBlockYSize = GetYSize() - nBlockYOff * nBlockYSize;
145 :
146 : #ifdef CPL_LSB
147 221 : const int nBO = nBand - 1;
148 : #else
149 : const int nBO = 4 - nBand;
150 : #endif
151 :
152 7550 : for (int iDestLine = 0; iDestLine < nThisBlockYSize; ++iDestLine)
153 : {
154 7329 : const auto nSrcOffset =
155 7329 : static_cast<GPtrDiff_t>(nThisBlockYSize - iDestLine - 1) *
156 7329 : nBlockXSize * 4;
157 :
158 7329 : GDALCopyWords(m_poGDS->m_pabyBlockBuf + nBO + nSrcOffset, GDT_Byte, 4,
159 : static_cast<GByte *>(pImage) +
160 7329 : static_cast<GPtrDiff_t>(iDestLine) * nBlockXSize,
161 : GDT_Byte, 1, nBlockXSize);
162 : }
163 :
164 221 : if (eErr == CE_None)
165 214 : eErr = FillCacheForOtherBands(nBlockXOff, nBlockYOff);
166 :
167 221 : return eErr;
168 : }
169 :
170 : /************************************************************************/
171 : /* GetColorInterpretation() */
172 : /************************************************************************/
173 :
174 9 : GDALColorInterp GTiffRGBABand::GetColorInterpretation()
175 :
176 : {
177 9 : if (nBand == 1)
178 2 : return GCI_RedBand;
179 7 : if (nBand == 2)
180 1 : return GCI_GreenBand;
181 6 : if (nBand == 3)
182 1 : return GCI_BlueBand;
183 :
184 5 : return GCI_AlphaBand;
185 : }
|