Skip to content

Commit

Permalink
Added support for the QCC marker in the main header.
Browse files Browse the repository at this point in the history
This is made necessary by the fact that Kakadu now produces these markers when Qfactor is used.
  • Loading branch information
aous72 committed Nov 4, 2020
1 parent a90c645 commit ecd73ef
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 29 deletions.
54 changes: 33 additions & 21 deletions src/core/codestream/ojph_codestream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -216,9 +216,11 @@ namespace ojph {
resilient = false;
skipped_res_for_read = skipped_res_for_recon = 0;


precinct_scratch_needed_bytes = 0;

used_qcc_fields = 0;
qcc = qcc_store;

allocator = new mem_fixed_allocator;
elastic_alloc = new mem_elastic_allocator(1048576); //1 megabyte

Expand All @@ -229,6 +231,8 @@ namespace ojph {
////////////////////////////////////////////////////////////////////////////
codestream::~codestream()
{
if (qcc_store != qcc)
delete[] qcc;
if (allocator)
delete allocator;
if (elastic_alloc)
Expand Down Expand Up @@ -838,8 +842,15 @@ namespace ojph {
else if (marker_idx == 5)
{ qcd.read(file); received_markers |= 2; }
else if (marker_idx == 6)
skip_marker(file, "QCC", "QCC is not supported yet",
OJPH_MSG_LEVEL::WARN, false);
{
int num_comps = siz.get_num_components();
if (qcc == qcc_store &&
num_comps * sizeof(param_qcc) > sizeof(qcc_store))
{
qcc = new param_qcc[num_comps];
}
qcc[used_qcc_fields++].read(file, num_comps);
}
else if (marker_idx == 7)
skip_marker(file, "RGN", "RGN is not supported yet",
OJPH_MSG_LEVEL::WARN, false);
Expand Down Expand Up @@ -1903,8 +1914,8 @@ namespace ojph {

this->comp_num = comp_num;
res = allocator->post_alloc_obj<resolution>(1);
res->finalize_alloc(codestream, comp_rect, recon_comp_rect, num_decomps,
comp_downsamp, this, NULL);
res->finalize_alloc(codestream, comp_rect, recon_comp_rect, comp_num,
num_decomps, comp_downsamp, this, NULL);
}

//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -2143,7 +2154,7 @@ namespace ojph {
void resolution::finalize_alloc(codestream *codestream,
const rect& res_rect,
const rect& recon_res_rect,
int res_num,
int comp_num, int res_num,
point comp_downsamp,
tile_comp *parent_tile,
resolution *parent_res)
Expand All @@ -2161,6 +2172,7 @@ namespace ojph {
this->parent = parent_tile;
this->parent_res = parent_res;
this->res_rect = res_rect;
this->comp_num = comp_num;
this->res_num = res_num;
//finalize next resolution
if (res_num > 0)
Expand All @@ -2178,8 +2190,8 @@ namespace ojph {
next_res_rect.siz.h = try1 - try0;

child_res->finalize_alloc(codestream, next_res_rect,
skipped_res_for_recon ? recon_res_rect : next_res_rect, res_num - 1,
comp_downsamp, parent_tile, this);
skipped_res_for_recon ? recon_res_rect : next_res_rect, comp_num,
res_num - 1, comp_downsamp, parent_tile, this);
}
else
child_res = NULL;
Expand Down Expand Up @@ -3390,7 +3402,7 @@ namespace ojph {
{
ui32 bit;
if (bb_read_bit(&bb, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p1"; }
empty_cb = (bit == 0);
*inc_tag.get(x>>cur_lev, y>>cur_lev, cur_lev) = (ui8)(1 - bit);
*inc_tag_flags.get(x>>cur_lev, y>>cur_lev, cur_lev) = 1;
Expand All @@ -3415,7 +3427,7 @@ namespace ojph {
while (bit == 0)
{
if (bb_read_bit(&bb, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p2"; }
mmsbs += 1 - bit;
}
*mmsb_tag.get(x>>cur_lev, y>>cur_lev, cur_lev) = (ui8)mmsbs;
Expand All @@ -3430,26 +3442,26 @@ namespace ojph {
//get number of passes
ui32 bit, num_passes = 1;
if (bb_read_bit(&bb, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p3"; }
if (bit)
{
num_passes = 2;
if (bb_read_bit(&bb, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p4"; }
if (bit)
{
if (bb_read_bits(&bb, 2, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p5"; }
num_passes = 3 + bit;
if (bit == 3)
{
if (bb_read_bits(&bb, 5, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p6"; }
num_passes = 6 + bit;
if (bit == 31)
{
if (bb_read_bits(&bb, 7, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p7"; }
num_passes = 37 + bit;
}
}
Expand All @@ -3465,17 +3477,17 @@ namespace ojph {
while (bit)
{
if (bb_read_bit(&bb, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p8"; }
bits1 += bit;
}

if (bb_read_bits(&bb, bits1, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p9"; }
cp->pass_length[0] = bit;
if (num_passes > 1)
{
if (bb_read_bits(&bb, bits1 + extra_bit, bit) == false)
{ data_left = 0; throw "error reading from file"; }
{ data_left = 0; throw "error reading from file p10"; }
cp->pass_length[1] = bit;
}
}
Expand Down Expand Up @@ -3606,11 +3618,11 @@ namespace ojph {
cur_cb_row = 0;
cur_line = 0;
cur_cb_height = 0;
param_qcd qcd = codestream->access_qcd();
this->K_max = qcd.get_Kmax(this->res_num, band_num);
param_qcd *qcd = codestream->access_qcd(parent->get_comp_num());
this->K_max = qcd->get_Kmax(this->res_num, band_num);
if (!reversible)
{
float d = qcd.irrev_get_delta(res_num, subband_num);
float d = qcd->irrev_get_delta(res_num, subband_num);
d /= (float)(1u << (31 - this->K_max));
delta = d;
delta_inv = (1.0f/d);
Expand Down
19 changes: 16 additions & 3 deletions src/core/codestream/ojph_codestream_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,14 @@ namespace ojph {
{ return ojph::param_cod(&cod); }
const param_cod* get_cod() //return internal code
{ return &cod; }
param_qcd access_qcd()
{ return qcd; }
param_qcd* access_qcd(int comp_num)
{
if (used_qcc_fields > 0)
for (int v = 0; v < used_qcc_fields; ++v)
if (qcc[v].get_comp_num() == comp_num)
return qcc + v;
return &qcd;
}
mem_fixed_allocator* get_allocator() { return allocator; }
mem_elastic_allocator* get_elastic_alloc() { return elastic_alloc; }
outfile_base* get_file() { return outfile; }
Expand Down Expand Up @@ -146,6 +152,11 @@ namespace ojph {
param_qcd qcd;
param_tlm tlm;

private: // this is to handle qcc
int used_qcc_fields;
param_qcc qcc_store[4], *qcc; // we allocate 4,
// if not enough, we allocate more

private:
mem_fixed_allocator *allocator;
mem_elastic_allocator *elastic_alloc;
Expand Down Expand Up @@ -238,7 +249,7 @@ namespace ojph {
static void pre_alloc(codestream *codestream, const rect& res_rect,
const rect& recon_res_rect, int res_num);
void finalize_alloc(codestream *codestream, const rect& res_rect,
const rect& recon_res_rect,
const rect& recon_res_rect, int comp_num,
int res_num, point comp_downsamp,
tile_comp *parent_tile,
resolution *parent_res);
Expand All @@ -247,6 +258,7 @@ namespace ojph {
void push_line();
line_buf* pull_line();
rect get_rect() { return res_rect; }
int get_comp_num() { return comp_num; }

ui32 prepare_precinct();
void write_precincts(outfile_base *file);
Expand All @@ -259,6 +271,7 @@ namespace ojph {
private:
bool reversible, skipped_res_for_read, skipped_res_for_recon;
int num_lines, num_bands, res_num;
int comp_num;
point comp_downsamp;
rect res_rect;
line_buf *lines;
Expand Down
65 changes: 64 additions & 1 deletion src/core/codestream/ojph_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,7 @@ namespace ojph {
}
else if ((Sqcd & 0x1F) == 2)
{
num_decomps = (Lqcd - 4) / 6;
num_decomps = (Lqcd - 5) / 6;
if (Lqcd != 5 + 6 * num_decomps)
OJPH_ERROR(0x00050086, "wrong Lqcd value in QCD marker");
for (int i = 0; i < 1 + 3 * num_decomps; ++i)
Expand All @@ -966,6 +966,69 @@ namespace ojph {
//
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
void param_qcc::read(infile_base *file, int num_comps)
{
if (file->read(&Lqcd, 2) != 2)
OJPH_ERROR(0x000500A1, "error reading QCC marker");
Lqcd = swap_byte(Lqcd);
if (num_comps < 257)
{
ui8 v;
if (file->read(&v, 1) != 1)
OJPH_ERROR(0x000500A2, "error reading QCC marker");
comp_idx = v;
}
else
{
if (file->read(&comp_idx, 2) != 2)
OJPH_ERROR(0x000500A3, "error reading QCC marker");
comp_idx = swap_byte(comp_idx);
}
if (file->read(&Sqcd, 1) != 1)
OJPH_ERROR(0x000500A4, "error reading QCC marker");
if ((Sqcd & 0x1F) == 0)
{
int offset = num_comps < 257 ? 5 : 6;
num_decomps = (Lqcd - offset) / 3;
if (Lqcd != offset + 3 * num_decomps)
OJPH_ERROR(0x000500A5, "wrong Lqcd value in QCC marker");
for (int i = 0; i < 1 + 3 * num_decomps; ++i)
if (file->read(&u8_SPqcd[i], 1) != 1)
OJPH_ERROR(0x000500A6, "error reading QCC marker");
}
else if ((Sqcd & 0x1F) == 1)
{
int offset = num_comps < 257 ? 6 : 7;
num_decomps = -1;
if (Lqcd != offset)
OJPH_ERROR(0x000500A7, "wrong Lqcc value in QCC marker");
}
else if ((Sqcd & 0x1F) == 2)
{
int offset = num_comps < 257 ? 6 : 7;
num_decomps = (Lqcd - offset) / 6;
if (Lqcd != offset + 6 * num_decomps)
OJPH_ERROR(0x000500A8, "wrong Lqcd value in QCC marker");
for (int i = 0; i < 1 + 3 * num_decomps; ++i)
{
if (file->read(&u16_SPqcd[i], 2) != 2)
OJPH_ERROR(0x000500A9, "error reading QCC marker");
u16_SPqcd[i] = swap_byte(u16_SPqcd[i]);
}
}
else
OJPH_ERROR(0x000500AA, "wrong Sqcd value in QCC marker");
}

//////////////////////////////////////////////////////////////////////////
//
//
//
//
//
//////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
bool param_sot::write(outfile_base *file, ui32 payload_len)
{
Expand Down
34 changes: 31 additions & 3 deletions src/core/codestream/ojph_params_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ namespace ojph {
PLT = 0xFF58, //packet length, tile-part header
CPF = 0xFF59, //corresponding profile values
QCD = 0xFF5C, //qunatization default (required)
QCC = 0xFF5D, //quantization component
COM = 0xFF64, //comment
SOT = 0xFF90, //start of tile-part
SOP = 0xFF91, //start of packet
Expand All @@ -116,7 +117,6 @@ namespace ojph {
EOC = 0xFFD9, //end of codestream (required)

COC = 0xFF53, //coding style component
QCC = 0xFF5D, //quantization component
RGN = 0xFF5E, //region of interest
POC = 0xFF5F, //progression order change
PPM = 0xFF60, //packed packet headers, main header
Expand Down Expand Up @@ -424,7 +424,14 @@ namespace ojph {
friend ::ojph::param_qcd;
public:
param_qcd()
{ memset(this, 0, sizeof(param_qcd)); base_delta = -1.0f; }
{
Lqcd = 0;
Sqcd = 0;
for (int i = 0; i < 97; ++i)
u16_SPqcd[i] = 0;
num_decomps = 0;
base_delta = -1.0f;
}

void set_delta(float delta) { base_delta = delta; }
void set_rev_quant(int bit_depth, bool is_employing_color_transform);
Expand Down Expand Up @@ -457,7 +464,7 @@ namespace ojph {
bool write(outfile_base *file);
void read(infile_base *file);

private:
protected:
ui16 Lqcd;
ui8 Sqcd;
union
Expand All @@ -469,6 +476,27 @@ namespace ojph {
float base_delta;
};

///////////////////////////////////////////////////////////////////////////
//
//
//
//
//
///////////////////////////////////////////////////////////////////////////
struct param_qcc : public param_qcd
{
friend ::ojph::param_qcc;
public:
param_qcc() : param_qcd()
{ comp_idx = 0; }

ui16 get_comp_num() { return comp_idx; }
void read(infile_base *file, int num_comps);

protected:
ui16 comp_idx;
};

///////////////////////////////////////////////////////////////////////////
//
//
Expand Down
12 changes: 12 additions & 0 deletions src/core/common/ojph_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ namespace ojph {
struct param_siz;
struct param_cod;
struct param_qcd;
struct param_qcc;
struct param_cap;
}

Expand Down Expand Up @@ -165,6 +166,17 @@ namespace ojph {
local::param_qcd* state;
};

////////////////////////////////////////////////////////////////////////////
class param_qcc
{
public:
OJPH_EXPORT
param_qcc(local::param_qcc* p) : state(p) {}

private:
local::param_qcc* state;
};

}

#endif // !OJPH_PARAMS_H
2 changes: 1 addition & 1 deletion src/core/common/ojph_version.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@

#define OPENJPH_VERSION_MAJOR 0
#define OPENJPH_VERSION_MINOR 7
#define OPENJPH_VERSION_PATCH 1
#define OPENJPH_VERSION_PATCH 2

0 comments on commit ecd73ef

Please sign in to comment.