ht_dec.c File Reference

implements HTJ2K block decoder More...

`#include <assert.h>`
`#include <string.h>`
`#include "opj_includes.h"`
`#include "t1_ht_luts.h"`

## Data Structures

struct | dec_mel
| MEL state structure for reading and decoding the MEL bitstream. More...
struct | rev_struct
| A structure for reading and unstuffing a segment that grows backward, such as VLC and MRP. More...
struct | frwd_struct
| State structure for reading and unstuffing of forward-growing bitstreams; these are: MagSgn and SPP bitstreams. More...

## Typedefs

typedef struct dec_mel | dec_mel_t
| MEL state structure for reading and decoding the MEL bitstream.
typedef struct rev_struct | rev_struct_t
| A structure for reading and unstuffing a segment that grows backward, such as VLC and MRP.
typedef struct frwd_struct | frwd_struct_t
| State structure for reading and unstuffing of forward-growing bitstreams; these are: MagSgn and SPP bitstreams.

## Functions

static INLINE OPJ_UINT32 | population_count (OPJ_UINT32 val)
| Generates population count (i.e., the number of set bits).
static INLINE OPJ_UINT32 | count_leading_zeros (OPJ_UINT32 val)
| Counts the number of leading zeros.
static INLINE OPJ_UINT32 | read_le_uint32 (const void *dataIn)
| Read a little-endian serialized UINT32.
static INLINE void | mel_read (dec_mel_t *melp)
| Reads and unstuffs the MEL bitstream.
static INLINE void | mel_decode (dec_mel_t *melp)
| Decodes unstuffed MEL segment bits stored in tmp to runs.
static INLINE OPJ_BOOL | mel_init (dec_mel_t *melp, OPJ_UINT8 *bbuf, int lcup, int scup)
| Initiates a dec_mel_t structure for MEL decoding and reads some bytes in order to get the read address to a multiple of 4.
static INLINE int | mel_get_run (dec_mel_t *melp)
| Retrieves one run from dec_mel_t; if there are no runs stored MEL segment is decoded.
static INLINE void | rev_read (rev_struct_t *vlcp)
| Read and unstuff data from a backwardly-growing segment.
static INLINE void | rev_init (rev_struct_t *vlcp, OPJ_UINT8 *data, int lcup, int scup)
| Initiates the rev_struct_t structure and reads a few bytes to move the read address to multiple of 4.
static INLINE OPJ_UINT32 | rev_fetch (rev_struct_t *vlcp)
| Retrieves 32 bits from the head of a rev_struct structure.
static INLINE OPJ_UINT32 | rev_advance (rev_struct_t *vlcp, OPJ_UINT32 num_bits)
| Consumes num_bits from a rev_struct structure.
static INLINE void | rev_read_mrp (rev_struct_t *mrp)
| Reads and unstuffs from rev_struct.
static INLINE void | rev_init_mrp (rev_struct_t *mrp, OPJ_UINT8 *data, int lcup, int len2)
| Initialized rev_struct structure for MRP segment, and reads a number of bytes such that the next 32 bits read are from an address that is a multiple of 4.
static INLINE OPJ_UINT32 | rev_fetch_mrp (rev_struct_t *mrp)
| Retrieves 32 bits from the head of a rev_struct structure.
static INLINE OPJ_UINT32 | rev_advance_mrp (rev_struct_t *mrp, OPJ_UINT32 num_bits)
| Consumes num_bits from a rev_struct structure.
static INLINE OPJ_UINT32 | decode_init_uvlc (OPJ_UINT32 vlc, OPJ_UINT32 mode, OPJ_UINT32 *u)
| Decode initial UVLC to get the u value (or u_q).
static INLINE OPJ_UINT32 | decode_noninit_uvlc (OPJ_UINT32 vlc, OPJ_UINT32 mode, OPJ_UINT32 *u)
| Decode non-initial UVLC to get the u value (or u_q).
static INLINE void | frwd_read (frwd_struct_t *msp)
| Read and unstuffs 32 bits from forward-growing bitstream.
static INLINE void | frwd_init (frwd_struct_t *msp, const OPJ_UINT8 *data, int size, OPJ_UINT32 X)
| Initialize frwd_struct_t struct and reads some bytes.
static INLINE void | frwd_advance (frwd_struct_t *msp, OPJ_UINT32 num_bits)
| Consume num_bits bits from the bitstream of frwd_struct_t.
static INLINE OPJ_UINT32 | frwd_fetch (frwd_struct_t *msp)
| Fetches 32 bits from the frwd_struct_t bitstream.
static OPJ_BOOL | opj_t1_allocate_buffers (opj_t1_t *t1, OPJ_UINT32 w, OPJ_UINT32 h)
| Allocates T1 buffers.
OPJ_BOOL | opj_t1_ht_decode_cblk (opj_t1_t *t1, opj_tcd_cblk_dec_t *cblk, OPJ_UINT32 orient, OPJ_UINT32 roishift, OPJ_UINT32 cblksty, opj_event_mgr_t *p_manager, opj_mutex_t *p_manager_mutex, OPJ_BOOL check_pterm)
| Decode 1 HT code-block.

