Changed cmake version test to allow for cmake 2.8.11.x
[openjpeg.git] / src / lib / openjp2 / mqc.c
index 8a792b601760844dbaec1adc5a21b07741a87e2c..6299b171d8788ffb32bd13c36027eb3f10b6983a 100644 (file)
@@ -38,6 +38,8 @@
 
 #include "opj_includes.h"
 
+#include <assert.h>
+
 /** @defgroup MQC MQC - Implementation of an MQ-Coder */
 /*@{*/
 
@@ -77,7 +79,7 @@ static void opj_mqc_setbits(opj_mqc_t *mqc);
 /* <summary> */
 /* This array defines all the possible states for a context. */
 /* </summary> */
-static opj_mqc_state_t mqc_states[47 * 2] = {
+static const 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]},
@@ -182,13 +184,10 @@ static opj_mqc_state_t mqc_states[47 * 2] = {
 
 static void opj_mqc_byteout(opj_mqc_t *mqc)
 {
-    /* avoid accessing uninitialized memory*/
-    if (mqc->bp == mqc->start - 1) {
-        mqc->bp++;
-        *mqc->bp = (OPJ_BYTE)(mqc->c >> 19);
-        mqc->c &= 0x7ffff;
-        mqc->ct = 8;
-    } else if (*mqc->bp == 0xff) {
+    /* bp is initialized to start - 1 in opj_mqc_init_enc() */
+    /* but this is safe, see opj_tcd_code_block_enc_allocate_data() */
+    assert(mqc->bp >= mqc->start - 1);
+    if (*mqc->bp == 0xff) {
         mqc->bp++;
         *mqc->bp = (OPJ_BYTE)(mqc->c >> 20);
         mqc->c &= 0xfffff;
@@ -272,19 +271,6 @@ static void opj_mqc_setbits(opj_mqc_t *mqc)
 ==========================================================
 */
 
-opj_mqc_t* opj_mqc_create(void)
-{
-    opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t));
-    return mqc;
-}
-
-void opj_mqc_destroy(opj_mqc_t *mqc)
-{
-    if (mqc) {
-        opj_free(mqc);
-    }
-}
-
 OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc)
 {
     const ptrdiff_t diff = mqc->bp - mqc->start;
@@ -296,13 +282,25 @@ OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc)
 
 void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp)
 {
-    /* TODO MSD: need to take a look to the v2 version */
+    /* To avoid the curctx pointer to be dangling, but not strictly */
+    /* required as the current context is always set before encoding */
     opj_mqc_setcurctx(mqc, 0);
+
+    /* As specified in Figure C.10 - Initialization of the encoder */
+    /* (C.2.8 Initialization of the encoder (INITENC)) */
     mqc->a = 0x8000;
     mqc->c = 0;
+    /* Yes, we point before the start of the buffer, but this is safe */
+    /* given opj_tcd_code_block_enc_allocate_data() */
     mqc->bp = bp - 1;
     mqc->ct = 12;
+    /* At this point we should test *(mqc->bp) against 0xFF, but this is not */
+    /* necessary, as this is only used at the beginning of the code block */
+    /* and our initial fake byte is set at 0 */
+    assert(*(mqc->bp) != 0xff);
+
     mqc->start = bp;
+    mqc->end_of_byte_stream_counter = 0;
 }
 
 void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d)
@@ -316,60 +314,102 @@ void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d)
 
 void opj_mqc_flush(opj_mqc_t *mqc)
 {
+    /* C.2.9 Termination of coding (FLUSH) */
+    /* Figure C.11 – FLUSH procedure */
     opj_mqc_setbits(mqc);
     mqc->c <<= mqc->ct;
     opj_mqc_byteout(mqc);
     mqc->c <<= mqc->ct;
     opj_mqc_byteout(mqc);
 
+    /* It is forbidden that a coding pass ends with 0xff */
     if (*mqc->bp != 0xff) {
+        /* Advance pointer so that opj_mqc_numbytes() returns a valid value */
         mqc->bp++;
     }
 }
 
