Codeblock.h
Go to the documentation of this file.
/*
* Copyright (C) 2016-2023 Grok Image Compression Inc.
*
* This source code is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This source code is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "grk_includes.h"
#include <vector>
namespace grk
{
// code segment (code block can be encoded into multiple segments)
struct Segment
{
Segment()
{
clear();
}
void clear()
{
numpasses = 0;
len = 0;
maxpasses = 0;
numPassesInPacket = 0;
numBytesInPacket = 0;
}
uint32_t numpasses; // number of passes in segment
uint32_t len; // total length of segment
uint32_t maxpasses; // maximum number of passes in segment
uint32_t numPassesInPacket; // number of passes contributed by current packet
uint32_t numBytesInPacket; // number of bytes contributed by current packet
};
// compressing/decoding pass
struct CodePass
{
CodePass() : rate(0), distortiondec(0), len(0), term(0), slope(0) {}
uint32_t rate;
double distortiondec;
uint32_t len;
uint8_t term;
uint16_t slope; // ln(slope) in 8.8 fixed point
};
// quality layer
struct Layer
{
Layer() : numpasses(0), len(0), distortion(0), data(nullptr) {}
uint32_t numpasses; // Number of passes in the layer
uint32_t len; // number of bytes in layer
double distortion; // layer distortion decrease
uint8_t* data; // compressed layer data
};
// note: block lives in canvas coordinates
struct Codeblock : public grk_buf2d<int32_t, AllocatorAligned>, public ICacheable
{
Codeblock(uint16_t numLayers)
: numbps(0), numlenbits(0)
#ifdef DEBUG_LOSSLESS_T2
,
included(false)
#endif
{
numPassesInPacket = std::vector<uint8_t>(numLayers);
std::fill(numPassesInPacket.begin(), numPassesInPacket.end(), 0);
}
virtual ~Codeblock()
{
compressedStream.dealloc();
}
Codeblock(const Codeblock& rhs)
: grk_buf2d(rhs), numbps(rhs.numbps), numlenbits(rhs.numlenbits),
numPassesInPacket(rhs.numPassesInPacket)
#ifdef DEBUG_LOSSLESS_T2
,
included(0)
#endif
{
compressedStream = rhs.compressedStream;
}
Codeblock& operator=(const Codeblock& rhs)
{
if(this != &rhs)
{ // self-assignment check expected
x0 = rhs.x0;
y0 = rhs.y0;
x1 = rhs.x1;
y1 = rhs.y1;
compressedStream = rhs.compressedStream;
numbps = rhs.numbps;
numlenbits = rhs.numlenbits;
numPassesInPacket = rhs.numPassesInPacket;
#ifdef DEBUG_LOSSLESS_T2
included = rhs.included;
packet_length_info = rhs.packet_length_info;
#endif
}
return *this;
}
void setRect(grk_rect32 r)
{
(*(grk_rect32*)this) = r;
}
grk_buf8 compressedStream;
uint8_t numbps;
uint8_t numlenbits;
uint8_t getNumPassesInPacket(uint16_t layno)
{
assert(layno < numPassesInPacket.size());
return numPassesInPacket[layno];
}
void setNumPassesInPacket(uint16_t layno, uint8_t passes)
{
assert(layno < numPassesInPacket.size());
numPassesInPacket[layno] = passes;
}
void incNumPassesInPacket(uint16_t layno, uint8_t delta)
{
assert(layno < numPassesInPacket.size());
numPassesInPacket[layno] += delta;
}
protected:
std::vector<uint8_t> numPassesInPacket;
#ifdef DEBUG_LOSSLESS_T2
uint32_t included;
std::vector<PacketLengthInfo> packet_length_info;
#endif
};
struct CompressCodeblock : public Codeblock
{
CompressCodeblock(uint16_t numLayers)
: Codeblock(numLayers), paddedCompressedStream(nullptr), layers(nullptr), passes(nullptr),
numPassesInPreviousPackets(0), numPassesTotal(0), contextStream(nullptr)
{}
virtual ~CompressCodeblock()
{
compressedStream.dealloc();
grk_free(layers);
grk_free(passes);
}
bool init()
{
if(!layers)
{
layers = (Layer*)grk_calloc(maxCompressLayersGRK, sizeof(Layer));
if(!layers)
return false;
}
if(!passes)
{
passes = (CodePass*)grk_calloc(100, sizeof(CodePass));
if(!passes)
return false;
}
return true;
}
bool allocData(size_t nominalBlockSize)
{
uint32_t desired_data_size = (uint32_t)(nominalBlockSize * sizeof(uint32_t));
// we add two fake zero bytes at beginning of buffer, so that mq coder
// can be initialized to data[-1] == actualData[1], and still point
// to a valid memory location
auto buf = new uint8_t[desired_data_size + grk_cblk_enc_compressed_data_pad_left];
buf[0] = 0;
buf[1] = 0;
paddedCompressedStream = buf + grk_cblk_enc_compressed_data_pad_left;
compressedStream.buf = buf;
compressedStream.len = desired_data_size;
compressedStream.owns_data = true;
return true;
}
uint8_t* paddedCompressedStream;
Layer* layers;
CodePass* passes;
uint32_t numPassesInPreviousPackets; /* number of passes in previous packets */
uint32_t numPassesTotal; /* total number of passes in all layers */
uint32_t* contextStream;
};
struct DecompressCodeblock : public Codeblock
{
DecompressCodeblock(uint16_t numLayers)
: Codeblock(numLayers), segs(nullptr), numSegments(0),
#ifdef DEBUG_LOSSLESS_T2
included(0),
#endif
numSegmentsAllocated(0)
{}
virtual ~DecompressCodeblock()
{
release();
}
Segment* getSegment(uint32_t segmentIndex)
{
if(!segs)
{
numSegmentsAllocated = 1;
segs = new Segment[numSegmentsAllocated];
numSegmentsAllocated = 1;
}
else if(segmentIndex >= numSegmentsAllocated)
{
auto new_segs = new Segment[2 * numSegmentsAllocated];
for(uint32_t i = 0; i < numSegmentsAllocated; ++i)
new_segs[i] = segs[i];
numSegmentsAllocated *= 2;
delete[] segs;
segs = new_segs;
}
return segs + segmentIndex;
}
bool init()
{
return true;
}
uint32_t getNumSegments(void)
{
return numSegments;
}
Segment* getCurrentSegment(void)
{
return numSegments ? getSegment(numSegments - 1) : nullptr;
}
Segment* nextSegment(void)
{
numSegments++;
return getCurrentSegment();
}
void cleanUpSegBuffers()
{
for(auto& b : seg_buffers)
delete b;
seg_buffers.clear();
numSegments = 0;
}
size_t getSegBuffersLen()
{
return std::accumulate(seg_buffers.begin(), seg_buffers.end(), (size_t)0,
[](const size_t s, grk_buf8* a) { return (s + a->len); });
}
bool copyToContiguousBuffer(uint8_t* buffer)
{
if(!buffer)
return false;
size_t offset = 0;
for(auto& buf : seg_buffers)
{
if(buf->len)
{
memcpy(buffer + offset, buf->buf, buf->len);
offset += buf->len;
}
}
return true;
}
void release(void)
{
cleanUpSegBuffers();
delete[] segs;
segs = nullptr;
grk_buf2d::dealloc();
}
std::vector<grk_buf8*> seg_buffers;
private:
Segment* segs; /* information on segments */
uint32_t numSegments; /* number of segment in block*/
uint32_t numSegmentsAllocated; // number of segments allocated for segs array
};
} // namespace grk
grk::ICacheable
Definition ICacheable.h:29
grk_includes.h
grk
Copyright (C) 2016-2023 Grok Image Compression Inc.
Definition ICacheable.h:20
grk::grk_read
void grk_read(const uint8_t *buffer, TYPE *value, uint32_t numBytes)
Definition BufferedStream.h:239
grk::maxCompressLayersGRK
const uint16_t maxCompressLayersGRK
Definition CodeStreamLimits.h:43
grk::grk_free
void grk_free(void *ptr)
Deallocates or frees a memory block.
Definition MemManager.cpp:96
grk::delta
static const float delta
Definition WaveletFwd.cpp:42
grk::grk_calloc
void * grk_calloc(size_t num, size_t size)
Allocate a memory block with elements initialized to 0.
Definition MemManager.cpp:68
grk::CodePass
Definition Codeblock.h:46
grk::CodePass::slope
uint16_t slope
Definition Codeblock.h:52
grk::CodePass::term
uint8_t term
Definition Codeblock.h:51
grk::CodePass::len
uint32_t len
Definition Codeblock.h:50
grk::CodePass::rate
uint32_t rate
Definition Codeblock.h:48
grk::CodePass::distortiondec
double distortiondec
Definition Codeblock.h:49
grk::CodePass::CodePass
CodePass()
Definition Codeblock.h:47
grk::Codeblock
Definition Codeblock.h:66
grk::Codeblock::numlenbits
uint8_t numlenbits
Definition Codeblock.h:116
grk::Codeblock::Codeblock
Codeblock(const Codeblock &rhs)
Definition Codeblock.h:81
grk::Codeblock::getNumPassesInPacket
uint8_t getNumPassesInPacket(uint16_t layno)
Definition Codeblock.h:117
grk::Codeblock::numbps
uint8_t numbps
Definition Codeblock.h:115
grk::Codeblock::setRect
void setRect(grk_rect32 r)
Definition Codeblock.h:110
grk::Codeblock::setNumPassesInPacket
void setNumPassesInPacket(uint16_t layno, uint8_t passes)
Definition Codeblock.h:122
grk::Codeblock::~Codeblock
virtual ~Codeblock()
Definition Codeblock.h:77
grk::Codeblock::numPassesInPacket
std::vector< uint8_t > numPassesInPacket
Definition Codeblock.h:134
grk::Codeblock::compressedStream
grk_buf8 compressedStream
Definition Codeblock.h:114
grk::Codeblock::incNumPassesInPacket
void incNumPassesInPacket(uint16_t layno, uint8_t delta)
Definition Codeblock.h:127
grk::Codeblock::Codeblock
Codeblock(uint16_t numLayers)
Definition Codeblock.h:67
grk::Codeblock::operator=
Codeblock & operator=(const Codeblock &rhs)
Definition Codeblock.h:91
grk::CompressCodeblock
Definition Codeblock.h:142
grk::CompressCodeblock::init
bool init()
Definition Codeblock.h:153
grk::CompressCodeblock::numPassesInPreviousPackets
uint32_t numPassesInPreviousPackets
Definition Codeblock.h:195
grk::CompressCodeblock::numPassesTotal
uint32_t numPassesTotal
Definition Codeblock.h:196
grk::CompressCodeblock::passes
CodePass * passes
Definition Codeblock.h:194
grk::CompressCodeblock::allocData
bool allocData(size_t nominalBlockSize)
Allocates data memory for an compressing code block.
Definition Codeblock.h:175
grk::CompressCodeblock::CompressCodeblock
CompressCodeblock(uint16_t numLayers)
Definition Codeblock.h:143
grk::CompressCodeblock::contextStream
uint32_t * contextStream
Definition Codeblock.h:197
grk::CompressCodeblock::layers
Layer * layers
Definition Codeblock.h:193
grk::CompressCodeblock::paddedCompressedStream
uint8_t * paddedCompressedStream
Definition Codeblock.h:192
grk::CompressCodeblock::~CompressCodeblock
virtual ~CompressCodeblock()
Definition Codeblock.h:147
grk::DecompressCodeblock
Definition Codeblock.h:201
grk::DecompressCodeblock::getSegBuffersLen
size_t getSegBuffersLen()
Definition Codeblock.h:257
grk::DecompressCodeblock::init
bool init()
Definition Codeblock.h:233
grk::DecompressCodeblock::copyToContiguousBuffer
bool copyToContiguousBuffer(uint8_t *buffer)
Definition Codeblock.h:262
grk::DecompressCodeblock::~DecompressCodeblock
virtual ~DecompressCodeblock()
Definition Codeblock.h:209
grk::DecompressCodeblock::numSegmentsAllocated
uint32_t numSegmentsAllocated
Definition Codeblock.h:289
grk::DecompressCodeblock::DecompressCodeblock
DecompressCodeblock(uint16_t numLayers)
Definition Codeblock.h:202
grk::DecompressCodeblock::release
void release(void)
Definition Codeblock.h:277
grk::DecompressCodeblock::cleanUpSegBuffers
void cleanUpSegBuffers()
Definition Codeblock.h:250
grk::DecompressCodeblock::nextSegment
Segment * nextSegment(void)
Definition Codeblock.h:245
grk::DecompressCodeblock::seg_buffers
std::vector< grk_buf8 * > seg_buffers
Definition Codeblock.h:284
grk::DecompressCodeblock::getCurrentSegment
Segment * getCurrentSegment(void)
Definition Codeblock.h:241
grk::DecompressCodeblock::segs
Segment * segs
Definition Codeblock.h:287
grk::DecompressCodeblock::numSegments
uint32_t numSegments
Definition Codeblock.h:288
grk::DecompressCodeblock::getNumSegments
uint32_t getNumSegments(void)
Definition Codeblock.h:237
grk::DecompressCodeblock::getSegment
Segment * getSegment(uint32_t segmentIndex)
Definition Codeblock.h:213
grk::Layer
Definition Codeblock.h:56
grk::Layer::len
uint32_t len
Definition Codeblock.h:59
grk::Layer::distortion
double distortion
Definition Codeblock.h:60
grk::Layer::data
uint8_t * data
Definition Codeblock.h:61
grk::Layer::Layer
Layer()
Definition Codeblock.h:57
grk::Layer::numpasses
uint32_t numpasses
Definition Codeblock.h:58
grk::Segment
Definition Codeblock.h:24
grk::Segment::clear
void clear()
Definition Codeblock.h:29
grk::Segment::maxpasses
uint32_t maxpasses
Definition Codeblock.h:39
grk::Segment::len
uint32_t len
Definition Codeblock.h:38
grk::Segment::numBytesInPacket
uint32_t numBytesInPacket
Definition Codeblock.h:41
grk::Segment::numPassesInPacket
uint32_t numPassesInPacket
Definition Codeblock.h:40
grk::Segment::Segment
Segment()
Definition Codeblock.h:25
grk::Segment::numpasses
uint32_t numpasses
Definition Codeblock.h:37
grk::grk_buf2d
Definition buffer.h:230
grk::grk_buf< uint8_t, AllocatorVanilla >
grk::grk_buf::owns_data
bool owns_data
Definition buffer.h:198
grk::grk_buf::len
size_t len
Definition buffer.h:197
grk::grk_buf::dealloc
virtual void dealloc()
Definition buffer.h:117
grk::grk_buf::buf
T * buf
Definition buffer.h:195
grk::grk_buf::offset
size_t offset
Definition buffer.h:196
grk::grk_rect< uint32_t >
grk::grk_rect< uint32_t >::y1
uint32_t y1
Definition geometry.h:124
grk::grk_rect< uint32_t >::x0
uint32_t x0
Definition geometry.h:124
grk::grk_rect< uint32_t >::x1
uint32_t x1
Definition geometry.h:124
grk::grk_rect< uint32_t >::y0
uint32_t y0
Definition geometry.h:124
grk_cblk_enc_compressed_data_pad_left
const uint8_t grk_cblk_enc_compressed_data_pad_left
Definition t1_common.h:40