Coverage Report

Created: 2025-06-13 06:29

/src/gdal/frmts/gtiff/gtiffrgbaband.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 "gtiffrgbaband.h"
15
#include "gtiffdataset.h"
16
17
#include "tiffio.h"
18
19
/************************************************************************/
20
/*                           GTiffRGBABand()                            */
21
/************************************************************************/
22
23
GTiffRGBABand::GTiffRGBABand(GTiffDataset *poDSIn, int nBandIn)
24
0
    : GTiffRasterBand(poDSIn, nBandIn)
25
0
{
26
0
    eDataType = GDT_Byte;
27
0
}
28
29
/************************************************************************/
30
/*                       IGetDataCoverageStatus()                       */
31
/************************************************************************/
32
33
int GTiffRGBABand::IGetDataCoverageStatus(int, int, int, int, int, double *)
34
0
{
35
0
    return GDAL_DATA_COVERAGE_STATUS_UNIMPLEMENTED |
36
0
           GDAL_DATA_COVERAGE_STATUS_DATA;
37
0
}
38
39
/************************************************************************/
40
/*                            IWriteBlock()                             */
41
/************************************************************************/
42
43
CPLErr GTiffRGBABand::IWriteBlock(int, int, void *)
44
45
0
{
46
0
    ReportError(CE_Failure, CPLE_AppDefined,
47
0
                "RGBA interpreted raster bands are read-only.");
48
0
    return CE_Failure;
49
0
}
50
51
/************************************************************************/
52
/*                             IReadBlock()                             */
53
/************************************************************************/
54
55
CPLErr GTiffRGBABand::IReadBlock(int nBlockXOff, int nBlockYOff, void *pImage)
56
57
0
{
58
0
    m_poGDS->Crystalize();
59
60
0
    const auto nBlockBufSize =
61
0
        4 * static_cast<GPtrDiff_t>(nBlockXSize) * nBlockYSize;
62
0
    const int nBlockId = nBlockXOff + nBlockYOff * nBlocksPerRow;
63
64
0
    if (m_poGDS->m_nPlanarConfig == PLANARCONFIG_SEPARATE)
65
0
    {
66
0
        for (int iBand = 0; iBand < m_poGDS->m_nSamplesPerPixel; iBand++)
67
0
        {
68
0
            int nBlockIdBand = nBlockId + iBand * m_poGDS->m_nBlocksPerBand;
69
0
            if (!m_poGDS->IsBlockAvailable(nBlockIdBand, nullptr, nullptr,
70
0
                                           nullptr))
71
0
                return CE_Failure;
72
0
        }
73
0
    }
74
0
    else
75
0
    {
76
0
        if (!m_poGDS->IsBlockAvailable(nBlockId, nullptr, nullptr, nullptr))
77
0
            return CE_Failure;
78
0
    }
79
80
    /* -------------------------------------------------------------------- */
81
    /*      Allocate a temporary buffer for this strip.                     */
82
    /* -------------------------------------------------------------------- */
83
0
    if (m_poGDS->m_pabyBlockBuf == nullptr)
84
0
    {
85
0
        m_poGDS->m_pabyBlockBuf = static_cast<GByte *>(
86
0
            VSI_MALLOC3_VERBOSE(4, nBlockXSize, nBlockYSize));
87
0
        if (m_poGDS->m_pabyBlockBuf == nullptr)
88
0
            return CE_Failure;
89
0
    }
90
91
    /* -------------------------------------------------------------------- */
92
    /*      Read the strip                                                  */
93
    /* -------------------------------------------------------------------- */
94
0
    CPLErr eErr = CE_None;
95
96
0
    if (m_poGDS->m_nLoadedBlock != nBlockId)
97
0
    {
98
0
        if (TIFFIsTiled(m_poGDS->m_hTIFF))
99
0
        {
100
0
            if (TIFFReadRGBATileExt(
101
0
                    m_poGDS->m_hTIFF, nBlockXOff * nBlockXSize,
102
0
                    nBlockYOff * nBlockYSize,
103
0
                    reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
104
0
                    !m_poGDS->m_bIgnoreReadErrors) == 0 &&
105
0
                !m_poGDS->m_bIgnoreReadErrors)
106
0
            {
107
                // Once TIFFError() is properly hooked, this can go away.
108
0
                ReportError(CE_Failure, CPLE_AppDefined,
109
0
                            "TIFFReadRGBATile() failed.");
110
111
0
                memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
112
113
0
                eErr = CE_Failure;
114
0
            }
115
0
        }
116
0
        else
117
0
        {
118
0
            if (TIFFReadRGBAStripExt(
119
0
                    m_poGDS->m_hTIFF, nBlockId * nBlockYSize,
120
0
                    reinterpret_cast<uint32_t *>(m_poGDS->m_pabyBlockBuf),
121
0
                    !m_poGDS->m_bIgnoreReadErrors) == 0 &&
122
0
                !m_poGDS->m_bIgnoreReadErrors)
123
0
            {
124
                // Once TIFFError() is properly hooked, this can go away.
125
0
                ReportError(CE_Failure, CPLE_AppDefined,
126
0
                            "TIFFReadRGBAStrip() failed.");
127
128
0
                memset(m_poGDS->m_pabyBlockBuf, 0, nBlockBufSize);
129
130
0
                eErr = CE_Failure;
131
0
            }
132
0
        }
133
0
    }
134
135
0
    m_poGDS->m_nLoadedBlock = eErr == CE_None ? nBlockId : -1;
136
137
    /* -------------------------------------------------------------------- */
138
    /*      Handle simple case of eight bit data, and pixel interleaving.   */
139
    /* -------------------------------------------------------------------- */
140
0
    int nThisBlockYSize = nBlockYSize;
141
142
0
    if (nBlockYOff * nBlockYSize > GetYSize() - nBlockYSize &&
143
0
        !TIFFIsTiled(m_poGDS->m_hTIFF))
144
0
        nThisBlockYSize = GetYSize() - nBlockYOff * nBlockYSize;
145
146
0
#ifdef CPL_LSB
147
0
    const int nBO = nBand - 1;
148
#else
149
    const int nBO = 4 - nBand;
150
#endif
151
152
0
    for (int iDestLine = 0; iDestLine < nThisBlockYSize; ++iDestLine)
153
0
    {
154
0
        const auto nSrcOffset =
155
0
            static_cast<GPtrDiff_t>(nThisBlockYSize - iDestLine - 1) *
156
0
            nBlockXSize * 4;
157
158
0
        GDALCopyWords(m_poGDS->m_pabyBlockBuf + nBO + nSrcOffset, GDT_Byte, 4,
159
0
                      static_cast<GByte *>(pImage) +
160
0
                          static_cast<GPtrDiff_t>(iDestLine) * nBlockXSize,
161
0
                      GDT_Byte, 1, nBlockXSize);
162
0
    }
163
164
0
    if (eErr == CE_None)
165
0
        eErr = FillCacheForOtherBands(nBlockXOff, nBlockYOff);
166
167
0
    return eErr;
168
0
}
169
170
/************************************************************************/
171
/*                       GetColorInterpretation()                       */
172
/************************************************************************/
173
174
GDALColorInterp GTiffRGBABand::GetColorInterpretation()
175
176
0
{
177
0
    if (nBand == 1)
178
0
        return GCI_RedBand;
179
0
    if (nBand == 2)
180
0
        return GCI_GreenBand;
181
0
    if (nBand == 3)
182
0
        return GCI_BlueBand;
183
184
0
    return GCI_AlphaBand;
185
0
}