Coverage Report

Created: 2025-11-16 06:25

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