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 "gtiffsplitbitmapband.h"
31 :
32 : #include "gtiffdataset.h"
33 :
34 : #include "cpl_error_internal.h"
35 :
36 : /************************************************************************/
37 : /* GTiffSplitBitmapBand() */
38 : /************************************************************************/
39 :
40 10 : GTiffSplitBitmapBand::GTiffSplitBitmapBand(GTiffDataset *poDSIn, int nBandIn)
41 10 : : GTiffBitmapBand(poDSIn, nBandIn)
42 :
43 : {
44 10 : nBlockXSize = poDS->GetRasterXSize();
45 10 : nBlockYSize = 1;
46 10 : }
47 :
48 : /************************************************************************/
49 : /* ~GTiffSplitBitmapBand() */
50 : /************************************************************************/
51 :
52 20 : GTiffSplitBitmapBand::~GTiffSplitBitmapBand()
53 : {
54 20 : }
55 :
56 : /************************************************************************/
57 : /* IGetDataCoverageStatus() */
58 : /************************************************************************/
59 :
60 0 : int GTiffSplitBitmapBand::IGetDataCoverageStatus(int, int, int, int, int,
61 : double *)
62 : {
63 : return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
64 0 : GDAL_DATA_COVERAGE_STATUS_DATA;
65 : }
66 :
67 : /************************************************************************/
68 : /* IReadBlock() */
69 : /************************************************************************/
70 :
71 23837 : CPLErr GTiffSplitBitmapBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff,
72 : void *pImage)
73 :
74 : {
75 23837 : m_poGDS->Crystalize();
76 :
77 23837 : if (m_nLastLineValid >= 0 && nBlockYOff > m_nLastLineValid)
78 0 : return CE_Failure;
79 :
80 23837 : if (m_poGDS->m_pabyBlockBuf == nullptr)
81 : {
82 14 : m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
83 7 : VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF)));
84 7 : if (m_poGDS->m_pabyBlockBuf == nullptr)
85 : {
86 0 : return CE_Failure;
87 : }
88 : }
89 :
90 : /* -------------------------------------------------------------------- */
91 : /* Read through to target scanline. */
92 : /* -------------------------------------------------------------------- */
93 23837 : if (m_poGDS->m_nLoadedBlock >= nBlockYOff)
94 0 : m_poGDS->m_nLoadedBlock = -1;
95 :
96 : // Set to 1 to allow GTiffErrorHandler to implement limitation on error
97 : // messages
98 23837 : GTIFFGetThreadLocalLibtiffError() = 1;
99 47671 : while (m_poGDS->m_nLoadedBlock < nBlockYOff)
100 : {
101 23837 : ++m_poGDS->m_nLoadedBlock;
102 :
103 23837 : std::vector<CPLErrorHandlerAccumulatorStruct> aoErrors;
104 23837 : CPLInstallErrorHandlerAccumulator(aoErrors);
105 47674 : int nRet = TIFFReadScanline(m_poGDS->m_hTIFF, m_poGDS->m_pabyBlockBuf,
106 23837 : m_poGDS->m_nLoadedBlock, 0);
107 23837 : CPLUninstallErrorHandlerAccumulator();
108 :
109 24051 : for (size_t iError = 0; iError < aoErrors.size(); ++iError)
110 : {
111 214 : ReportError(aoErrors[iError].type, aoErrors[iError].no, "%s",
112 214 : aoErrors[iError].msg.c_str());
113 : // FAX decoding only handles EOF condition as a warning, so
114 : // catch it so as to turn on error when attempting to read
115 : // following lines, to avoid performance issues.
116 428 : if (!m_poGDS->m_bIgnoreReadErrors &&
117 214 : aoErrors[iError].msg.find("Premature EOF") != std::string::npos)
118 : {
119 0 : m_nLastLineValid = nBlockYOff;
120 0 : nRet = -1;
121 : }
122 : }
123 :
124 23837 : if (nRet == -1 && !m_poGDS->m_bIgnoreReadErrors)
125 : {
126 3 : ReportError(CE_Failure, CPLE_AppDefined,
127 : "TIFFReadScanline() failed.");
128 3 : m_poGDS->m_nLoadedBlock = -1;
129 3 : GTIFFGetThreadLocalLibtiffError() = 0;
130 3 : return CE_Failure;
131 : }
132 : }
133 23834 : GTIFFGetThreadLocalLibtiffError() = 0;
134 :
135 : /* -------------------------------------------------------------------- */
136 : /* Translate 1bit data to eight bit. */
137 : /* -------------------------------------------------------------------- */
138 23834 : int iSrcOffset = 0;
139 23834 : int iDstOffset = 0;
140 :
141 21647500 : for (int iPixel = 0; iPixel < nBlockXSize; ++iPixel, ++iSrcOffset)
142 : {
143 21623700 : if (m_poGDS->m_pabyBlockBuf[iSrcOffset >> 3] &
144 21623700 : (0x80 >> (iSrcOffset & 0x7)))
145 21262600 : static_cast<GByte *>(pImage)[iDstOffset++] = 1;
146 : else
147 361064 : static_cast<GByte *>(pImage)[iDstOffset++] = 0;
148 : }
149 :
150 23834 : return CE_None;
151 : }
152 :
153 : /************************************************************************/
154 : /* IWriteBlock() */
155 : /************************************************************************/
156 :
157 0 : CPLErr GTiffSplitBitmapBand::IWriteBlock(int /* nBlockXOff */,
158 : int /* nBlockYOff */,
159 : void * /* pImage */)
160 :
161 : {
162 0 : ReportError(CE_Failure, CPLE_AppDefined,
163 : "Split bitmap bands are read-only.");
164 0 : return CE_Failure;
165 : }
|