jpc_mqdec.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       jpc_mqdec.c (9552B)
       ---
            1 /*
            2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
            3  *   British Columbia.
            4  * Copyright (c) 2001-2003 Michael David Adams.
            5  * All rights reserved.
            6  */
            7 
            8 /* __START_OF_JASPER_LICENSE__
            9  * 
           10  * JasPer License Version 2.0
           11  * 
           12  * Copyright (c) 1999-2000 Image Power, Inc.
           13  * Copyright (c) 1999-2000 The University of British Columbia
           14  * Copyright (c) 2001-2003 Michael David Adams
           15  * 
           16  * All rights reserved.
           17  * 
           18  * Permission is hereby granted, free of charge, to any person (the
           19  * "User") obtaining a copy of this software and associated documentation
           20  * files (the "Software"), to deal in the Software without restriction,
           21  * including without limitation the rights to use, copy, modify, merge,
           22  * publish, distribute, and/or sell copies of the Software, and to permit
           23  * persons to whom the Software is furnished to do so, subject to the
           24  * following conditions:
           25  * 
           26  * 1.  The above copyright notices and this permission notice (which
           27  * includes the disclaimer below) shall be included in all copies or
           28  * substantial portions of the Software.
           29  * 
           30  * 2.  The name of a copyright holder shall not be used to endorse or
           31  * promote products derived from the Software without specific prior
           32  * written permission.
           33  * 
           34  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
           35  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
           36  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
           37  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
           38  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
           39  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
           40  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
           41  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
           42  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
           43  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
           44  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
           45  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
           46  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
           47  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
           48  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
           49  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
           50  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
           51  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
           52  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
           53  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
           54  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
           55  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
           56  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
           57  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
           58  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
           59  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
           60  * 
           61  * __END_OF_JASPER_LICENSE__
           62  */
           63 
           64 /*
           65  * MQ Arithmetic Decoder
           66  *
           67  * $Id: jpc_mqdec.c 1918 2005-07-24 14:12:08Z baford $
           68  */
           69 
           70 /******************************************************************************\
           71 * Includes.
           72 \******************************************************************************/
           73 
           74 #include <assert.h>
           75 #include <stdlib.h>
           76 #include <stdarg.h>
           77 
           78 #include "jasper/jas_types.h"
           79 #include "jasper/jas_malloc.h"
           80 #include "jasper/jas_math.h"
           81 #include "jasper/jas_debug.h"
           82 
           83 #include "jpc_mqdec.h"
           84 
           85 /******************************************************************************\
           86 * Local macros.
           87 \******************************************************************************/
           88 
           89 #if defined(DEBUG)
           90 #define        MQDEC_CALL(n, x) \
           91         ((jas_getdbglevel() >= (n)) ? ((void)(x)) : ((void)0))
           92 #else
           93 #define        MQDEC_CALL(n, x)
           94 #endif
           95 
           96 /******************************************************************************\
           97 * Local function prototypes.
           98 \******************************************************************************/
           99 
          100 static void jpc_mqdec_bytein(jpc_mqdec_t *mqdec);
          101 
          102 /******************************************************************************\
          103 * Code for creation and destruction of a MQ decoder.
          104 \******************************************************************************/
          105 
          106 /* Create a MQ decoder. */
          107 jpc_mqdec_t *jpc_mqdec_create(int maxctxs, jas_stream_t *in)
          108 {
          109         jpc_mqdec_t *mqdec;
          110 
          111         /* There must be at least one context. */
          112         assert(maxctxs > 0);
          113 
          114         /* Allocate memory for the MQ decoder. */
          115         if (!(mqdec = jas_malloc(sizeof(jpc_mqdec_t)))) {
          116                 goto error;
          117         }
          118         mqdec->in = in;
          119         mqdec->maxctxs = maxctxs;
          120         /* Allocate memory for the per-context state information. */
          121         if (!(mqdec->ctxs = jas_malloc(mqdec->maxctxs * sizeof(jpc_mqstate_t *)))) {
          122                 goto error;
          123         }
          124         /* Set the current context to the first context. */
          125         mqdec->curctx = mqdec->ctxs;
          126 
          127         /* If an input stream has been associated with the MQ decoder,
          128           initialize the decoder state from the stream. */
          129         if (mqdec->in) {
          130                 jpc_mqdec_init(mqdec);
          131         }
          132         /* Initialize the per-context state information. */
          133         jpc_mqdec_setctxs(mqdec, 0, 0);
          134 
          135         return mqdec;
          136 
          137 error:
          138         /* Oops...  Something has gone wrong. */
          139         if (mqdec) {
          140                 jpc_mqdec_destroy(mqdec);
          141         }
          142         return 0;
          143 }
          144 
          145 /* Destroy a MQ decoder. */
          146 void jpc_mqdec_destroy(jpc_mqdec_t *mqdec)
          147 {
          148         if (mqdec->ctxs) {
          149                 jas_free(mqdec->ctxs);
          150         }
          151         jas_free(mqdec);
          152 }
          153 
          154 /******************************************************************************\
          155 * Code for initialization of a MQ decoder.
          156 \******************************************************************************/
          157 
          158 /* Initialize the state of a MQ decoder. */
          159 
          160 void jpc_mqdec_init(jpc_mqdec_t *mqdec)
          161 {
          162         int c;
          163 
          164         mqdec->eof = 0;
          165         mqdec->creg = 0;
          166         /* Get the next byte from the input stream. */
          167         if ((c = jas_stream_getc(mqdec->in)) == EOF) {
          168                 /* We have encountered an I/O error or EOF. */
          169                 c = 0xff;
          170                 mqdec->eof = 1;
          171         }
          172         mqdec->inbuffer = c;
          173         mqdec->creg += mqdec->inbuffer << 16;
          174         jpc_mqdec_bytein(mqdec);
          175         mqdec->creg <<= 7;
          176         mqdec->ctreg -= 7;
          177         mqdec->areg = 0x8000;
          178 }
          179 
          180 /* Set the input stream for a MQ decoder. */
          181 
          182 void jpc_mqdec_setinput(jpc_mqdec_t *mqdec, jas_stream_t *in)
          183 {
          184         mqdec->in = in;
          185 }
          186 
          187 /* Initialize one or more contexts. */
          188 
          189 void jpc_mqdec_setctxs(jpc_mqdec_t *mqdec, int numctxs, jpc_mqctx_t *ctxs)
          190 {
          191         jpc_mqstate_t **ctx;
          192         int n;
          193 
          194         ctx = mqdec->ctxs;
          195         n = JAS_MIN(mqdec->maxctxs, numctxs);
          196         while (--n >= 0) {
          197                 *ctx = &jpc_mqstates[2 * ctxs->ind + ctxs->mps];
          198                 ++ctx;
          199                 ++ctxs;
          200         }
          201         n = mqdec->maxctxs - numctxs;
          202         while (--n >= 0) {
          203                 *ctx = &jpc_mqstates[0];
          204                 ++ctx;
          205         }
          206 }
          207 
          208 /* Initialize a context. */
          209 
          210 void jpc_mqdec_setctx(jpc_mqdec_t *mqdec, int ctxno, jpc_mqctx_t *ctx)
          211 {
          212         jpc_mqstate_t **ctxi;
          213         ctxi = &mqdec->ctxs[ctxno];
          214         *ctxi = &jpc_mqstates[2 * ctx->ind + ctx->mps];
          215 }
          216 
          217 /******************************************************************************\
          218 * Code for decoding a bit.
          219 \******************************************************************************/
          220 
          221 /* Decode a bit. */
          222 
          223 int jpc_mqdec_getbit_func(register jpc_mqdec_t *mqdec)
          224 {
          225         int bit;
          226         JAS_DBGLOG(100, ("jpc_mqdec_getbit_func(%p)\n", mqdec));
          227         MQDEC_CALL(100, jpc_mqdec_dump(mqdec, stderr));
          228         bit = jpc_mqdec_getbit_macro(mqdec);
          229         MQDEC_CALL(100, jpc_mqdec_dump(mqdec, stderr));
          230         JAS_DBGLOG(100, ("ctx = %d, decoded %d\n", mqdec->curctx -
          231           mqdec->ctxs, bit));
          232         return bit;
          233 }
          234 
          235 /* Apply MPS_EXCHANGE algorithm (with RENORMD). */
          236 int jpc_mqdec_mpsexchrenormd(register jpc_mqdec_t *mqdec)
          237 {
          238         int ret;
          239         register jpc_mqstate_t *state = *mqdec->curctx;
          240         jpc_mqdec_mpsexchange(mqdec->areg, state->qeval, mqdec->curctx, ret);
          241         jpc_mqdec_renormd(mqdec->areg, mqdec->creg, mqdec->ctreg, mqdec->in,
          242           mqdec->eof, mqdec->inbuffer);
          243         return ret;
          244 }
          245 
          246 /* Apply LPS_EXCHANGE algorithm (with RENORMD). */
          247 int jpc_mqdec_lpsexchrenormd(register jpc_mqdec_t *mqdec)
          248 {
          249         int ret;
          250         register jpc_mqstate_t *state = *mqdec->curctx;
          251         jpc_mqdec_lpsexchange(mqdec->areg, state->qeval, mqdec->curctx, ret);
          252         jpc_mqdec_renormd(mqdec->areg, mqdec->creg, mqdec->ctreg, mqdec->in,
          253           mqdec->eof, mqdec->inbuffer);
          254         return ret;
          255 }
          256 
          257 /******************************************************************************\
          258 * Support code.
          259 \******************************************************************************/
          260 
          261 /* Apply the BYTEIN algorithm. */
          262 static void jpc_mqdec_bytein(jpc_mqdec_t *mqdec)
          263 {
          264         int c;
          265         unsigned char prevbuf;
          266 
          267         if (!mqdec->eof) {
          268                 if ((c = jas_stream_getc(mqdec->in)) == EOF) {
          269                         mqdec->eof = 1;
          270                         c = 0xff;
          271                 }
          272                 prevbuf = mqdec->inbuffer;
          273                 mqdec->inbuffer = c;
          274                 if (prevbuf == 0xff) {
          275                         if (c > 0x8f) {
          276                                 mqdec->creg += 0xff00;
          277                                 mqdec->ctreg = 8;
          278                         } else {
          279                                 mqdec->creg += c << 9;
          280                                 mqdec->ctreg = 7;
          281                         }
          282                 } else {
          283                         mqdec->creg += c << 8;
          284                         mqdec->ctreg = 8;
          285                 }
          286         } else {
          287                 mqdec->creg += 0xff00;
          288                 mqdec->ctreg = 8;
          289         }
          290 }
          291 
          292 /******************************************************************************\
          293 * Code for debugging.
          294 \******************************************************************************/
          295 
          296 /* Dump a MQ decoder to a stream for debugging. */
          297 
          298 void jpc_mqdec_dump(jpc_mqdec_t *mqdec, FILE *out)
          299 {
          300         fprintf(out, "MQDEC A = %08lx, C = %08lx, CT=%08lx, ",
          301           (unsigned long) mqdec->areg, (unsigned long) mqdec->creg,
          302           (unsigned long) mqdec->ctreg);
          303         fprintf(out, "CTX = %d, ", (int)(mqdec->curctx - mqdec->ctxs));
          304         fprintf(out, "IND %d, MPS %d, QEVAL %x\n", (int)(*mqdec->curctx -
          305           jpc_mqstates), (int)(*mqdec->curctx)->mps, (int)(*mqdec->curctx)->qeval);
          306 }