## Variables

static OPJ_BOOL | only_cleanup_pass_is_decoded = OPJ_FALSE
| Displays the error message for disabling the decoding of SPP and MRP passes.

## Detailed Description

implements HTJ2K block decoder

## Typedef Documentation

## dec_mel_t

typedef struct dec_mel dec_mel_t

MEL state structure for reading and decoding the MEL bitstream.

A number of events is decoded from the MEL bitstream ahead of time and stored in run/num_runs. Each run represents the number of zero events before a one event.

## frwd_struct_t

typedef struct frwd_struct frwd_struct_t

State structure for reading and unstuffing of forward-growing bitstreams; these are: MagSgn and SPP bitstreams.

## rev_struct_t

typedef struct rev_struct rev_struct_t

A structure for reading and unstuffing a segment that grows backward, such as VLC and MRP.

## Function Documentation

## count_leading_zeros()

INLINE OPJ_UINT32 count_leading_zeros | ( | OPJ_UINT32 | val | ) |

static

Counts the number of leading zeros.

Parameters

  [in] | val | is the value for which leading zero count is sought

References population_count().

Referenced by opj_t1_ht_decode_cblk().

## decode_init_uvlc()

INLINE OPJ_UINT32 decode_init_uvlc | ( | OPJ_UINT32 | vlc,
|  | OPJ_UINT32 | mode,
|  | OPJ_UINT32 * | u )

static

Decode initial UVLC to get the u value (or u_q).

Parameters

  [in] | vlc | is the head of the VLC bitstream
  [in] | mode | is 0, 1, 2, 3, or 4. Values in 0 to 3 are composed of u_off of 1st quad and 2nd quad of a quad pair. The value 4 occurs when both bits are 1, and the event decoded from MEL bitstream is also 1.
  [out] | u | is the u value (or u_q) + 1. Note: we produce u + 1; this value is a partial calculation of u + kappa.

Referenced by opj_t1_ht_decode_cblk().

## decode_noninit_uvlc()

INLINE OPJ_UINT32 decode_noninit_uvlc | ( | OPJ_UINT32 | vlc,
|  | OPJ_UINT32 | mode,
|  | OPJ_UINT32 * | u )

static

Decode non-initial UVLC to get the u value (or u_q).

Parameters

  [in] | vlc | is the head of the VLC bitstream
  [in] | mode | is 0, 1, 2, or 3. The 1st bit is u_off of 1st quad and 2nd for 2nd quad of a quad pair
  [out] | u | is the u value (or u_q) + 1. Note: we produce u + 1; this value is a partial calculation of u + kappa.

Referenced by opj_t1_ht_decode_cblk().

## frwd_advance()

