Change CMakeLists.txt to build examples by default (image_to_j2k and j2k_to_image).
[openjpeg.git] / libopenjpeg / mqc.c
index 3f6eb921b13097ccf22a878cb55dd458ba17aeca..5d25238ee68308308fd955ff53ddd4d05da7a5c9 100644 (file)
@@ -1,7 +1,10 @@
 /*
- * Copyright (c) 2001-2002, David Janssens
+ * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2007, Professor Benoit Macq
+ * Copyright (c) 2001-2003, David Janssens
  * Copyright (c) 2002-2003, Yannick Verschueren
- * Copyright (c) 2002-2003,  Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
+ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
+ * Copyright (c) 2005, Herve Drolon, FreeImage Team
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#include "mqc.h"
-#include <stdio.h>
-
-/* <summary> */
-/* This struct defines the state of a context. */
-/* </summary> */
-typedef struct mqc_state_s {
-       unsigned int qeval;                                             /* the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */
-       int mps;                                                                                        /* the Most Probable Symbol (0 or 1) */
-       struct mqc_state_s *nmps;                       /* next state if the next encoded symbol is the MPS */
-       struct mqc_state_s *nlps;                       /* next state if the next encoded symbol is the LPS */
-} mqc_state_t;
+#include "opj_includes.h"
+
+/** @defgroup MQC MQC - Implementation of an MQ-Coder */
+/*@{*/
+
+/** @name Local static functions */
+/*@{*/
+
+/**
+Output a byte, doing bit-stuffing if necessary.
+After a 0xff byte, the next byte must be smaller than 0x90.
+@param mqc MQC handle
+*/
+static void mqc_byteout(opj_mqc_t *mqc);
+/**
+Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000
+@param mqc MQC handle
+*/
+static void mqc_renorme(opj_mqc_t *mqc);
+/**
+Encode the most probable symbol
+@param mqc MQC handle
+*/
+static void mqc_codemps(opj_mqc_t *mqc);
+/**
+Encode the most least symbol
+@param mqc MQC handle
+*/
+static void mqc_codelps(opj_mqc_t *mqc);
+/**
+Fill mqc->c with 1's for flushing
+@param mqc MQC handle
+*/
+static void mqc_setbits(opj_mqc_t *mqc);
+/**
+FIXME: documentation ???
+@param mqc MQC handle
+@return 
+*/
+static INLINE int mqc_mpsexchange(opj_mqc_t *const mqc);
+/**
+FIXME: documentation ???
+@param mqc MQC handle
+@return 
+*/
+static INLINE int mqc_lpsexchange(opj_mqc_t *const mqc);
+/**
+Input a byte
+@param mqc MQC handle
+*/
+static INLINE void mqc_bytein(opj_mqc_t *const mqc);
+/**
+Renormalize mqc->a and mqc->c while decoding
+@param mqc MQC handle
+*/
+static INLINE void mqc_renormd(opj_mqc_t *const mqc);
+/*@}*/
+
+/*@}*/
 
 /* <summary> */
 /* This array defines all the possible states for a context. */
 /* </summary> */
