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 : * 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 613 : FetchBufferDirectIO(VSILFILE *fpIn, GByte *pTempBufferIn,
33 : size_t nTempBufferSizeIn)
34 613 : : fp(fpIn), pTempBuffer(pTempBufferIn),
35 613 : nTempBufferSize(nTempBufferSizeIn)
36 : {
37 613 : }
38 :
39 9595 : const GByte *FetchBytes(vsi_l_offset nOffset, int nPixels, int nDTSize,
40 : bool bIsByteSwapped, bool bIsComplex, int nBlockId)
41 : {
42 9595 : if (!FetchBytes(pTempBuffer, nOffset, nPixels, nDTSize, bIsByteSwapped,
43 : bIsComplex, nBlockId))
44 : {
45 18 : return nullptr;
46 : }
47 9577 : return pTempBuffer;
48 : }
49 :
50 9595 : bool FetchBytes(GByte *pabyDstBuffer, vsi_l_offset nOffset, int nPixels,
51 : int nDTSize, bool bIsByteSwapped, bool bIsComplex,
52 : int nBlockId)
53 : {
54 9595 : vsi_l_offset nSeekForward = 0;
55 13801 : if (nOffset <= VSIFTellL(fp) ||
56 4206 : (nSeekForward = nOffset - VSIFTellL(fp)) > nTempBufferSize)
57 : {
58 7344 : if (VSIFSeekL(fp, nOffset, SEEK_SET) != 0)
59 : {
60 0 : CPLError(CE_Failure, CPLE_FileIO, "Cannot seek to block %d",
61 : nBlockId);
62 0 : return false;
63 : }
64 : }
65 : else
66 : {
67 4502 : while (nSeekForward > 0)
68 : {
69 2251 : vsi_l_offset nToRead = nSeekForward;
70 2251 : if (nToRead > nTempBufferSize)
71 0 : nToRead = nTempBufferSize;
72 2251 : if (VSIFReadL(pTempBuffer, static_cast<size_t>(nToRead), 1,
73 2251 : fp) != 1)
74 : {
75 0 : CPLError(CE_Failure, CPLE_FileIO, "Cannot seek to block %d",
76 : nBlockId);
77 0 : return false;
78 : }
79 2251 : nSeekForward -= nToRead;
80 : }
81 : }
82 9595 : if (VSIFReadL(pabyDstBuffer, static_cast<size_t>(nPixels) * nDTSize, 1,
83 9595 : fp) != 1)
84 : {
85 18 : CPLError(CE_Failure, CPLE_FileIO, "Missing data for block %d",
86 : nBlockId);
87 18 : return false;
88 : }
89 :
90 9577 : if (bIsByteSwapped)
91 : {
92 2318 : if (bIsComplex)
93 1213 : GDALSwapWords(pabyDstBuffer, nDTSize / 2, 2 * nPixels,
94 : nDTSize / 2);
95 : else
96 1105 : GDALSwapWords(pabyDstBuffer, nDTSize, nPixels, nDTSize);
97 : }
98 9577 : return true;
99 : }
100 :
101 : static const bool bMinimizeIO = true;
102 : };
103 :
104 : #endif // FETCHBUFFERDIRECTIO_H_INCLUDED
|