INLINE void frwd_advance | ( | frwd_struct_t * | msp,
|  | OPJ_UINT32 | num_bits )

static

Consume num_bits bits from the bitstream of frwd_struct_t.

Parameters

  [in] | msp | is a pointer to frwd_struct_t
  [in] | num_bits | is the number of bit to consume

References frwd_struct::bits, and frwd_struct::tmp.

Referenced by opj_t1_ht_decode_cblk().

## frwd_fetch()

INLINE OPJ_UINT32 frwd_fetch | ( | frwd_struct_t * | msp | ) |

static

Fetches 32 bits from the frwd_struct_t bitstream.

Parameters

  [in] | msp | is a pointer to frwd_struct_t

References frwd_struct::bits, frwd_read(), and frwd_struct::tmp.

Referenced by opj_t1_ht_decode_cblk().

## frwd_init()

INLINE void frwd_init | ( | frwd_struct_t * | msp,
|  | const OPJ_UINT8 * | data,
|  | int | size,
|  | OPJ_UINT32 | X )

static

Initialize frwd_struct_t struct and reads some bytes.

Parameters

  [in] | msp | is a pointer to frwd_struct_t
  [in] | data | is a pointer to the start of data
  [in] | size | is the number of byte in the bitstream
  [in] | X | is the value fed in when the bitstream is exhausted. See frwd_read.

References frwd_struct::bits, frwd_struct::data, frwd_read(), OPJ_FALSE, frwd_struct::size, frwd_struct::tmp, frwd_struct::unstuff, and frwd_struct::X.

Referenced by opj_t1_ht_decode_cblk().

## frwd_read()

INLINE void frwd_read | ( | frwd_struct_t * | msp | ) |

static

Read and unstuffs 32 bits from forward-growing bitstream.

A subroutine to read from both the MagSgn or SPP bitstreams; in particular, when MagSgn bitstream is consumed, 0xFF's are fed, while when SPP is exhausted 0's are fed in. X controls this value.

Unstuffing prevent sequences that are more than 0xFF7F from appearing in the compressed sequence. So whenever a value of 0xFF is coded, the MSB of the next byte is set 0 and must be ignored during decoding.

Reading can go beyond the end of buffer by up to 3 bytes.

Parameters

  [in] | msp | is a pointer to frwd_struct_t structure

References frwd_struct::bits, frwd_struct::data, read_le_uint32(), frwd_struct::size, frwd_struct::tmp, frwd_struct::unstuff, and frwd_struct::X.

Referenced by frwd_fetch(), and frwd_init().

## mel_decode()

INLINE void mel_decode | ( | dec_mel_t * | melp | ) |

static

Decodes unstuffed MEL segment bits stored in tmp to runs.

Runs are stored in "runs" and the number of runs in "num_runs". Each run represents a number of zero events that may or may not terminate in a 1 event. Each run is stored in 7 bits. The LSB is 1 if the run terminates in a 1 event, 0 otherwise. The next 6 bits, for the case terminating with 1, contain the number of consecutive 0 zero events * 2; for the case terminating with 0, they store (number of consecutive 0 zero events - 1) * 2. A total of 6 bits (made up of 1 + 5) should have been enough.

Parameters

  [in] | melp | is a pointer to dec_mel_t structure

References dec_mel::bits, dec_mel::k, mel_read(), dec_mel::num_runs, dec_mel::runs, and dec_mel::tmp.

Referenced by mel_get_run().

## mel_get_run()

INLINE int mel_get_run | ( | dec_mel_t * | melp | ) |

static

Retrieves one run from dec_mel_t; if there are no runs stored MEL segment is decoded.

Parameters

  [in] | melp | is a pointer to dec_mel_t structure

References mel_decode(), dec_mel::num_runs, and dec_mel::runs.

Referenced by opj_t1_ht_decode_cblk().

## mel_init()

