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 "gtiffsplitband.h"
31 :
32 : #include "gtiffdataset.h"
33 :
34 : /************************************************************************/
35 : /* GTiffSplitBand() */
36 : /************************************************************************/
37 :
38 131118 : GTiffSplitBand::GTiffSplitBand(GTiffDataset *poDSIn, int nBandIn)
39 131118 : : GTiffRasterBand(poDSIn, nBandIn)
40 : {
41 131118 : nBlockXSize = poDS->GetRasterXSize();
42 131118 : nBlockYSize = 1;
43 131118 : }
44 :
45 : /************************************************************************/
46 : /* IGetDataCoverageStatus() */
47 : /************************************************************************/
48 :
49 0 : int GTiffSplitBand::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 : /* IReadBlock() */
57 : /************************************************************************/
58 :
59 78291 : CPLErr GTiffSplitBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff,
60 : void *pImage)
61 :
62 : {
63 78291 : m_poGDS->Crystalize();
64 :
65 : // Optimization when reading the same line in a contig multi-band TIFF.
66 78291 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG &&
67 48291 : m_poGDS->nBands > 1 && m_poGDS->m_nLoadedBlock == nBlockYOff)
68 : {
69 4011 : goto extract_band_data;
70 : }
71 :
72 74280 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_CONTIG && m_poGDS->nBands > 1)
73 : {
74 40276 : if (m_poGDS->m_pabyBlockBuf == nullptr)
75 : {
76 14 : m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
77 7 : VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF)));
78 7 : if (m_poGDS->m_pabyBlockBuf == nullptr)
79 : {
80 1 : return CE_Failure;
81 : }
82 : }
83 : }
84 : else
85 : {
86 34004 : CPLAssert(TIFFScanlineSize(m_poGDS->m_hTIFF) == nBlockXSize);
87 : }
88 :
89 : /* -------------------------------------------------------------------- */
90 : /* Read through to target scanline. */
91 : /* -------------------------------------------------------------------- */
92 74279 : if (m_poGDS->m_nLoadedBlock >= nBlockYOff)
93 33 : m_poGDS->m_nLoadedBlock = -1;
94 :
95 74279 : if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE &&
96 30000 : m_poGDS->nBands > 1)
97 : {
98 : // If we change of band, we must start reading the
99 : // new strip from its beginning.
100 30000 : if (m_poGDS->m_nLastBandRead != nBand)
101 20 : m_poGDS->m_nLoadedBlock = -1;
102 30000 : m_poGDS->m_nLastBandRead = nBand;
103 : }
104 :
105 203674 : while (m_poGDS->m_nLoadedBlock < nBlockYOff)
106 : {
107 129397 : ++m_poGDS->m_nLoadedBlock;
108 194550 : if (TIFFReadScanline(m_poGDS->m_hTIFF,
109 61149 : m_poGDS->m_pabyBlockBuf ? m_poGDS->m_pabyBlockBuf
110 : : pImage,
111 129397 : m_poGDS->m_nLoadedBlock,
112 129397 : (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE)
113 64244 : ? static_cast<uint16_t>(nBand - 1)
114 129399 : : 0) == -1 &&
115 2 : !m_poGDS->m_bIgnoreReadErrors)
116 : {
117 2 : ReportError(CE_Failure, CPLE_AppDefined,
118 : "TIFFReadScanline() failed.");
119 2 : m_poGDS->m_nLoadedBlock = -1;
120 2 : return CE_Failure;
121 : }
122 : }
123 :
124 74277 : extract_band_data:
125 : /* -------------------------------------------------------------------- */
126 : /* Extract band data from contig buffer. */
127 : /* -------------------------------------------------------------------- */
128 78288 : if (m_poGDS->m_pabyBlockBuf != nullptr)
129 : {
130 44286 : for (int iPixel = 0, iSrcOffset = nBand - 1, iDstOffset = 0;
131 180732 : iPixel < nBlockXSize;
132 136446 : ++iPixel, iSrcOffset += m_poGDS->nBands, ++iDstOffset)
133 : {
134 136446 : static_cast<GByte *>(pImage)[iDstOffset] =
135 136446 : m_poGDS->m_pabyBlockBuf[iSrcOffset];
136 : }
137 : }
138 :
139 78288 : return CE_None;
140 : }
141 :
142 : /************************************************************************/
143 : /* IWriteBlock() */
144 : /************************************************************************/
145 :
146 0 : CPLErr GTiffSplitBand::IWriteBlock(int /* nBlockXOff */, int /* nBlockYOff */,
147 : void * /* pImage */)
148 :
149 : {
150 0 : ReportError(CE_Failure, CPLE_AppDefined, "Split bands are read-only.");
151 0 : return CE_Failure;
152 : }
|