chromium/third_party/pdfium/third_party/libopenjpeg/ht_dec.c

//***************************************************************************/
// This software is released under the 2-Clause BSD license, included
// below.
//
// Copyright (c) 2021, Aous Naman
// Copyright (c) 2021, Kakadu Software Pty Ltd, Australia
// Copyright (c) 2021, The University of New South Wales, Australia
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
// IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
// TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//***************************************************************************/
// This file is part of the OpenJpeg software implementation.
// File: ht_dec.c
// Author: Aous Naman
// Date: 01 September 2021
//***************************************************************************/

//***************************************************************************/
/** @file ht_dec.c
 *  @brief implements HTJ2K block decoder
 */

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

#include "t1_ht_luts.h"

/////////////////////////////////////////////////////////////////////////////
// compiler detection
/////////////////////////////////////////////////////////////////////////////
#ifdef _MSC_VER
#define OPJ_COMPILER_MSVC
#elif (defined __GNUC__)
#define OPJ_COMPILER_GNUC
#endif

#if defined(OPJ_COMPILER_MSVC) && defined(_M_ARM64) \
    && !defined(_M_ARM64EC) && !defined(_M_CEE_PURE) && !defined(__CUDACC__) \
    && !defined(__INTEL_COMPILER) && !defined(__clang__)
#define MSVC_NEON_INTRINSICS
#endif

#ifdef MSVC_NEON_INTRINSICS
#include <arm64_neon.h>
#endif

//************************************************************************/
/** @brief Displays the error message for disabling the decoding of SPP and
  * MRP passes
  */
static OPJ_BOOL only_cleanup_pass_is_decoded =;

//************************************************************************/
/** @brief Generates population count (i.e., the number of set bits)
  *
  *   @param [in]  val is the value for which population count is sought
  */
static INLINE
OPJ_UINT32 population_count(OPJ_UINT32 val)
{}

//************************************************************************/
/** @brief Counts the number of leading zeros
  *
  *   @param [in]  val is the value for which leading zero count is sought
  */
#ifdef OPJ_COMPILER_MSVC
#pragma intrinsic(_BitScanReverse)
#endif
static INLINE
OPJ_UINT32 count_leading_zeros(OPJ_UINT32 val)
{}

//************************************************************************/
/** @brief Read a little-endian serialized UINT32.
  *
  *   @param [in]  dataIn pointer to byte stream to read from
  */
static INLINE OPJ_UINT32 read_le_uint32(const void* dataIn)
{}

//************************************************************************/
/** @brief 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.
  */
dec_mel_t;

//************************************************************************/
/** @brief 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.
  *
  *  @param [in]  melp is a pointer to dec_mel_t structure
  */
static INLINE
void mel_read(dec_mel_t *melp)
{}

//************************************************************************/
/** @brief 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.
  *
  *  @param [in]  melp is a pointer to dec_mel_t structure
  */
static INLINE
void mel_decode(dec_mel_t *melp)
{}

//************************************************************************/
/** @brief 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
  *
  *  @param [in]  melp is a pointer to dec_mel_t structure
  *  @param [in]  bbuf is a pointer to byte buffer
  *  @param [in]  lcup is the length of MagSgn+MEL+VLC segments
  *  @param [in]  scup is the length of MEL+VLC segments
  */
static INLINE
OPJ_BOOL mel_init(dec_mel_t *melp, OPJ_UINT8* bbuf, int lcup, int scup)
{}

//************************************************************************/
/** @brief Retrieves one run from dec_mel_t; if there are no runs stored
  *         MEL segment is decoded
  *
  * @param [in]  melp is a pointer to dec_mel_t structure
  */
static INLINE
int mel_get_run(dec_mel_t *melp)
{}

//************************************************************************/
/** @brief A structure for reading and unstuffing a segment that grows
  *         backward, such as VLC and MRP
  */
rev_struct_t;

//************************************************************************/
/** @brief 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).
  *
  *  @param [in]  vlcp is a pointer to rev_struct_t structure
  */
static INLINE
void rev_read(rev_struct_t *vlcp)
{}

//************************************************************************/
/** @brief 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.
  *
  *  @param [in]  vlcp is a pointer to rev_struct_t structure
  *  @param [in]  data is a pointer to byte at the start of the cleanup pass
  *  @param [in]  lcup is the length of MagSgn+MEL+VLC segments
  *  @param [in]  scup is the length of MEL+VLC segments
  */
static INLINE
void rev_init(rev_struct_t *vlcp, OPJ_UINT8* data, int lcup, int scup)
{}

//************************************************************************/
/** @brief 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
  *
  *  @param [in]  vlcp is a pointer to rev_struct structure
  */
static INLINE
OPJ_UINT32 rev_fetch(rev_struct_t *vlcp)
{}

//************************************************************************/
/** @brief Consumes num_bits from a rev_struct structure
  *
  *  @param [in]  vlcp is a pointer to rev_struct structure
  *  @param [in]  num_bits is the number of bits to be removed
  */
static INLINE
OPJ_UINT32 rev_advance(rev_struct_t *vlcp, OPJ_UINT32 num_bits)
{}

