Skip to content

Commit

Permalink
Modified NLT, NLT Validity needs work
Browse files Browse the repository at this point in the history
  • Loading branch information
aous72 committed Jan 13, 2025
1 parent 579d7dd commit af15dd0
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 39 deletions.
57 changes: 32 additions & 25 deletions src/core/codestream/ojph_params.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -372,17 +372,17 @@ namespace ojph {
//
////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////////////////////////////////////////
void param_nlt::set_type3_transformation(ui32 comp_num, bool enable)
////////////////////////////////////////////////////////////////////////////
void param_nlt::set_nonlinearity(ui32 comp_num, nonlinearity type)
{
state->set_type3_transformation(comp_num, enable);
state->set_nonlinearity(comp_num, type);
}

//////////////////////////////////////////////////////////////////////////
bool param_nlt::get_type3_transformation(ui32 comp_num, ui8& bit_depth,
bool& is_signed)
////////////////////////////////////////////////////////////////////////////
bool param_nlt::get_nonlinearity(ui32 comp_num, ui8& bit_depth,
bool& is_signed, nonlinearity& type) const
{
return state->get_type3_transformation(comp_num, bit_depth, is_signed);
return state->get_nonlinearity(comp_num, bit_depth, is_signed, type);
}

////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1333,7 +1333,7 @@ namespace ojph {

// first stage; find out if all components captured by the default
// entry (ALL_COMPS) has the same bit_depth/signedness,
// while doing this, set the BDnlt for components not captured but the
// while doing this, set the BDnlt for components not captured by the
// default entry (ALL_COMPS)
ui32 bit_depth = 0; // unknown yet
bool is_signed = false; // unknown yet
Expand Down Expand Up @@ -1405,23 +1405,29 @@ namespace ojph {

trim_non_existing_components(num_comps);

if (is_any_enabled() == false)
return;
siz.set_Rsiz_flag(param_siz::RSIZ_EXT_FLAG | param_siz::RSIZ_NLT_FLAG);
if (is_any_enabled() == true)
siz.set_Rsiz_flag(param_siz::RSIZ_EXT_FLAG | param_siz::RSIZ_NLT_FLAG);
}

//////////////////////////////////////////////////////////////////////////
void param_nlt::set_type3_transformation(ui32 comp_num, bool enable)
void param_nlt::set_nonlinearity(ui32 comp_num, nonlinearity type)
{
if (type != ojph::param_nlt::OJPH_NLT_NO_NLT &&
type != ojph::param_nlt::OJPH_NLT_BINARY_COMPLEMENT_NLT)
OJPH_ERROR(0x00050171, "Nonliearity other than types 0 "
"(No Nonlinearity) and 3 (Binary Binary Complement to Sign Magnitude "
"Conversion) is not supported yet");
param_nlt* p = get_comp_object(comp_num);
if (p == NULL)
p = add_object(comp_num);
p->enabled = enable;
p->Tnlt = type;
p->enabled = true;
}

//////////////////////////////////////////////////////////////////////////
bool param_nlt::get_type3_transformation(ui32 comp_num, ui8& bit_depth,
bool& is_signed) const
bool
param_nlt::get_nonlinearity(ui32 comp_num, ui8& bit_depth, bool& is_signed,
nonlinearity& type) const
{
const param_nlt* p = get_comp_object(comp_num);
p = p ? p : this;
Expand All @@ -1430,8 +1436,10 @@ namespace ojph {
bit_depth = (ui8)((p->BDnlt & 0x7F) + 1);
bit_depth = bit_depth <= 38 ? bit_depth : 38;
is_signed = (p->BDnlt & 0x80) == 0x80;
type = (nonlinearity)p->Tnlt;
return true;
}
return p->enabled;
return false;
}

//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1499,14 +1507,10 @@ namespace ojph {
//////////////////////////////////////////////////////////////////////////
const param_nlt* param_nlt::get_comp_object(ui32 comp_num) const
{
if (Cnlt == comp_num)
return this;
else {
param_nlt* p = next;
while (p && p->Cnlt != comp_num)
p = p->next;
return p;
}
const param_nlt* p = this;
while (p && p->Cnlt != comp_num)
p = p->next;
return p;
}

//////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -1540,8 +1544,11 @@ namespace ojph {
{
param_nlt* p = this->next;
while (p) {
if (p->enabled == true && p->Cnlt >= num_comps)
if (p->enabled == true && p->Cnlt >= num_comps) {
p->enabled = false;
OJPH_INFO(0x00050161, "We are removing the NLT marker segment "
"for the non-existing component %d", p->Cnlt);
}
p = p->next;
}
}
Expand Down
9 changes: 5 additions & 4 deletions src/core/codestream/ojph_params_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -673,12 +673,13 @@ namespace ojph {
struct param_nlt
{
using special_comp_num = ojph::param_nlt::special_comp_num;
using nonlinearity = ojph::param_nlt::nonlinearity;
public:
param_nlt() {
Lnlt = 6;
Cnlt = special_comp_num::ALL_COMPS; // default
BDnlt = 0;
Tnlt = 3;
Tnlt = nonlinearity::OJPH_NLT_NO_NLT;
enabled = false; next = NULL; alloced_next = false;
}

Expand All @@ -691,9 +692,9 @@ namespace ojph {
}

void check_validity(param_siz& siz);
void set_type3_transformation(ui32 comp_num, bool enable);
bool get_type3_transformation(ui32 comp_num, ui8& bit_depth,
bool& is_signed) const;
void set_nonlinearity(ui32 comp_num, nonlinearity type);
bool get_nonlinearity(ui32 comp_num, ui8& bit_depth,
bool& is_signed, nonlinearity& type) const;
bool write(outfile_base* file) const;
void read(infile_base* file);

Expand Down
53 changes: 43 additions & 10 deletions src/core/common/ojph_params.h
Original file line number Diff line number Diff line change
Expand Up @@ -141,33 +141,66 @@ namespace ojph {
{
public:
enum special_comp_num : ui16 { ALL_COMPS = 65535 };
enum nonlinearity : ui8 {
OJPH_NLT_NO_NLT = 0, // supported
OJPH_NLT_GAMMA_STYLE_NLT = 1, // not supported
OJPH_NLT_LUT_STYLE_NLT = 2, // not supported
OJPH_NLT_BINARY_COMPLEMENT_NLT = 3 // supported
};
public:
param_nlt(local::param_nlt* p) : state(p) {}

/**
* @brief enables or disables type 3 nonlinearity for a component
* or the default setting
*
* If you think that you need type 3 nonlinearity for all components,
* call this function with comp_num set to 65535 and enable to true.
* When creating a codestream for writing, call this function before
* you call codestream::write_headers.
*
* There are a few things to know here.
* The NLT marker segment contains the nonlinearity type and the
* bit depth and signedness of the component to which it applies.
* There is the default component ALL_COMPS which applies to all
* components unless it is overridden by another NLT segment marker.
* The library checks that the settings make sense, and also make
* sure that bit depth and signedness are correct, creating any missing
* NLT marker segments.
* If all components have the same bit depth and signedness, and need
* nonlinearity type 3 (Binary Complement to Sign Magnitude Conversion),
* then the best option is to set ALL_COMPS to type 3.
* Otherwise, the best option is to set type 3 only to components that
* need it, leaving out the default ALL_COMPS nonlinearity not set.
* Another option is for the end-user can set the ALL_COMPS to type 3,
* and then put exception for the components that does not need type 3,
* by setting them to type 0.
*
* It also worth noting that type 3 nonlinearity has no effect on
* positive image samples. It is also not recommended for integer-valued
* types. It is only recommended for floating-points image samples for
* which some of the samples are negative, where type 3 nonlinearity
* should be beneficial. This is because the encoding engine expects
* two-complement representation for negative values while floating point
* numbers have a sign bit followed by an exponent, which has a biased
* integer representation. The core idea is to make floating-point
* representation more compatible with integer representation.
*
* @param comp_num: component number, or 65535 for the default setting
* @param enable: true to enable nlt type 3 for this component or the
default setting, false to disable nlt type 3.
* @param type: desired non-linearity from enum nonlinearity
*/
void set_type3_transformation(ui32 comp_num, bool enable);
void set_nonlinearity(ui32 comp_num, nonlinearity type);

/**
* @brief get the state (enabled or disabled) of type 3 nonlinearity
* for a component or the default setting
* @brief get the nonlinearity type associated with comp_num, which
* should be one from enum nonlinearity
*
* @param comp_num: component number, or 65535 for the default setting
* @param bit_depth: returns the bit depth of the component/default
* @param is_signed: returns true if the component/default is signed
* @return true if enabled or false if not.
* @param type: nonlinearity type
* @return true if the nonlinearity for comp_num is set
*/
bool get_type3_transformation(ui32 comp_num, ui8& bit_depth,
bool& is_signed);
bool get_nonlinearity(ui32 comp_num, ui8& bit_depth,
bool& is_signed, nonlinearity& type) const;

private:
local::param_nlt* state;
Expand Down

0 comments on commit af15dd0

Please sign in to comment.