INLINE OPJ_BOOL mel_init | ( | dec_mel_t * | melp,
|  | OPJ_UINT8 * | bbuf,
|  | int | lcup,
|  | int | scup )

static

Initiates a dec_mel_t structure for MEL decoding and reads some bytes in order to get the read address to a multiple of 4.

Parameters

  [in] | melp | is a pointer to dec_mel_t structure
  [in] | bbuf | is a pointer to byte buffer
  [in] | lcup | is the length of MagSgn+MEL+VLC segments
  [in] | scup | is the length of MEL+VLC segments

References dec_mel::bits, dec_mel::data, dec_mel::k, dec_mel::num_runs, OPJ_FALSE, OPJ_TRUE, dec_mel::runs, dec_mel::size, dec_mel::tmp, and dec_mel::unstuff.

Referenced by opj_t1_ht_decode_cblk().

## mel_read()

INLINE void mel_read | ( | dec_mel_t * | melp | ) |

static

Reads and unstuffs the MEL bitstream.

This design needs more bytes in the codeblock buffer than the length of the cleanup pass by up to 2 bytes.

Unstuffing removes the MSB of the byte following a byte whose value is 0xFF; this prevents sequences larger than 0xFF7F in value from appearing the bitstream.

Parameters

  [in] | melp | is a pointer to dec_mel_t structure

References dec_mel::bits, dec_mel::data, read_le_uint32(), dec_mel::size, dec_mel::tmp, and dec_mel::unstuff.

Referenced by mel_decode().

## opj_t1_allocate_buffers()

OPJ_BOOL opj_t1_allocate_buffers | ( | opj_t1_t * | t1,
|  | OPJ_UINT32 | w,
|  | OPJ_UINT32 | h )

static

Allocates T1 buffers.

Parameters

  [in,out] | t1 | is codeblock coefficients storage
  [in] | w | is codeblock width
  [in] | h | is codeblock height

References opj_t1::data, opj_t1::datasize, opj_t1::flags, opj_t1::flagssize, opj_t1::h, opj_aligned_free(), opj_aligned_malloc(), OPJ_FALSE, OPJ_TRUE, and opj_t1::w.

Referenced by opj_t1_ht_decode_cblk().

## opj_t1_ht_decode_cblk()

OPJ_BOOL opj_t1_ht_decode_cblk | ( | opj_t1_t * | t1,
|  | opj_tcd_cblk_dec_t * | cblk,
|  | OPJ_UINT32 | orient,
|  | OPJ_UINT32 | roishift,
|  | OPJ_UINT32 | cblksty,
|  | opj_event_mgr_t * | p_manager,
|  | opj_mutex_t * | p_manager_mutex,
|  | OPJ_BOOL | check_pterm )

Decode 1 HT code-block.

Decodes one codeblock, processing the cleanup, siginificance propagation, and magnitude refinement pass.

Parameters

  | t1 | T1 handle
  | cblk | Code-block coding parameters
  | orient |
  | roishift | Region of interest shifting value
  | cblksty | Code-block style
  | p_manager | the event manager
  | p_manager_mutex | mutex for the event manager
  | check_pterm | whether PTERM correct termination should be checked
  [in,out] | t1 | is codeblock coefficients storage
  [in] | cblk | is codeblock properties
  [in] | orient | is the subband to which the codeblock belongs (not needed)
  [in] | roishift | is region of interest shift
  [in] | cblksty | is codeblock style
  [in] | p_manager | is events print manager
  [in] | p_manager_mutex | a mutex to control access to p_manager
  [in] | check_pterm | check termination (not used)

State storage One byte per quad; for 1024 columns, or 512 quads, we need 512 bytes. We are using 2 extra bytes one on the left and one on the right for convenience.

The MSB bit in each byte is (\sigma^nw | \sigma^n), and the 7 LSBs contain max(E^nw | E^n)

