Coverage Report

Created: 2026-10-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/openexr/src/lib/OpenEXR/ImfCompressor.h
Line
Count
Source
1
//
2
// SPDX-License-Identifier: BSD-3-Clause
3
// Copyright (c) Contributors to the OpenEXR Project.
4
//
5
6
#ifndef INCLUDED_IMF_COMPRESSOR_H
7
#define INCLUDED_IMF_COMPRESSOR_H
8
9
//-----------------------------------------------------------------------------
10
//
11
//  class Compressor
12
//
13
//-----------------------------------------------------------------------------
14
15
#include "ImfForward.h"
16
17
#include "ImfCompression.h"
18
19
#include "ImfContext.h"
20
21
#include "openexr_compression.h"
22
23
#include <Imath/ImathBox.h>
24
25
#include <stdlib.h>
26
#include <memory>
27
28
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_ENTER
29
30
class IMF_EXPORT_TYPE Compressor
31
{
32
public:
33
    //---------------------------------------------
34
    // Constructor -- hdr is the header of the file
35
    // that will be compressed or uncompressed
36
    //---------------------------------------------
37
38
    IMF_EXPORT
39
    Compressor (const Header& hdr,
40
                exr_compression_t compression_type,
41
                size_t maxScanLineSize,
42
                int scanlines = -1);
43
44
    //-----------
45
    // Destructor
46
    //-----------
47
48
    IMF_EXPORT
49
    virtual ~Compressor ();
50
51
    Compressor (const Compressor& other)            = delete;
52
    Compressor& operator= (const Compressor& other) = delete;
53
    Compressor (Compressor&& other)                 = delete;
54
    Compressor& operator= (Compressor&& other)      = delete;
55
56
    //----------------------------------------------
57
    // Maximum number of scan lines processed by
58
    // a single call to compress() and uncompress().
59
    //----------------------------------------------
60
61
    IMF_EXPORT
62
    virtual int numScanLines () const;
63
64
    //----------------------------------------------
65
    // Return the compression type used by this compressor.
66
    //----------------------------------------------
67
68
0
    exr_compression_t compressionType () const { return _comp_type; }
69
70
    //--------------------------------------------
71
    // Format of the pixel data read and written
72
    // by the compress() and uncompress() methods.
73
    // The default implementation of format()
74
    // returns XDR.
75
    //--------------------------------------------
76
77
    enum IMF_EXPORT_ENUM Format
78
    {
79
        NATIVE, // the machine's native format
80
        XDR     // Xdr format
81
    };
82
83
    IMF_EXPORT
84
    virtual Format format () const;
85
86
    //----------------------------
87
    // Access to the file's header
88
    //----------------------------
89
90
0
    const Header& header () const { return _header; }
91
92
    //-------------------------------------------------------------------------
93
    // Compress an array of bytes that represents the contents of up to
94
    // numScanLines() scan lines:
95
    //
96
    //      inPtr   Input buffer (uncompressed data).
97
    //
98
    //      inSize    Number of bytes in the input buffer
99
    //
100
    //      minY    Minimum y coordinate of the scan lines to
101
    //        be compressed
102
    //
103
    //      outPtr    Pointer to output buffer
104
    //
105
    //      return value  Size of compressed data in output buffer
106
    //
107
    // Arrangement of uncompressed pixel data in the input buffer:
108
    //
109
    //  Before calling
110
    //
111
    //          compress (buf, size, minY, ...);
112
    //
113
    //  the InputFile::writePixels() method gathers pixel data from the
114
    //  frame buffer, fb, and places them in buffer buf, like this:
115
    //
116
    //  char *endOfBuf = buf;
117
    //
118
    //  for (int y = minY;
119
    //       y <= min (minY + numScanLines() - 1, header().dataWindow().max.y);
120
    //       ++y)
121
    //  {
122
    //      for (ChannelList::ConstIterator c = header().channels().begin();
123
    //     c != header().channels().end();
124
    //     ++c)
125
    //      {
126
    //    if (modp (y, c.channel().ySampling) != 0)
127
    //        continue;
128
    //
129
    //    for (int x = header().dataWindow().min.x;
130
    //         x <= header().dataWindow().max.x;
131
    //         ++x)
132
    //    {
133
    //        if (modp (x, c.channel().xSampling) != 0)
134
    //      continue;
135
    //
136
    //        Xdr::write<CharPtrIO> (endOfBuf, fb.pixel (c, x, y));
137
    //    }
138
    //      }
139
    //  }
140
    //
141
    //  int size = endOfBuf - buf;
142
    //
143
    //-------------------------------------------------------------------------
144
145
    virtual int
146
    compress (const char* inPtr, int inSize, int minY, const char*& outPtr);
147
148
    IMF_EXPORT
149
    virtual int compressTile (
150
        const char*            inPtr,
151
        int                    inSize,
152
        IMATH_NAMESPACE::Box2i range,
153
        const char*&           outPtr);
154
155
    //-------------------------------------------------------------------------
156
    // Uncompress an array of bytes that has been compressed by compress():
157
    //
158
    //      inPtr   Input buffer (compressed data).
159
    //
160
    //      inSize    Number of bytes in the input buffer
161
    //
162
    //      minY    Minimum y coordinate of the scan lines to
163
    //        be uncompressed
164
    //
165
    //      outPtr    Pointer to output buffer
166
    //
167
    //      return value  Size of uncompressed data in output buffer
168
    //
169
    //-------------------------------------------------------------------------
170
171
    virtual int uncompress (
172
        const char* inPtr, int inSize, int minY, const char*& outPtr);
173
174
    IMF_EXPORT
175
    virtual int uncompressTile (
176
        const char*            inPtr,
177
        int                    inSize,
178
        IMATH_NAMESPACE::Box2i range,
179
        const char*&           outPtr);
180
181
0
    void setExpectedSize (size_t sz) { _expectedSize = sz; }
182
0
    void setTileLevel (int lx, int ly) { _levelX = lx; _levelY = ly; }
183
184
0
    exr_storage_t storageType () const { return _store_type; }
185
0
    void setStorageType (exr_storage_t st) { _store_type = st; }
186
187
protected:
188
    friend int compressWithSampleCountTable (
189
        Compressor&  compressor,
190
        const char*  inPtr,
191
        int          inSize,
192
        int          minY,
193
        const char*& outPtr,
194
        const char*  sampleCountTable,
195
        int          sampleCountTableSize);
196
197
    friend int compressTileWithSampleCountTable (
198
        Compressor&            compressor,
199
        const char*            inPtr,
200
        int                    inSize,
201
        IMATH_NAMESPACE::Box2i range,
202
        const char*&           outPtr,
203
        const char*            sampleCountTable,
204
        int                    sampleCountTableSize);
205
206
    Context _ctxt;
207
    const Header& _header;
208
209
    size_t _maxScanLineSize = 0;
210
    int _numScanLines = -1;
211
212
    exr_compression_t _comp_type;
213
    exr_storage_t _store_type;
214
215
    exr_decode_pipeline_t _decoder = EXR_DECODE_PIPELINE_INITIALIZER;
216
    exr_encode_pipeline_t _encoder = EXR_ENCODE_PIPELINE_INITIALIZER;
217
    bool _decoder_init = false;
218
    bool _encoder_init = false;
219
    std::unique_ptr<char[]> _memory_buffer;
220
    uint64_t _buf_sz = 0;
221
    size_t _expectedSize = 0;
222
223
    int _levelX = 0;
224
    int _levelY = 0;
225
226
    uint64_t runEncodeStep (
227
        const char* inPtr,
228
        int inSize,
229
        IMATH_NAMESPACE::Box2i range,
230
        const char*& outPtr,
231
        const char* sampleCountTable = nullptr,
232
        int sampleCountTableSize     = 0);
233
    uint64_t runDecodeStep (
234
        const char* inPtr,
235
        int inSize,
236
        IMATH_NAMESPACE::Box2i range,
237
        const char*& outPtr);
238
};
239
240
//-----------------------------------------------------------------
241
// Construct a Compressor for compression type c:
242
//
243
//  maxScanLineSize Maximum number of bytes per uncompressed
244
//      scan line.
245
//
246
//  header    Header of the input or output file whose
247
//      pixels will be compressed or uncompressed.
248
//
249
//  return value  A pointer to a new Compressor object (it
250
//      is the caller's responsibility to delete
251
//      the object), or 0 (if c is NO_COMPRESSION).
252
//
253
//-----------------------------------------------------------------
254
255
IMF_EXPORT
256
Compressor*
257
newCompressor (Compression c, size_t maxScanLineSize, const Header& hdr);
258
259
//-----------------------------------------------------------------
260
// Construct a Compressor for compression type c for a tiled image:
261
//
262
//  tileLineSize  Maximum number of bytes per uncompressed
263
//      line in a tile.
264
//
265
//  numTileLines  Maximum number of lines in a tile.
266
//
267
//  header    Header of the input or output file whose
268
//      pixels will be compressed or uncompressed.
269
//
270
//  return value  A pointer to a new Compressor object (it
271
//      is the caller's responsibility to delete
272
//      the object), or 0 (if c is NO_COMPRESSION).
273
//
274
//-----------------------------------------------------------------
275
276
IMF_EXPORT
277
Compressor* newTileCompressor (
278
    Compression c, size_t tileLineSize, size_t numTileLines, const Header& hdr);
279
280
//-----------------------------------------------------------------
281
// Return the maximum number of scanlines in each chunk
282
// of a scanline image using the given compression scheme
283
//-----------------------------------------------------------------
284
285
IMF_EXPORT
286
int numLinesInBuffer (Compression comp);
287
288
OPENEXR_IMF_INTERNAL_NAMESPACE_HEADER_EXIT
289
290
#endif