+#define BYPASS_CT_INIT  0xDEADBEEF
+
 void opj_mqc_bypass_init_enc(opj_mqc_t *mqc)
 {
+    /* This function is normally called after at least one opj_mqc_flush() */
+    /* which will have advance mqc->bp by at least 2 bytes beyond its */
+    /* initial position */
+    assert(mqc->bp >= mqc->start);
     mqc->c = 0;
-    mqc->ct = 8;
-    /*if (*mqc->bp == 0xff) {
-    mqc->ct = 7;
-     } */
+    /* in theory we should initialize to 8, but use this special value */
+    /* as a hint that opj_mqc_bypass_enc() has never been called, so */
+    /* as to avoid the 0xff 0x7f elimination trick in opj_mqc_bypass_flush_enc() */
+    /* to trigger when we don't have output any bit during this bypass sequence */
+    /* Any value > 8 will do */
+    mqc->ct = BYPASS_CT_INIT;
+    /* Given that we are called after opj_mqc_flush(), the previous byte */
+    /* cannot be 0xff. */
+    assert(mqc->bp[-1] != 0xff);
 }
 
 void opj_mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d)
 {
+    if (mqc->ct == BYPASS_CT_INIT) {
+        mqc->ct = 8;
+    }
     mqc->ct--;
     mqc->c = mqc->c + (d << mqc->ct);
     if (mqc->ct == 0) {
-        mqc->bp++;
         *mqc->bp = (OPJ_BYTE)mqc->c;
         mqc->ct = 8;
+        /* If the previous byte was 0xff, make sure that the next msb is 0 */
         if (*mqc->bp == 0xff) {
             mqc->ct = 7;
         }
+        mqc->bp++;
         mqc->c = 0;
     }
 }
 
-OPJ_UINT32 opj_mqc_bypass_flush_enc(opj_mqc_t *mqc)
+OPJ_UINT32 opj_mqc_bypass_get_extra_bytes(opj_mqc_t *mqc, OPJ_BOOL erterm)
 {
-    OPJ_BYTE bit_padding;
-
-    bit_padding = 0;
+    return (mqc->ct < 7 ||
+            (mqc->ct == 7 && (erterm || mqc->bp[-1] != 0xff))) ? 1 : 0;
+}
 
-    if (mqc->ct != 0) {
+void opj_mqc_bypass_flush_enc(opj_mqc_t *mqc, OPJ_BOOL erterm)
+{
+    /* Is there any bit remaining to be flushed ? */
+    /* If the last output byte is 0xff, we can discard it, unless */
+    /* erterm is required (I'm not completely sure why in erterm */
+    /* we must output 0xff 0x2a if the last byte was 0xff instead of */
+    /* discarding it, but Kakadu requires it when decoding */
+    /* in -fussy mode) */
+    if (mqc->ct < 7 || (mqc->ct == 7 && (erterm || mqc->bp[-1] != 0xff))) {
+        OPJ_BYTE bit_value = 0;
+        /* If so, fill the remaining lsbs with an alternating sequence of */
+        /* 0,1,... */
+        /* Note: it seems the standard only requires that for a ERTERM flush */
+        /* and doesn't specify what to do for a regular BYPASS flush */
         while (mqc->ct > 0) {
             mqc->ct--;
-            mqc->c += (OPJ_UINT32)(bit_padding << mqc->ct);
-            bit_padding = (bit_padding + 1) & 0x01;
+            mqc->c += (OPJ_UINT32)(bit_value << mqc->ct);
+            bit_value = (OPJ_BYTE)(1U - bit_value);
         }
-        mqc->bp++;
         *mqc->bp = (OPJ_BYTE)mqc->c;
-        mqc->ct = 8;
-        mqc->c = 0;
+        /* Advance pointer so that opj_mqc_numbytes() returns a valid value */
+        mqc->bp++;
+    } else if (mqc->ct == 7 && mqc->bp[-1] == 0xff) {
+        /* Discard last 0xff */
+        assert(!erterm);
+        mqc->bp --;
+    } else if (mqc->ct == 8 && !erterm &&
+               mqc->bp[-1] == 0x7f && mqc->bp[-2] == 0xff) {
+        /* Tiny optimization: discard terminating 0xff 0x7f since it is */
+        /* interpreted as 0xff 0x7f [0xff 0xff] by the decoder, and given */
+        /* the bit stuffing, in fact as 0xff 0xff [0xff ..] */
+        /* Happens once on opj_compress -i ../MAPA.tif -o MAPA.j2k  -M 1 */
+        mqc->bp -= 2;
     }
 
-    return 1;
+    assert(mqc->bp[-1] != 0xff);
 }
 
 void opj_mqc_reset_enc(opj_mqc_t *mqc)
@@ -380,6 +420,7 @@ void opj_mqc_reset_enc(opj_mqc_t *mqc)
     opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4);
 }
 
