/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 | 0 | : GTiffBitmapBand(poDSIn, nBandIn) |
26 | | |
27 | 0 | { |
28 | 0 | nBlockXSize = poDS->GetRasterXSize(); |
29 | 0 | nBlockYSize = 1; |
30 | 0 | } |
31 | | |
32 | | /************************************************************************/ |
33 | | /* ~GTiffSplitBitmapBand() */ |
34 | | /************************************************************************/ |
35 | | |
36 | | GTiffSplitBitmapBand::~GTiffSplitBitmapBand() |
37 | 0 | { |
38 | 0 | } |
39 | | |
40 | | /************************************************************************/ |
41 | | /* IGetDataCoverageStatus() */ |
42 | | /************************************************************************/ |
43 | | |
44 | | int GTiffSplitBitmapBand::IGetDataCoverageStatus(int, int, int, int, int, |
45 | | double *) |
46 | 0 | { |
47 | 0 | return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED | |
48 | 0 | GDAL_DATA_COVERAGE_STATUS_DATA; |
49 | 0 | } |
50 | | |
51 | | /************************************************************************/ |
52 | | /* IReadBlock() */ |
53 | | /************************************************************************/ |
54 | | |
55 | | CPLErr GTiffSplitBitmapBand::IReadBlock(int /* nBlockXOff */, int nBlockYOff, |
56 | | void *pImage) |
57 | | |
58 | 0 | { |
59 | 0 | m_poGDS->Crystalize(); |
60 | |
|
61 | 0 | if (m_nLastLineValid >= 0 && nBlockYOff > m_nLastLineValid) |
62 | 0 | return CE_Failure; |
63 | | |
64 | 0 | if (m_poGDS->m_pabyBlockBuf == nullptr) |
65 | 0 | { |
66 | 0 | m_poGDS->m_pabyBlockBuf = static_cast<GByte *>( |
67 | 0 | VSI_MALLOC_VERBOSE(TIFFScanlineSize(m_poGDS->m_hTIFF))); |
68 | 0 | if (m_poGDS->m_pabyBlockBuf == nullptr) |
69 | 0 | { |
70 | 0 | return CE_Failure; |
71 | 0 | } |
72 | 0 | } |
73 | | |
74 | | /* -------------------------------------------------------------------- */ |
75 | | /* Read through to target scanline. */ |
76 | | /* -------------------------------------------------------------------- */ |
77 | 0 | if (m_poGDS->m_nLoadedBlock >= nBlockYOff) |
78 | 0 | m_poGDS->m_nLoadedBlock = -1; |
79 | | |
80 | | // Set to 1 to allow GTiffErrorHandler to implement limitation on error |
81 | | // messages |
82 | 0 | GTIFFGetThreadLocalLibtiffError() = 1; |
83 | 0 | while (m_poGDS->m_nLoadedBlock < nBlockYOff) |
84 | 0 | { |
85 | 0 | ++m_poGDS->m_nLoadedBlock; |
86 | |
|
87 | 0 | CPLErrorAccumulator oErrorAccumulator; |
88 | 0 | int nRet; |
89 | 0 | { |
90 | 0 | auto oAccumulator = oErrorAccumulator.InstallForCurrentScope(); |
91 | 0 | nRet = TIFFReadScanline(m_poGDS->m_hTIFF, m_poGDS->m_pabyBlockBuf, |
92 | 0 | m_poGDS->m_nLoadedBlock, 0); |
93 | 0 | } |
94 | |
|
95 | 0 | for (const auto &oError : oErrorAccumulator.GetErrors()) |
96 | 0 | { |
97 | 0 | 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 | 0 | if (!m_poGDS->m_bIgnoreReadErrors && |
102 | 0 | oError.msg.find("Premature EOF") != std::string::npos) |
103 | 0 | { |
104 | 0 | m_nLastLineValid = nBlockYOff; |
105 | 0 | nRet = -1; |
106 | 0 | } |
107 | 0 | } |
108 | |
|
109 | 0 | if (nRet == -1 && !m_poGDS->m_bIgnoreReadErrors) |
110 | 0 | { |
111 | 0 | ReportError(CE_Failure, CPLE_AppDefined, |
112 | 0 | "TIFFReadScanline() failed."); |
113 | 0 | m_poGDS->m_nLoadedBlock = -1; |
114 | 0 | GTIFFGetThreadLocalLibtiffError() = 0; |
115 | 0 | return CE_Failure; |
116 | 0 | } |
117 | 0 | } |
118 | 0 | GTIFFGetThreadLocalLibtiffError() = 0; |
119 | | |
120 | | /* -------------------------------------------------------------------- */ |
121 | | /* Translate 1bit data to eight bit. */ |
122 | | /* -------------------------------------------------------------------- */ |
123 | 0 | int iSrcOffset = 0; |
124 | 0 | int iDstOffset = 0; |
125 | |
|
126 | 0 | for (int iPixel = 0; iPixel < nBlockXSize; ++iPixel, ++iSrcOffset) |
127 | 0 | { |
128 | 0 | if (m_poGDS->m_pabyBlockBuf[iSrcOffset >> 3] & |
129 | 0 | (0x80 >> (iSrcOffset & 0x7))) |
130 | 0 | static_cast<GByte *>(pImage)[iDstOffset++] = 1; |
131 | 0 | else |
132 | 0 | static_cast<GByte *>(pImage)[iDstOffset++] = 0; |
133 | 0 | } |
134 | |
|
135 | 0 | return CE_None; |
136 | 0 | } |
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 | } |