//************************************************************************/
/** @brief 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
  *
  *  @param [in]  mrp is a pointer to rev_struct structure
  */
static INLINE
void rev_read_mrp(rev_struct_t *mrp)
{}

//************************************************************************/
/** @brief 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.
  *
  *  @param [in]  mrp is a pointer to rev_struct structure
  *  @param [in]  data is a pointer to byte at the start of the cleanup pass
  *  @param [in]  lcup is the length of MagSgn+MEL+VLC segments
  *  @param [in]  len2 is the length of SPP+MRP segments
  */
static INLINE
void rev_init_mrp(rev_struct_t *mrp, OPJ_UINT8* data, int lcup, int len2)
{}

//************************************************************************/
/** @brief 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
  *
  *  @param [in]  mrp is a pointer to rev_struct structure
  */
static INLINE
OPJ_UINT32 rev_fetch_mrp(rev_struct_t *mrp)
{}

//************************************************************************/
/** @brief Consumes num_bits from a rev_struct structure
  *
  *  @param [in]  mrp is a pointer to rev_struct structure
  *  @param [in]  num_bits is the number of bits to be removed
  */
static INLINE
OPJ_UINT32 rev_advance_mrp(rev_struct_t *mrp, OPJ_UINT32 num_bits)
{}

//************************************************************************/
/** @brief Decode initial UVLC to get the u value (or u_q)
  *
  *  @param [in]  vlc is the head of the VLC bitstream
  *  @param [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.
  *  @param [out] u is the u value (or u_q) + 1.  Note: we produce u + 1;
  *               this value is a partial calculation of u + kappa.
  */
static INLINE
OPJ_UINT32 decode_init_uvlc(OPJ_UINT32 vlc, OPJ_UINT32 mode, OPJ_UINT32 *u)
{}

//************************************************************************/
/** @brief Decode non-initial UVLC to get the u value (or u_q)
  *
  *  @param [in]  vlc is the head of the VLC bitstream
  *  @param [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
  *  @param [out] u is the u value (or u_q) + 1.  Note: we produce u + 1;
  *               this value is a partial calculation of u + kappa.
  */
static INLINE
OPJ_UINT32 decode_noninit_uvlc(OPJ_UINT32 vlc, OPJ_UINT32 mode, OPJ_UINT32 *u)
{}

//************************************************************************/
/** @brief State structure for reading and unstuffing of forward-growing
  *         bitstreams; these are: MagSgn and SPP bitstreams
  */
frwd_struct_t;

//************************************************************************/
/** @brief 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 conpressed 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.
  *
  *  @param  [in]  msp is a pointer to frwd_struct_t structure
  *
  */
static INLINE
void frwd_read(frwd_struct_t *msp)
{}

//************************************************************************/
/** @brief Initialize frwd_struct_t struct and reads some bytes
  *
  *  @param [in]  msp is a pointer to frwd_struct_t
  *  @param [in]  data is a pointer to the start of data
  *  @param [in]  size is the number of byte in the bitstream
  *  @param [in]  X is the value fed in when the bitstream is exhausted.
  *               See frwd_read.
  */
static INLINE
void frwd_init(frwd_struct_t *msp, const OPJ_UINT8* data, int size,
               OPJ_UINT32 X)
{}

//************************************************************************/
/** @brief Consume num_bits bits from the bitstream of frwd_struct_t
  *
  *  @param [in]  msp is a pointer to frwd_struct_t
  *  @param [in]  num_bits is the number of bit to consume
  */
static INLINE
void frwd_advance(frwd_struct_t *msp, OPJ_UINT32 num_bits)
{}

//************************************************************************/
/** @brief Fetches 32 bits from the frwd_struct_t bitstream
  *
  *  @param [in]  msp is a pointer to frwd_struct_t
  */
static INLINE
OPJ_UINT32 frwd_fetch(frwd_struct_t *msp)
{}

//************************************************************************/
/** @brief Allocates T1 buffers
  *
  *  @param [in, out]  t1 is codeblock cofficients storage
  *  @param [in]       w is codeblock width
  *  @param [in]       h is codeblock height
  */
static OPJ_BOOL opj_t1_allocate_buffers(
    opj_t1_t *t1,
    OPJ_UINT32 w,
    OPJ_UINT32 h)
{}

/**
Decode 1 HT code-block
@param t1 T1 handle
@param cblk Code-block coding parameters
@param orient
@param roishift Region of interest shifting value
@param cblksty Code-block style
@param p_manager the event manager
@param p_manager_mutex mutex for the event manager
@param check_pterm whether PTERM correct termination should be checked
*/
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);

//************************************************************************/
/** @brief Decodes one codeblock, processing the cleanup, siginificance
  *         propagation, and magnitude refinement pass
  *
  *  @param [in, out]  t1 is codeblock cofficients storage
  *  @param [in]       cblk is codeblock properties
  *  @param [in]       orient is the subband to which the codeblock belongs (not needed)
  *  @param [in]       roishift is region of interest shift
  *  @param [in]       cblksty is codeblock style
  *  @param [in]       p_manager is events print manager
  *  @param [in]       p_manager_mutex a mutex to control access to p_manager
  *  @param [in]       check_pterm: check termination (not used)
  */
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)
{}