+#ifdef notdef
 OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc)
 {
     OPJ_UINT32 correction = 1;
@@ -396,15 +437,23 @@ OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc)
 
     return correction;
 }
+#endif
 
 void opj_mqc_restart_init_enc(opj_mqc_t *mqc)
 {
     /* <Re-init part> */
-    opj_mqc_setcurctx(mqc, 0);
+
+    /* As specified in Figure C.10 - Initialization of the encoder */
+    /* (C.2.8 Initialization of the encoder (INITENC)) */
     mqc->a = 0x8000;
     mqc->c = 0;
     mqc->ct = 12;
-    mqc->bp--;
+    /* This function is normally called after at least one opj_mqc_flush() */
+    /* which will have advance mqc->bp by at least 2 bytes beyond its */
+    /* initial position */
+    mqc->bp --;
+    assert(mqc->bp >= mqc->start - 1);
+    assert(*mqc->bp != 0xff);
     if (*mqc->bp == 0xff) {
         mqc->ct = 13;
     }
@@ -436,17 +485,36 @@ void opj_mqc_segmark_enc(opj_mqc_t *mqc)
     }
 }
 
-OPJ_BOOL opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len)
+static void opj_mqc_init_dec_common(opj_mqc_t *mqc,
+                                    OPJ_BYTE *bp,
+                                    OPJ_UINT32 len,
+                                    OPJ_UINT32 extra_writable_bytes)
+{
+    (void)extra_writable_bytes;
+
+    assert(extra_writable_bytes >= OPJ_COMMON_CBLK_DATA_EXTRA);
+    mqc->start = bp;
+    mqc->end = bp + len;
+    /* Insert an artificial 0xFF 0xFF marker at end of the code block */
+    /* data so that the bytein routines stop on it. This saves us comparing */
+    /* the bp and end pointers */
+    /* But before inserting it, backup th bytes we will overwrite */
+    memcpy(mqc->backup, mqc->end, OPJ_COMMON_CBLK_DATA_EXTRA);
+    mqc->end[0] = 0xFF;
+    mqc->end[1] = 0xFF;
+    mqc->bp = bp;
+}
+void opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len,
+                      OPJ_UINT32 extra_writable_bytes)
 {
     /* Implements ISO 15444-1 C.3.5 Initialization of the decoder (INITDEC) */
     /* Note: alternate "J.1 - Initialization of the software-conventions */
     /* decoder" has been tried, but does */
     /* not bring any improvement. */
     /* See https://github.com/uclouvain/openjpeg/issues/921 */
+    opj_mqc_init_dec_common(mqc, bp, len, extra_writable_bytes);
     opj_mqc_setcurctx(mqc, 0);
-    mqc->start = bp;
-    mqc->end = bp + len;
-    mqc->bp = bp;
+    mqc->end_of_byte_stream_counter = 0;
     if (len == 0) {
         mqc->c = 0xff << 16;
     } else {
@@ -457,7 +525,22 @@ OPJ_BOOL opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len)
     mqc->c <<= 7;
     mqc->ct -= 7;
     mqc->a = 0x8000;
-    return OPJ_TRUE;
+}
+
+
+void opj_mqc_raw_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len,
+                          OPJ_UINT32 extra_writable_bytes)
+{
+    opj_mqc_init_dec_common(mqc, bp, len, extra_writable_bytes);
+    mqc->c = 0;
+    mqc->ct = 0;
+}
+
+
+void opq_mqc_finish_dec(opj_mqc_t *mqc)
+{
+    /* Restore the bytes overwritten by opj_mqc_init_dec_common() */
+    memcpy(mqc->end, mqc->backup, OPJ_COMMON_CBLK_DATA_EXTRA);
 }
 
 void opj_mqc_resetstates(opj_mqc_t *mqc)