References opj_t1::cblkdatabuffer, opj_t1::cblkdatabuffersize, opj_tcd_cblk_dec::chunks, count_leading_zeros(), opj_t1::data, opj_tcd_seg_data_chunk::data, decode_init_uvlc(), decode_noninit_uvlc(), EVT_ERROR, EVT_WARNING, opj_t1::flags, frwd_advance(), frwd_fetch(), frwd_init(), J2K_CCP_CBLKSTY_VSC, opj_tcd_seg::len, opj_tcd_seg_data_chunk::len, opj_tcd_cblk_dec::Mb, mel_get_run(), mel_init(), opj_t1::mustuse_cblkdatabuffer, opj_tcd_cblk_dec::numbps, opj_tcd_cblk_dec::numchunks, opj_tcd_cblk_dec::numsegs, only_cleanup_pass_is_decoded, opj_event_msg(), OPJ_FALSE, opj_mutex_lock(), opj_mutex_unlock(), opj_realloc(), opj_t1_allocate_buffers(), OPJ_TRUE, population_count(), opj_tcd_seg::real_num_passes, rev_advance(), rev_advance_mrp(), rev_fetch(), rev_fetch_mrp(), rev_init(), rev_init_mrp(), opj_tcd_cblk_dec::segs, vlc_tbl0, vlc_tbl1, opj_tcd_cblk_dec::x0, opj_tcd_cblk_dec::x1, opj_tcd_cblk_dec::y0, and opj_tcd_cblk_dec::y1.

Referenced by opj_t1_clbl_decode_processor().

## population_count()

INLINE OPJ_UINT32 population_count | ( | OPJ_UINT32 | val | ) |

static

Generates population count (i.e., the number of set bits).

Parameters

  [in] | val | is the value for which population count is sought

Referenced by count_leading_zeros(), and opj_t1_ht_decode_cblk().

## read_le_uint32()

INLINE OPJ_UINT32 read_le_uint32 | ( | const void * | dataIn | ) |

static

Read a little-endian serialized UINT32.

Parameters

  [in] | dataIn | pointer to byte stream to read from

References INLINE.

Referenced by frwd_read(), mel_read(), rev_read(), and rev_read_mrp().

## rev_advance()

INLINE OPJ_UINT32 rev_advance | ( | rev_struct_t * | vlcp,
|  | OPJ_UINT32 | num_bits )

static

Consumes num_bits from a rev_struct structure.

Parameters

  [in] | vlcp | is a pointer to rev_struct structure
  [in] | num_bits | is the number of bits to be removed

References rev_struct::bits, and rev_struct::tmp.

Referenced by opj_t1_ht_decode_cblk().

## rev_advance_mrp()

INLINE OPJ_UINT32 rev_advance_mrp | ( | rev_struct_t * | mrp,
|  | OPJ_UINT32 | num_bits )

static

Consumes num_bits from a rev_struct structure.

Parameters

  [in] | mrp | is a pointer to rev_struct structure
  [in] | num_bits | is the number of bits to be removed

References rev_struct::bits, and rev_struct::tmp.

Referenced by opj_t1_ht_decode_cblk().

## rev_fetch()

INLINE OPJ_UINT32 rev_fetch | ( | rev_struct_t * | vlcp | ) |

static

Retrieves 32 bits from the head of a rev_struct structure.

By the end of this call, vlcp->tmp must have no less than 33 bits

Parameters

  [in] | vlcp | is a pointer to rev_struct structure

References rev_struct::bits, rev_read(), and rev_struct::tmp.

Referenced by opj_t1_ht_decode_cblk().

## rev_fetch_mrp()

INLINE OPJ_UINT32 rev_fetch_mrp | ( | rev_struct_t * | mrp | ) |

static

Retrieves 32 bits from the head of a rev_struct structure.

By the end of this call, mrp->tmp must have no less than 33 bits

Parameters

  [in] | mrp | is a pointer to rev_struct structure

References rev_struct::bits, rev_read_mrp(), and rev_struct::tmp.

