⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mq_encoder.h

📁 该源码是JPEG2000的c++源代码,希望对研究JPEG2000标准以及编解码的朋友们有用.
💻 H
📖 第 1 页 / 共 2 页
字号:
/*****************************************************************************/// File: mq_encoder.h [scope = CORESYS/CODING]// Version: Kakadu, V2.2// Author: David Taubman// Last Revised: 20 June, 2001/*****************************************************************************/// Copyright 2001, David Taubman, The University of New South Wales (UNSW)// The copyright owner is Unisearch Ltd, Australia (commercial arm of UNSW)// Neither this copyright statement, nor the licensing details below// may be removed from this file or dissociated from its contents./*****************************************************************************/// Licensee: Book Owner// License number: 99999// The Licensee has been granted a NON-COMMERCIAL license to the contents of// this source file, said Licensee being the owner of a copy of the book,// "JPEG2000: Image Compression Fundamentals, Standards and Practice," by// Taubman and Marcellin (Kluwer Academic Publishers, 2001).  A brief summary// of the license appears below.  This summary is not to be relied upon in// preference to the full text of the license agreement, which was accepted// upon breaking the seal of the compact disc accompanying the above-mentioned// book.// 1. The Licensee has the right to Non-Commercial Use of the Kakadu software,//    Version 2.2, including distribution of one or more Applications built//    using the software, provided such distribution is not for financial//    return.// 2. The Licensee has the right to personal use of the Kakadu software,//    Version 2.2.// 3. The Licensee has the right to distribute Reusable Code (including//    source code and dynamically or statically linked libraries) to a Third//    Party, provided the Third Party possesses a license to use the Kakadu//    software, Version 2.2, and provided such distribution is not for//    financial return./******************************************************************************Description:   Defines interfaces for the low-level binary symbol operations associatedwith the MQ coder.  Includes, interfaces to support the arithetic coder bypassmode as well.  Also includes macros which may be used as substitutes for thecoding functions.  Both the macros and the functions achieve the sameresult, although the macro implementation is more carefully tuned for speed,while the function implementation is somewhat more dydactic.******************************************************************************/#ifndef MQ_ENCODER_H#define MQ_ENCODER_H#include <assert.h>#include "kdu_messaging.h"// Defined here:struct mqe_state;struct mqe_transition;class mq_encoder;/* ========================================================================= *//*                                Constants                                  *//* ========================================================================= */#define MQE_SPACER 3#define MQE_CARRY_POS (16+MQE_SPACER+8)#define MQE_CARRY_BIT ((kdu_int32)(1<<MQE_CARRY_POS))#define MQE_PARTIAL_POS (16+MQE_SPACER)#define MQE_PARTIAL_CLEAR (~(((kdu_int32)(-1))<<MQE_PARTIAL_POS))#define MQE_MSBS_POS (MQE_PARTIAL_POS+1)#define MQE_MSBS_CLEAR (~(((kdu_int32)(-1))<<MQE_MSBS_POS))#define MQE_A_MIN ((kdu_int32)(1<<15))/* ========================================================================= *//*                             Class Definitions                             *//* ========================================================================= *//*****************************************************************************//*                                 mqe_state                                 *//*****************************************************************************/struct mqe_state {  public: // Member functions    void init(int Sigma, kdu_int32 s); // Inline implementation appears later      /* `Sigma' is in the range 0 to 46 and `s' is the MPS identity. */  public: // Data    kdu_int32 mps_p_bar; // Holds `p_bar' + `s'*2^31 (`s' is the MPS; 0 or 1)    mqe_transition *transition;  };  /* Notes:        This structure manages the state of the probability estimation state     machine for a single coding context.  The representation is redundant,     of course, since all that is required is the vaue of `Sigma', in the     range 0 through 46, and the value of the MPS, `s' (0 or 1).  However,     this expanded representation avoids unnecessary de-referencing steps     by the MP encoder and so can significantly increase throughput.        The `transition' pointer holds the address of the entry in     `mq_encoder::transition_table' which corresponds to this element.  There     are 92 entries in the transition table, whose indices have the form     `idx'=2*`Sigma'+s.  If renormalization occurs while encoding an MPS,     the state is updated according to state=state.transition->mps; if     renormalization occurs while encoding an LPS, the state is updated     according to state=state.transition->lps.  The transition table is     carefully constructed to ensure that all information is mapped correctly     by this simple operation.        The trick of keeping the MPS identity in the most significant bit     (i.e., the sign bit) of the `mps_p_bar' member, allows the encoder to     be implemented with a most common symbol path having only one comparison     and very few other operations. *//*****************************************************************************//*                                mqe_transition                             *//*****************************************************************************/struct mqe_transition {  /* See the definition of `mqe_state' for an explanation of this structure. */    mqe_state mps;    mqe_state lps;  };/*****************************************************************************//*                                  mq_encoder                               *//*****************************************************************************/class mq_encoder {  /* This object can be used for both MQ and raw codeword segments. */  public: // Member functions    mq_encoder()      { active = false; buf_start=buf_next=NULL; prev=next=NULL; }    void start(kdu_byte *buffer, bool MQ_segment);      /* Start a new MQ or raw codeword segment.  On entry, `buffer' points         to the location to which the first code byte will be written.  Note         carefully, however, that the MQ codeword segments actually require         access to the location immediately prior to the `buffer' pointer.         The value at that location is temporarily saved and restored only when         the `terminate' member function is called.  To allow access to         `buffer'[-1], the caller should take care in allocating storage         for coded bytes.            The buffer is required to be large enough to hold the compressed         output.  If the user determines that the buffer may need to grow,         the `augment_buffer' function should be used in the manner described         below.  This policy allows buffer size tests and potential function         calls to be eliminated from all time-critical code. */    int get_bytes_used()      { /* Returns the total number of bytes from the original `buffer'           supplied in the `start' call which have been used by this object           and any previous objects which it continues.  The function is           provided only to facilitate determination by the user as to whether           or not buffer space will need to be augmented.  There is no           attempt to determine truncation lengths. */        assert((!checked_out) && (buf_start != NULL));        return (buf_next-buf_start);      }    void augment_buffer(kdu_byte *old_handle, kdu_byte *new_handle)      { /* Use this if you need to increase the size of the buffer.  You must           first create the new buffer and copy the old buffer's contents into           the new buffer.  Then call this function for every `mqe_coder'           object which is using the buffer. The object will alter its internal           pointers accordingly.   The `old_handle' and `new_handle' pointers           should generally point to the first allocated location in each of           the original and new buffers. */        if (buf_start == NULL)          return; // Encoder finished working with buffer        assert((!checked_out) && (old_handle != NULL) && (new_handle != NULL));        buf_start += (new_handle-old_handle);        buf_next += (new_handle-old_handle);      }    void continues(mq_encoder *previous)      { /* Use this function to continue a coding segment beyond the current           coding pass.  This sets up internal references between the           coding objects which manage the same codeword segment, so that           truncation point computation may be performed later. */        assert((!active) && (buf_start == NULL));        assert(previous->active); // Can't continue an inactive segment.        assert(!previous->checked_out);        *this = *previous;        prev = previous; previous->next = this;        previous->active = false;      }    int get_incremental_length(bool &final)      { /* This function returns the number of additional code bytes generated           by this object, beyond the point of continuation from any           previous object in a continuation list.  If possible, the function           invokes the truncation point optimization algorithm for this           object and all objects which it continues and have not already           had their truncation points determined.  This will not be possible           if the object is still active or it has been continued by another           object which has generated less than 5 additional bytes so far.           If truncation point optimization is not possible, the `final'           argument is set to false and the function returns a reasonable           lower bound (not quite a guaranteed bound) for the length, which           is the number of bytes which have actually been put onto the           byte buffer beyond the point of continuation (or the start of the           buffer).  The return value is guaranteed to be non-negative. */        if (!truncation_point_found)          {            mq_encoder *scan_ahead = this;            while (scan_ahead->next != NULL) scan_ahead = scan_ahead->next;            mq_encoder *scan_back = scan_ahead;            for (; scan_back != NULL; scan_back=scan_back->prev)              {                if (scan_back->truncation_point_found)                  break;                if ((!scan_back->active) &&                    ((scan_ahead->buf_next - scan_back->buf_next) >= 5))                  scan_back->find_truncation_point(scan_ahead->buf_next);              }          }        final = truncation_point_found;        if (prev == NULL)          return buf_next - buf_start;        else          return buf_next - prev->buf_next;      }    kdu_byte *terminate(bool optimal);      /* This function is quite involved.  It flushes the state of the coder         and then determines a suitable truncation length.  If `optimal' is         true, it terminates to the smallest possible codeword segment which         will result in correct decoding of the coded symbols.            If the codeword segment has been continued across multiple coding         objects, this function may be invoked only on the last such object.         It automatically visits the other objects and forces optimal         truncation length computation if this has not already been done         (see "get_incremental_length" for a discussion of early         length computation).  This guarantees that their `finish' functions         will return correct lengths.            For a thorough discussion of optimal termination and length         computation, see Section 12.3.2 of the book by Taubman and Marcellin.            If `optimal' is false, the function uses the predictable         termination algorithms expected by error resilient decoders. See         Section 12.4 of the book by Taubman and Marcellin for a discussion         of error resilient termination for MQ and raw codeword segments.            The function returns a pointer to the next free location in         the byte buffer; this may be used to start another codeword         segment. */    void finish()      { /* Invoke this function on the last element in a codeword segment           (the same one which you invoked `terminate' on) to reset all           objects in the segment in preparation for later calls to the           `start' member function. */        assert((!active) && (next == NULL));        mq_encoder *scan, *next_scan;        for (scan=this; scan != NULL; scan = next_scan)          {            assert(!scan->active);            next_scan = scan->prev;            scan->next = scan->prev = NULL;            scan->truncation_point_found = false;            scan->buf_start = scan->buf_next = NULL;          }      }  public: // Functions to check out state information for use with fast macros    void check_out(kdu_int32 &A, kdu_int32 &C,                   kdu_int32 &t, kdu_int32 &temp, kdu_byte * &store)      { // Use this form for MQ codeword segments.        assert(active && (!checked_out) && MQ_segment); checked_out = true;        A = this->A; C = this->C;        t = this->t; temp = this->temp; store = this->buf_next;      }    void check_out(kdu_int32 &t, kdu_int32 &temp, kdu_byte * &store)      { // Use this form for raw codeword segments.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -