/src/gdal/frmts/gtiff/gtiffsplitbitmapband.cpp
Line | Count | Source (jump to first uncovered line) |
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 "gtiffsplitbitmapband.h" |
15 | | |
16 | | #include "gtiffdataset.h" |
17 | | |
18 | | #include "cpl_error_internal.h" |
19 | | |
20 | | /************************************************************************/ |
21 | | /* GTiffSplitBitmapBand() */ |
22 | | /************************************************************************/ |
23 | | |
24 | | GTiffSplitBitmapBand::GTiffSplitBitmapBand(GTiffDataset *poDSIn, int nBandIn) |
25 | 14.5k | : GTiffBitmapBand(poDSIn, nBandIn) |
26 | | |
27 | 14.5k | { |
28 | 14.5k | nBlockXSize = poDS->GetRasterXSize(); |
29 | 14.5k | nBlockYSize = 1; |
30 | 14.5k | } |
31 | | |
32 | | /************************************************************************/ |
33 | | /* ~GTiffSplitBitmapBand() */ |
34 | | /************************************************************************/ |
35 | | |
36 | | GTiffSplitBitmapBand::~GTiffSplitBitmapBand() |
37 | 14.5k | { |
38 | 14.5k | } |
39 | | |
40 | | /************************************************************************/ |
41 | | /* IGetDataCoverageStatus() */ |
42 | | /************************************************************************/ |
43 | | |
44 | | int GTiffSplitBitmapBand::IGetDataCoverageStatus(int, int, int, int, int, |
45 | | double *) |
46 | 139 | { |
47 | 139 | return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED | |
48 | 139 | GDAL_DATA_COVERAGE_STATUS_DATA; |
49 | 139 | } |
50 | | |
51 | | /************************************************************************/ |
52 | | /* IReadBlock() */ |
53 | | /************************************************************************/ |
54 | | |
55 | | CPLErr GTiffSplitBitmapBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff, |
56 | | void *pImage) |
57 | | |
58 | 377k | { |
59 | 377k | m_poGDS->Crystalize(); |
60 | | |
61 | 377k | if (m_nLastLineValid >= 0 && nBlockYOff > m_nLastLineValid) |
62 | 10 | return CE_Failure; |
63 | | |
64 | 377k | if (m_poGDS->m_pabyBlockBuf == nullptr) |
65 | 3.58k | { |
66 | 3.58k | m_poGDS->m_pabyBlockBuf = static_cast<GByte *>( |
67 | 3.58k | VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF))); |
68 | 3.58k | if (m_poGDS->m_pabyBlockBuf == nullptr) |
69 | 0 | { |
70 | 0 | return CE_Failure; |
71 | 0 | } |
72 | 3.58k | } |
73 | | |
74 | | /* -------------------------------------------------------------------- */ |
75 | | /* Read through to target scanline. */ |
76 | | /* -------------------------------------------------------------------- */ |
77 | 377k | if (m_poGDS->m_nLoadedBlock >= nBlockYOff) |
78 | 514 | m_poGDS->m_nLoadedBlock = -1; |
79 | | |
80 | | // Set to 1 to allow GTiffErrorHandler to implement limitation on error |
81 | | // messages |
82 | 377k | GTIFFGetThreadLocalLibtiffError() = 1; |
83 | 2.52M | while (m_poGDS->m_nLoadedBlock < nBlockYOff) |
84 | 2.15M | { |
85 | 2.15M | ++m_poGDS->m_nLoadedBlock; |
86 | | |
87 | 2.15M | CPLErrorAccumulator oErrorAccumulator; |
88 | 2.15M | int nRet; |
89 | 2.15M | { |
90 | 2.15M | auto oAccumulator = oErrorAccumulator.InstallForCurrentScope(); |
91 | 2.15M | nRet = TIFFReadScanline(m_poGDS->m_hTIFF, m_poGDS->m_pabyBlockBuf, |
92 | 2.15M | m_poGDS->m_nLoadedBlock, 0); |
93 | 2.15M | } |
94 | | |
95 | 2.15M | for (const auto &oError : oErrorAccumulator.GetErrors()) |
96 | 402k | { |
97 | 402k | ReportError(oError.type, oError.no, "%s", oError.msg.c_str()); |
98 | | // FAX decoding only handles EOF condition as a warning, so |
99 | | // catch it so as to turn on error when attempting to read |
100 | | // following lines, to avoid performance issues. |
101 | 402k | if (!m_poGDS->m_bIgnoreReadErrors && |
102 | 402k | oError.msg.find("Premature EOF") != std::string::npos) |
103 | 633 | { |
104 | 633 | m_nLastLineValid = nBlockYOff; |
105 | 633 | nRet = -1; |
106 | 633 | } |
107 | 402k | } |
108 | | |
109 | 2.15M | if (nRet == -1 && !m_poGDS->m_bIgnoreReadErrors) |
110 | 6.83k | { |
111 | 6.83k | ReportError(CE_Failure, CPLE_AppDefined, |
112 | 6.83k | "TIFFReadScanline() failed."); |
113 | 6.83k | m_poGDS->m_nLoadedBlock = -1; |
114 | 6.83k | GTIFFGetThreadLocalLibtiffError() = 0; |
115 | 6.83k | return CE_Failure; |
116 | 6.83k | } |
117 | 2.15M | } |
118 | 370k | GTIFFGetThreadLocalLibtiffError() = 0; |
119 | | |
120 | | /* -------------------------------------------------------------------- */ |
121 | | /* Translate 1bit data to eight bit. */ |
122 | | /* -------------------------------------------------------------------- */ |
123 | 370k | int iSrcOffset = 0; |
124 | 370k | int iDstOffset = 0; |
125 | | |
126 | 773M | for (int iPixel = 0; iPixel < nBlockXSize; ++iPixel, ++iSrcOffset) |
127 | 772M | { |
128 | 772M | if (m_poGDS->m_pabyBlockBuf[iSrcOffset >> 3] & |
129 | 772M | (0x80 >> (iSrcOffset & 0x7))) |
130 | 72.3M | static_cast<GByte *>(pImage)[iDstOffset++] = 1; |
131 | 700M | else |
132 | 700M | static_cast<GByte *>(pImage)[iDstOffset++] = 0; |
133 | 772M | } |
134 | | |
135 | 370k | return CE_None; |
136 | 377k | } |
137 | | |
138 | | /************************************************************************/ |
139 | | /* IWriteBlock() */ |
140 | | /************************************************************************/ |
141 | | |
142 | | CPLErr GTiffSplitBitmapBand::IWriteBlock(int /* nBlockXOff */, |
143 | | int /* nBlockYOff */, |
144 | | void * /* pImage */) |
145 | | |
146 | 0 | { |
147 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
148 | 0 | "Split bitmap bands are read-only."); |
149 | 0 | return CE_Failure; |
150 | 0 | } |