Referenced by opj_t1_ht_decode_cblk().

## rev_init()

INLINE void rev_init | ( | rev_struct_t * | vlcp,
|  | OPJ_UINT8 * | data,
|  | int | lcup,
|  | int | scup )

static

Initiates the rev_struct_t structure and reads a few bytes to move the read address to multiple of 4.

There is another similar rev_init_mrp subroutine. The difference is that this one, rev_init, discards the first 12 bits (they have the sum of the lengths of VLC and MEL segments), and first unstuff depends on first 4 bits.

Parameters

  [in] | vlcp | is a pointer to rev_struct_t structure
  [in] | data | is a pointer to byte at the start of the cleanup pass
  [in] | lcup | is the length of MagSgn+MEL+VLC segments
  [in] | scup | is the length of MEL+VLC segments

References rev_struct::bits, rev_struct::data, rev_read(), rev_struct::size, rev_struct::tmp, and rev_struct::unstuff.

Referenced by opj_t1_ht_decode_cblk().

## rev_init_mrp()

INLINE void rev_init_mrp | ( | rev_struct_t * | mrp,
|  | OPJ_UINT8 * | data,
|  | int | lcup,
|  | int | len2 )

static

Initialized rev_struct structure for MRP segment, and reads a number of bytes such that the next 32 bits read are from an address that is a multiple of 4.

Note this is designed for an architecture that read size must be compatible with the alignment of the read address

There is another similar subroutine rev_init. This subroutine does NOT skip the first 12 bits, and starts with unstuff set to true.

Parameters

  [in] | mrp | is a pointer to rev_struct structure
  [in] | data | is a pointer to byte at the start of the cleanup pass
  [in] | lcup | is the length of MagSgn+MEL+VLC segments
  [in] | len2 | is the length of SPP+MRP segments

References rev_struct::bits, rev_struct::data, OPJ_TRUE, rev_read_mrp(), rev_struct::size, rev_struct::tmp, and rev_struct::unstuff.

Referenced by opj_t1_ht_decode_cblk().

## rev_read()

INLINE void rev_read | ( | rev_struct_t * | vlcp | ) |

static

Read and unstuff data from a backwardly-growing segment.

This reader can read up to 8 bytes from before the VLC segment. Care must be taken not read from unreadable memory, causing a segmentation fault.

Note that there is another subroutine rev_read_mrp that is slightly different. The other one fills zeros when the buffer is exhausted. This one basically does not care if the bytes are consumed, because any extra data should not be used in the actual decoding.

Unstuffing is needed to prevent sequences more than 0xFF8F from appearing in the bits stream; since we are reading backward, we keep watch when a value larger than 0x8F appears in the bitstream. If the byte following this is 0x7F, we unstuff this byte (ignore the MSB of that byte, which should be 0).

Parameters

  [in] | vlcp | is a pointer to rev_struct_t structure

References rev_struct::bits, rev_struct::data, read_le_uint32(), rev_struct::size, rev_struct::tmp, and rev_struct::unstuff.

Referenced by rev_fetch(), and rev_init().

## rev_read_mrp()

INLINE void rev_read_mrp | ( | rev_struct_t * | mrp | ) |

static

Reads and unstuffs from rev_struct.

This is different than rev_read in that this fills in zeros when the the available data is consumed. The other does not care about the values when all data is consumed.

See rev_read for more information about unstuffing

Parameters

  [in] | mrp | is a pointer to rev_struct structure

References rev_struct::bits, rev_struct::data, read_le_uint32(), rev_struct::size, rev_struct::tmp, and rev_struct::unstuff.

Referenced by rev_fetch_mrp(), and rev_init_mrp().

## Variable Documentation

## only_cleanup_pass_is_decoded

OPJ_BOOL only_cleanup_pass_is_decoded = OPJ_FALSE

static

Displays the error message for disabling the decoding of SPP and MRP passes.

Referenced by opj_t1_ht_decode_cblk().