-mqc_state_t mqc_states[47 * 2] = {
+static opj_mqc_state_t mqc_states[47 * 2] = {
        {0x5601, 0, &mqc_states[2], &mqc_states[3]},
        {0x5601, 1, &mqc_states[3], &mqc_states[2]},
        {0x3401, 0, &mqc_states[4], &mqc_states[12]},
@@ -139,450 +189,405 @@ mqc_state_t mqc_states[47 * 2] = {
        {0x5601, 1, &mqc_states[93], &mqc_states[93]},
 };
 
-#define MQC_NUMCTXS 32
-
-unsigned int mqc_c;
-unsigned int mqc_a;
-unsigned int mqc_ct;
-unsigned char *mqc_bp;
-unsigned char *mqc_start;
-unsigned char *mqc_end;
-mqc_state_t *mqc_ctxs[MQC_NUMCTXS];
-mqc_state_t **mqc_curctx;
-
-/* <summary> */
-/* Return the number of bytes already encoded. */
-/* </summary> */
-int mqc_numbytes()
-{
-       return mqc_bp - mqc_start;
-}
-
-/* <summary> */
-/* Output a byte, doing bit-stuffing if necessary. */
-/* After a 0xff byte, the next byte must be smaller than 0x90 */
-/* </summary> */
-void mqc_byteout()
-{
-       if (*mqc_bp == 0xff) {
-               mqc_bp++;
-               *mqc_bp = mqc_c >> 20;
-               mqc_c &= 0xfffff;
-               mqc_ct = 7;
+/* 
+==========================================================
+   local functions
+==========================================================
+*/
+
+static void mqc_byteout(opj_mqc_t *mqc) {
+       if (*mqc->bp == 0xff) {
+               mqc->bp++;
+               *mqc->bp = mqc->c >> 20;
+               mqc->c &= 0xfffff;
+               mqc->ct = 7;
        } else {
-               if ((mqc_c & 0x8000000) == 0) { /* ((mqc_c&0x8000000)==0) CHANGE */
-                       mqc_bp++;
-                       *mqc_bp = mqc_c >> 19;
-                       mqc_c &= 0x7ffff;
-                       mqc_ct = 8;
+               if ((mqc->c & 0x8000000) == 0) {        /* ((mqc->c&0x8000000)==0) CHANGE */
+                       mqc->bp++;
+                       *mqc->bp = mqc->c >> 19;
+                       mqc->c &= 0x7ffff;
+                       mqc->ct = 8;
                } else {
-                       (*mqc_bp)++;
-                       if (*mqc_bp == 0xff) {
-                               mqc_c &= 0x7ffffff;
-                               mqc_bp++;
-                               *mqc_bp = mqc_c >> 20;
-                               mqc_c &= 0xfffff;
-                               mqc_ct = 7;
+                       (*mqc->bp)++;
+                       if (*mqc->bp == 0xff) {
+                               mqc->c &= 0x7ffffff;
+                               mqc->bp++;
+                               *mqc->bp = mqc->c >> 20;
+                               mqc->c &= 0xfffff;
+                               mqc->ct = 7;
                        } else {
-                               mqc_bp++;
-                               *mqc_bp = mqc_c >> 19;
-                               mqc_c &= 0x7ffff;
-                               mqc_ct = 8;
+                               mqc->bp++;
+                               *mqc->bp = mqc->c >> 19;
+                               mqc->c &= 0x7ffff;
+                               mqc->ct = 8;
                        }
                }
        }
 }
 
-/* <summary> */
-/* Renormalize mqc_a and mqc_c while encoding, so that mqc_a stays between 0x8000 and 0x10000 */
-/* </summary> */
-void mqc_renorme()
-{
+static void mqc_renorme(opj_mqc_t *mqc) {
        do {
-               mqc_a <<= 1;
-               mqc_c <<= 1;
-               mqc_ct--;
-               if (mqc_ct == 0) {
-                       mqc_byteout();
+               mqc->a <<= 1;
+               mqc->c <<= 1;
+               mqc->ct--;
+               if (mqc->ct == 0) {
+                       mqc_byteout(mqc);
                }
-       } while ((mqc_a & 0x8000) == 0);
+       } while ((mqc->a & 0x8000) == 0);
 }
 
-/* <summary> */
-/* Encode the most probable symbol. */
-/* </summary> */
-void mqc_codemps()
-{
-       mqc_a -= (*mqc_curctx)->qeval;
-       if ((mqc_a & 0x8000) == 0) {
-               if (mqc_a < (*mqc_curctx)->qeval) {
-                       mqc_a = (*mqc_curctx)->qeval;
+static void mqc_codemps(opj_mqc_t *mqc) {
+       mqc->a -= (*mqc->curctx)->qeval;
+       if ((mqc->a & 0x8000) == 0) {
+               if (mqc->a < (*mqc->curctx)->qeval) {
+                       mqc->a = (*mqc->curctx)->qeval;
                } else {
-                       mqc_c += (*mqc_curctx)->qeval;
+                       mqc->c += (*mqc->curctx)->qeval;
                }
-               *mqc_curctx = (*mqc_curctx)->nmps;
-               mqc_renorme();
+               *mqc->curctx = (*mqc->curctx)->nmps;
+               mqc_renorme(mqc);
        } else {
-               mqc_c += (*mqc_curctx)->qeval;
+               mqc->c += (*mqc->curctx)->qeval;
        }
 }
 
-/* <summary> */
-/* Encode the most least symbol. */
-/* </summary> */
-void mqc_codelps()
-{
-       mqc_a -= (*mqc_curctx)->qeval;
-       if (mqc_a < (*mqc_curctx)->qeval) {
-               mqc_c += (*mqc_curctx)->qeval;
+static void mqc_codelps(opj_mqc_t *mqc) {
+       mqc->a -= (*mqc->curctx)->qeval;
+       if (mqc->a < (*mqc->curctx)->qeval) {
+               mqc->c += (*mqc->curctx)->qeval;
        } else {
-               mqc_a = (*mqc_curctx)->qeval;
+               mqc->a = (*mqc->curctx)->qeval;
        }
-       *mqc_curctx = (*mqc_curctx)->nlps;
-       mqc_renorme();
+       *mqc->curctx = (*mqc->curctx)->nlps;
+       mqc_renorme(mqc);
 }
 
-/* <summary> */
-/* Initialize encoder. */
-/* </summary> */
-/* <param name="bp">Output buffer.</param> */
-void mqc_init_enc(unsigned char *bp)
-{
-       mqc_setcurctx(0);
-       mqc_a = 0x8000;
-       mqc_c = 0;
-       mqc_bp = bp - 1;
-       mqc_ct = 12;
-       if (*mqc_bp == 0xff) {
-               mqc_ct = 13;
+static void mqc_setbits(opj_mqc_t *mqc) {
+       unsigned int tempc = mqc->c + mqc->a;
+       mqc->c |= 0xffff;
+       if (mqc->c >= tempc) {
+               mqc->c -= 0x8000;
        }
-       mqc_start = bp;
 }
 
-/* <summary> */
-/* Set current context. */
-/* </summary> */
-/* <param name="ctxno">Context number.</param> */
-void mqc_setcurctx(int ctxno)
-{
-       mqc_curctx = &mqc_ctxs[ctxno];
+static INLINE int mqc_mpsexchange(opj_mqc_t *const mqc) {
+       int d;
+       if (mqc->a < (*mqc->curctx)->qeval) {
+               d = 1 - (*mqc->curctx)->mps;
+               *mqc->curctx = (*mqc->curctx)->nlps;
+       } else {
+               d = (*mqc->curctx)->mps;
+               *mqc->curctx = (*mqc->curctx)->nmps;
+       }
+       
+       return d;
 }
 
-/* <summary> */
-/* Encode a symbol using the MQ-coder. */
-/* </summary> */
-/* <param name="d"> The symbol to be encoded (0 or 1).</param> */
-void mqc_encode(int d)
-{
-       if ((*mqc_curctx)->mps == d) {
-               mqc_codemps();
+static INLINE int mqc_lpsexchange(opj_mqc_t *const mqc) {
+       int d;
+       if (mqc->a < (*mqc->curctx)->qeval) {
+               mqc->a = (*mqc->curctx)->qeval;
+               d = (*mqc->curctx)->mps;
+               *mqc->curctx = (*mqc->curctx)->nmps;
        } else {
-               mqc_codelps();
+               mqc->a = (*mqc->curctx)->qeval;
+               d = 1 - (*mqc->curctx)->mps;
+               *mqc->curctx = (*mqc->curctx)->nlps;
        }
+       
+       return d;
 }
 
-/* <summary> */
-/* Fill mqc_c with 1's for flushing */
-/* </summary> */
-void mqc_setbits()
-{
-       unsigned int tempc = mqc_c + mqc_a;
-       mqc_c |= 0xffff;
-       if (mqc_c >= tempc) {
-               mqc_c -= 0x8000;
+#ifdef MQC_PERF_OPT
+static INLINE void mqc_bytein(opj_mqc_t *const mqc) {
+       unsigned int i = *((unsigned int *) mqc->bp);
+       mqc->c += i & 0xffff00;
+       mqc->ct = i & 0x0f;
+       mqc->bp += (i >> 2) & 0x04;
+}
+#else
+static void mqc_bytein(opj_mqc_t *const mqc) {
+       if (mqc->bp != mqc->end) {
+               unsigned int c;
+               if (mqc->bp + 1 != mqc->end) {
+                       c = *(mqc->bp + 1);
+               } else {
+                       c = 0xff;
+               }
+               if (*mqc->bp == 0xff) {
+                       if (c > 0x8f) {
+                               mqc->c += 0xff00;
+                               mqc->ct = 8;
+                       } else {
+                               mqc->bp++;
+                               mqc->c += c << 9;
+                               mqc->ct = 7;
+                       }
+               } else {
+                       mqc->bp++;
+                       mqc->c += c << 8;
+                       mqc->ct = 8;
+               }
+       } else {
+               mqc->c += 0xff00;
+               mqc->ct = 8;
        }
 }
+#endif
 
-/* <summary> */
-/* Flush encoded data. */
-/* </summary> */
-void mqc_flush()
-{
-       mqc_setbits();
-       mqc_c <<= mqc_ct;
-       mqc_byteout();
-       mqc_c <<= mqc_ct;
-       mqc_byteout();
-
-       if (*mqc_bp != 0xff) {
-               mqc_bp++;
+static INLINE void mqc_renormd(opj_mqc_t *const mqc) {
+       do {
+               if (mqc->ct == 0) {
+                       mqc_bytein(mqc);
+               }
+               mqc->a <<= 1;
+               mqc->c <<= 1;
+               mqc->ct--;
+       } while (mqc->a < 0x8000);
+}
+
+/* 
+==========================================================
+   MQ-Coder interface
+==========================================================
+*/
+
+opj_mqc_t* mqc_create(void) {
+       opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
+#ifdef MQC_PERF_OPT
+       mqc->buffer = NULL;
+#endif
+       return mqc;
+}
+
+void mqc_destroy(opj_mqc_t *mqc) {
+       if(mqc) {
+#ifdef MQC_PERF_OPT
+               if (mqc->buffer) {
+                       opj_free(mqc->buffer);
+               }
+#endif
+               opj_free(mqc);
        }
 }
 
-/* <summary> */
-/* not fully implemented and tested !! */
-/* BYPASS mode switch, initialization operation */
-/* JPEG 2000 p 505 */
-/* </summary> */
-void mqc_bypass_init_enc()
-{
-       mqc_c = 0;
-       mqc_ct = 8;
-       if (*mqc_bp == 0xff) {
-               mqc_ct = 7;
+int mqc_numbytes(opj_mqc_t *mqc) {
+       return mqc->bp - mqc->start;
+}
+
+void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) {
+       mqc_setcurctx(mqc, 0);
+       mqc->a = 0x8000;
+       mqc->c = 0;
+       mqc->bp = bp - 1;
+       mqc->ct = 12;
+       if (*mqc->bp == 0xff) {
+               mqc->ct = 13;
        }
+       mqc->start = bp;
 }
 
-/* <summary> */
-/* not fully implemented and tested !! */
-/* BYPASS mode switch, coding operation */
-/* JPEG 2000 p 505 */
-/* </summary> */
-void mqc_bypass_enc(int d)
-{
-       mqc_ct--;
-       mqc_c = mqc_c + (d << mqc_ct);
-       if (mqc_ct == 0) {
-               mqc_bp++;
-               *mqc_bp = mqc_c;
-               mqc_ct = 8;
-               if (*mqc_bp == 0xff) {
-                       mqc_ct = 7;
+void mqc_encode(opj_mqc_t *mqc, int d) {
+       if ((*mqc->curctx)->mps == d) {
+               mqc_codemps(mqc);
+       } else {
+               mqc_codelps(mqc);
+       }
+}
+
+void mqc_flush(opj_mqc_t *mqc) {
+       mqc_setbits(mqc);
+       mqc->c <<= mqc->ct;
+       mqc_byteout(mqc);
+       mqc->c <<= mqc->ct;
+       mqc_byteout(mqc);
+       
+       if (*mqc->bp != 0xff) {
+               mqc->bp++;
+       }
+}
+
+void mqc_bypass_init_enc(opj_mqc_t *mqc) {
+       mqc->c = 0;
+       mqc->ct = 8;
+       /*if (*mqc->bp == 0xff) {
+       mqc->ct = 7;
+     } */
+}
+
+void mqc_bypass_enc(opj_mqc_t *mqc, int d) {
+       mqc->ct--;
+       mqc->c = mqc->c + (d << mqc->ct);
+       if (mqc->ct == 0) {
+               mqc->bp++;
+               *mqc->bp = mqc->c;
+               mqc->ct = 8;
+               if (*mqc->bp == 0xff) {
+                       mqc->ct = 7;
                }
-               mqc_c = 0;
+               mqc->c = 0;
        }
 }
 
-/* <summary> */
-/* not fully implemented and tested !! */
-/* BYPASS mode switch, flush operation */
-/* </summary> */
-int mqc_bypass_flush_enc()
-{
+int mqc_bypass_flush_enc(opj_mqc_t *mqc) {
        unsigned char bit_padding;
-
+       
        bit_padding = 0;
-
-       if (mqc_ct != 0) {
-               while (mqc_ct > 0) {
-                       mqc_ct--;
-                       mqc_c += bit_padding << mqc_ct;
+       
+       if (mqc->ct != 0) {
+               while (mqc->ct > 0) {
+                       mqc->ct--;
+                       mqc->c += bit_padding << mqc->ct;
                        bit_padding = (bit_padding + 1) & 0x01;
                }
-               mqc_bp++;
-               *mqc_bp = mqc_c;
-               mqc_ct = 8;
-               mqc_c = 0;
+               mqc->bp++;
+               *mqc->bp = mqc->c;
+               mqc->ct = 8;
+               mqc->c = 0;
        }
-
+       
        return 1;
 }
 
-/* <summary> */
-/* RESET mode switch */
-/* </summary> */
-void mqc_reset_enc()
-{
-       mqc_resetstates();
-       mqc_setstate(18, 0, 46);
-       mqc_setstate(0, 0, 3);
-       mqc_setstate(1, 0, 4);
+void mqc_reset_enc(opj_mqc_t *mqc) {
+       mqc_resetstates(mqc);
+       mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46);
+       mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3);
+       mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
 }
 
-/* <summary> */
-/* mode switch RESTART (TERMALL) */
-/* </summary> */
-int mqc_restart_enc()
-{
+int mqc_restart_enc(opj_mqc_t *mqc) {
        int correction = 1;
-
+       
        /* <flush part> */
-       int n = 27 - 15 - mqc_ct;
-       mqc_c <<= mqc_ct;
+       int n = 27 - 15 - mqc->ct;
+       mqc->c <<= mqc->ct;
        while (n > 0) {
-               mqc_byteout();
-               n -= mqc_ct;
-               mqc_c <<= mqc_ct;
+               mqc_byteout(mqc);
+               n -= mqc->ct;
+               mqc->c <<= mqc->ct;
        }
-       mqc_byteout();
-
+       mqc_byteout(mqc);
+       
        return correction;
 }
 
-/* <summary> */
-/* mode switch RESTART (TERMALL) reinitialisation */
-/* </summary> */
-void mqc_restart_init_enc()
-{
+void mqc_restart_init_enc(opj_mqc_t *mqc) {
        /* <Re-init part> */
-       mqc_a = 0x8000;
-       mqc_c = 0;
-       mqc_ct = 12;
-       mqc_bp--;
-       if (*mqc_bp == 0xff) {
-               mqc_ct = 13;
+       mqc_setcurctx(mqc, 0);
+       mqc->a = 0x8000;
+       mqc->c = 0;
+       mqc->ct = 12;
+       mqc->bp--;
+       if (*mqc->bp == 0xff) {
+               mqc->ct = 13;
        }
-
 }
 
-
-/* <summary> */
-/* ERTERM mode switch  */
-/* </summary> */
-void mqc_erterm_enc()
-{
-       int k = 11 - mqc_ct + 1;
-
+void mqc_erterm_enc(opj_mqc_t *mqc) {
+       int k = 11 - mqc->ct + 1;
+       
        while (k > 0) {
-               mqc_c <<= mqc_ct;
-               mqc_ct = 0;
-               mqc_byteout();
-               k -= mqc_ct;
+               mqc->c <<= mqc->ct;
+               mqc->ct = 0;
+               mqc_byteout(mqc);
+               k -= mqc->ct;
        }
-
-       if (*mqc_bp != 0xff) {
-               mqc_byteout();
+       
+       if (*mqc->bp != 0xff) {
+               mqc_byteout(mqc);
        }
 }
 
-/* <summary> */
-/* SEGMARK mode switch (SEGSYM) */
-/* </summary> */
-void mqc_segmark_enc()
-{
+void mqc_segmark_enc(opj_mqc_t *mqc) {
        int i;
-       mqc_setcurctx(18);
-
+       mqc_setcurctx(mqc, 18);
+       
        for (i = 1; i < 5; i++) {
-               mqc_encode(i % 2);
+               mqc_encode(mqc, i % 2);
        }
 }
 
-/* <summary> */
-/* </summary> */
-int mqc_mpsexchange()
-{
-       int d;
-       if (mqc_a < (*mqc_curctx)->qeval) {
-               d = 1 - (*mqc_curctx)->mps;
-               *mqc_curctx = (*mqc_curctx)->nlps;
-       } else {
-               d = (*mqc_curctx)->mps;
-               *mqc_curctx = (*mqc_curctx)->nmps;
-       }
-       return d;
-}
+void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) {
+       mqc_setcurctx(mqc, 0);
+       mqc->start = bp;
+       mqc->end = bp + len;
+       mqc->bp = bp;
+       if (len==0) mqc->c = 0xff << 16;
+       else mqc->c = *mqc->bp << 16;
 
-/* <summary> */
-/* </summary> */
-int mqc_lpsexchange()
-{
-       int d;
-       if (mqc_a < (*mqc_curctx)->qeval) {
-               mqc_a = (*mqc_curctx)->qeval;
-               d = (*mqc_curctx)->mps;
-               *mqc_curctx = (*mqc_curctx)->nmps;
-       } else {
-               mqc_a = (*mqc_curctx)->qeval;
-               d = 1 - (*mqc_curctx)->mps;
-               *mqc_curctx = (*mqc_curctx)->nlps;
-       }
-       return d;
-}
-
-/* <summary> */
-/* Input a byte. */
-/* </summary> */
-void mqc_bytein()
-{
-       if (mqc_bp != mqc_end) {
+#ifdef MQC_PERF_OPT
+       {
                unsigned int c;
-               if (mqc_bp + 1 != mqc_end) {
-                       c = *(mqc_bp + 1);
-               } else {
-                       c = 0xff;
-               }
-               if (*mqc_bp == 0xff) {
-                       if (c > 0x8f) {
-                               mqc_c += 0xff00;
-                               mqc_ct = 8;
+               unsigned int *ip;
+               unsigned char *end = mqc->end - 1;
+               mqc->buffer = opj_realloc(mqc->buffer, (2 * len + 1) * sizeof(unsigned int));
+               ip = (unsigned int *) mqc->buffer;
+
+               while (bp != end) {
+                       c = *(bp + 1);
+                       if (*bp == 0xff) {
+                               if (c > 0x8f) {
+                                       *ip = 0x0000ff18;
+                               } else {
+                                       bp++;
+                                       *ip = 0x00000017 | (c << 9);
+                               }
                        } else {
-                               mqc_bp++;
-                               mqc_c += c << 9;
-                               mqc_ct = 7;
+                               bp++;
+                               *ip = 0x00000018 | (c << 8);
                        }
-               } else {
-                       mqc_bp++;
-                       mqc_c += c << 8;
-                       mqc_ct = 8;
+                       ip++;
                }
-       } else {
-               mqc_c += 0xff00;
-               mqc_ct = 8;
-       }
-}
 
-/* <summary> */
-/* Renormalize mqc_a and mqc_c while decoding. */
-/* </summary> */
-void mqc_renormd()
-{
-       do {
-               if (mqc_ct == 0) {
-                       mqc_bytein();
+               /* Handle last byte of data */
+               c = 0xff;
+               if (*bp == 0xff) {
+                       *ip = 0x0000ff18;
+               } else {
+                       bp++;
+                       *ip = 0x00000018 | (c << 8);
                }
-               mqc_a <<= 1;
-               mqc_c <<= 1;
-               mqc_ct--;
-       } while (mqc_a < 0x8000);
-}
+               ip++;
 
-/* <summary> */
-/* Initialize decoder. */
-/* </summary> */
-void mqc_init_dec(unsigned char *bp, int len)
-{
-       mqc_setcurctx(0);
-       mqc_start = bp;
-       mqc_end = bp + len;
-       mqc_bp = bp;
-       mqc_c = *mqc_bp << 16;
-       mqc_bytein();
-       mqc_c <<= 7;
-       mqc_ct -= 7;
-       mqc_a = 0x8000;
+               *ip = 0x0000ff08;
+               mqc->bp = mqc->buffer;
+       }
+#endif
+       mqc_bytein(mqc);
+       mqc->c <<= 7;
+       mqc->ct -= 7;
+       mqc->a = 0x8000;
 }
 
-/* <summary> */
-/* Decode a symbol. */
-/* </summary> */
-int mqc_decode()
-{
+int mqc_decode(opj_mqc_t *const mqc) {
        int d;
-       mqc_a -= (*mqc_curctx)->qeval;
-       if ((mqc_c >> 16) < (*mqc_curctx)->qeval) {
-               d = mqc_lpsexchange();
-               mqc_renormd();
+       mqc->a -= (*mqc->curctx)->qeval;
+       if ((mqc->c >> 16) < (*mqc->curctx)->qeval) {
+               d = mqc_lpsexchange(mqc);
+               mqc_renormd(mqc);
        } else {
-               mqc_c -= (*mqc_curctx)->qeval << 16;
-               if ((mqc_a & 0x8000) == 0) {
-                       d = mqc_mpsexchange();
-                       mqc_renormd();
+               mqc->c -= (*mqc->curctx)->qeval << 16;
+               if ((mqc->a & 0x8000) == 0) {
+                       d = mqc_mpsexchange(mqc);
+                       mqc_renormd(mqc);
                } else {
-                       d = (*mqc_curctx)->mps;
+                       d = (*mqc->curctx)->mps;
                }
        }
+
        return d;
 }
 
-/* <summary> */
-/* Reset states of all contexts. */
-/* </summary> */
-void mqc_resetstates()
-{
+void mqc_resetstates(opj_mqc_t *mqc) {
        int i;
        for (i = 0; i < MQC_NUMCTXS; i++) {
-               mqc_ctxs[i] = mqc_states;
+               mqc->ctxs[i] = mqc_states;
        }
 }
 
-/* <summary> */
-/* Set the state for a context. */
-/* </summary> */
-/* <param name="ctxno">Context number</param> */
-/* <param name="msb">Most significant bit</param> */
-/* <param name="prob">Index to the probability of symbols</param> */
-void mqc_setstate(int ctxno, int msb, int prob)
-{
-       mqc_ctxs[ctxno] = &mqc_states[msb + (prob << 1)];
+void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob) {
+       mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)];
 }
+
+