/src/gdal/frmts/gtiff/fetchbufferdirectio.h
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 | | #ifndef FETCHBUFFERDIRECTIO_H_INCLUDED |
15 | | #define FETCHBUFFERDIRECTIO_H_INCLUDED |
16 | | |
17 | | #include "cpl_error.h" |
18 | | #include "cpl_vsi.h" |
19 | | #include "gdal.h" |
20 | | |
21 | | /************************************************************************/ |
22 | | /* FetchBufferDirectIO */ |
23 | | /************************************************************************/ |
24 | | |
25 | | class FetchBufferDirectIO final |
26 | | { |
27 | | VSILFILE *fp; |
28 | | GByte *pTempBuffer; |
29 | | size_t nTempBufferSize; |
30 | | |
31 | | public: |
32 | | FetchBufferDirectIO(VSILFILE *fpIn, GByte *pTempBufferIn, |
33 | | size_t nTempBufferSizeIn) |
34 | 0 | : fp(fpIn), pTempBuffer(pTempBufferIn), |
35 | 0 | nTempBufferSize(nTempBufferSizeIn) |
36 | 0 | { |
37 | 0 | } |
38 | | |
39 | | const GByte *FetchBytes(vsi_l_offset nOffset, int nPixels, int nDTSize, |
40 | | bool bIsByteSwapped, bool bIsComplex, int nBlockId) |
41 | 0 | { |
42 | 0 | if (!FetchBytes(pTempBuffer, nOffset, nPixels, nDTSize, bIsByteSwapped, |
43 | 0 | bIsComplex, nBlockId)) |
44 | 0 | { |
45 | 0 | return nullptr; |
46 | 0 | } |
47 | 0 | return pTempBuffer; |
48 | 0 | } |
49 | | |
50 | | bool FetchBytes(GByte *pabyDstBuffer, vsi_l_offset nOffset, int nPixels, |
51 | | int nDTSize, bool bIsByteSwapped, bool bIsComplex, |
52 | | int nBlockId) |
53 | 0 | { |
54 | 0 | vsi_l_offset nSeekForward = 0; |
55 | 0 | if (nOffset <= VSIFTellL(fp) || |
56 | 0 | (nSeekForward = nOffset - VSIFTellL(fp)) > nTempBufferSize) |
57 | 0 | { |
58 | 0 | if (VSIFSeekL(fp, nOffset, SEEK_SET) != 0) |
59 | 0 | { |
60 | 0 | CPLError(CE_Failure, CPLE_FileIO, "Cannot seek to block %d", |
61 | 0 | nBlockId); |
62 | 0 | return false; |
63 | 0 | } |
64 | 0 | } |
65 | 0 | else |
66 | 0 | { |
67 | 0 | while (nSeekForward > 0) |
68 | 0 | { |
69 | 0 | vsi_l_offset nToRead = nSeekForward; |
70 | 0 | if (nToRead > nTempBufferSize) |
71 | 0 | nToRead = nTempBufferSize; |
72 | 0 | if (VSIFReadL(pTempBuffer, static_cast<size_t>(nToRead), 1, |
73 | 0 | fp) != 1) |
74 | 0 | { |
75 | 0 | CPLError(CE_Failure, CPLE_FileIO, "Cannot seek to block %d", |
76 | 0 | nBlockId); |
77 | 0 | return false; |
78 | 0 | } |
79 | 0 | nSeekForward -= nToRead; |
80 | 0 | } |
81 | 0 | } |
82 | 0 | if (VSIFReadL(pabyDstBuffer, static_cast<size_t>(nPixels) * nDTSize, 1, |
83 | 0 | fp) != 1) |
84 | 0 | { |
85 | 0 | CPLError(CE_Failure, CPLE_FileIO, "Missing data for block %d", |
86 | 0 | nBlockId); |
87 | 0 | return false; |
88 | 0 | } |
89 | | |
90 | 0 | if (bIsByteSwapped) |
91 | 0 | { |
92 | 0 | if (bIsComplex) |
93 | 0 | GDALSwapWords(pabyDstBuffer, nDTSize / 2, 2 * nPixels, |
94 | 0 | nDTSize / 2); |
95 | 0 | else |
96 | 0 | GDALSwapWords(pabyDstBuffer, nDTSize, nPixels, nDTSize); |
97 | 0 | } |
98 | 0 | return true; |
99 | 0 | } |
100 | | |
101 | | static const bool bMinimizeIO = true; |
102 | | }; |
103 | | |
104 | | #endif // FETCHBUFFERDIRECTIO_H_INCLUDED |