Coverage Report

Created: 2025-06-13 06:18

/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