:: commit f6ed0ca2de6395da936316d73ca67db5bc662a8d

Kamila Szewczyk <kspalaiologos@gmail.com> — 2022-05-13 08:50

parents: ce572ea584

change CM api to buffer-wise

diff --git a/include/cm.h b/include/cm.h
index ebe5d76..413c954 100644
--- a/include/cm.h
+++ b/include/cm.h
@@ -19,7 +19,7 @@ typedef struct {
 void flush(state * s);
 void init(state * s);
 void begin(state * s);
-void encode_byte(state * s, u8 c);
-u8 decode_byte(state * s);
+void encode_bytes(state * s, u8 * c, s32 size);
+void decode_bytes(state * s, u8 * c, s32 size);
 
 #endif
diff --git a/src/cm.c b/src/cm.c
index 3047ad9..386da4d 100644
--- a/src/cm.c
+++ b/src/cm.c
@@ -104,88 +104,94 @@ void begin(state * s) {
             for (int k = 0; k < 17; k++) s->C2[2 * j + i][k] = (k << 12) - (k == 16);
 }
 
-void encode_byte(state * s, u8 c) {
-    if (s->c1 == s->c2)
-        ++s->run;
-    else
-        s->run = 0;
-
-    const int f = s->run > 2;
-
-    int ctx = 1;
-
-    while (ctx < 256) {
-        const int p0 = s->C0[ctx];
-        const int p1 = s->C1[s->c1][ctx];
-        const int p2 = s->C1[s->c2][ctx];
-        const int p = ((p0 + p1) * 7 + p2 + p2) >> 4;
-
-        const int j = p >> 12;
-        const int x1 = s->C2[2 * ctx + f][j];
-        const int x2 = s->C2[2 * ctx + f][j + 1];
-        const int ssep = x1 + (((x2 - x1) * (p & 4095)) >> 12);
-
-        if (c & 128) {
-            encodebit1(s, ssep * 3 + p);
-            s->C0[ctx] = update1(s->C0[ctx], 2);
-            s->C1[s->c1][ctx] = update1(s->C1[s->c1][ctx], 4);
-            s->C2[2 * ctx + f][j] = update1(s->C2[2 * ctx + f][j], 6);
-            s->C2[2 * ctx + f][j + 1] = update1(s->C2[2 * ctx + f][j + 1], 6);
-            ctx += ctx + 1;
-        } else {
-            encodebit0(s, ssep * 3 + p);
-            s->C0[ctx] = update0(s->C0[ctx], 2);
-            s->C1[s->c1][ctx] = update0(s->C1[s->c1][ctx], 4);
-            s->C2[2 * ctx + f][j] = update0(s->C2[2 * ctx + f][j], 6);
-            s->C2[2 * ctx + f][j + 1] = update0(s->C2[2 * ctx + f][j + 1], 6);
-            ctx += ctx;
+void encode_bytes(state * s, u8 * buf, s32 size) {
+    for(s32 i = 0; i < size; i++) {
+        u8 c = buf[i];
+
+        if (s->c1 == s->c2)
+            ++s->run;
+        else
+            s->run = 0;
+
+        const int f = s->run > 2;
+
+        int ctx = 1;
+
+        while (ctx < 256) {
+            const int p0 = s->C0[ctx];
+            const int p1 = s->C1[s->c1][ctx];
+            const int p2 = s->C1[s->c2][ctx];
+            const int p = ((p0 + p1) * 7 + p2 + p2) >> 4;
+
+            const int j = p >> 12;
+            const int x1 = s->C2[2 * ctx + f][j];
+            const int x2 = s->C2[2 * ctx + f][j + 1];
+            const int ssep = x1 + (((x2 - x1) * (p & 4095)) >> 12);
+
+            if (c & 128) {
+                encodebit1(s, ssep * 3 + p);
+                s->C0[ctx] = update1(s->C0[ctx], 2);
+                s->C1[s->c1][ctx] = update1(s->C1[s->c1][ctx], 4);
+                s->C2[2 * ctx + f][j] = update1(s->C2[2 * ctx + f][j], 6);
+                s->C2[2 * ctx + f][j + 1] = update1(s->C2[2 * ctx + f][j + 1], 6);
+                ctx += ctx + 1;
+            } else {
+                encodebit0(s, ssep * 3 + p);
+                s->C0[ctx] = update0(s->C0[ctx], 2);
+                s->C1[s->c1][ctx] = update0(s->C1[s->c1][ctx], 4);
+                s->C2[2 * ctx + f][j] = update0(s->C2[2 * ctx + f][j], 6);
+                s->C2[2 * ctx + f][j + 1] = update0(s->C2[2 * ctx + f][j + 1], 6);
+                ctx += ctx;
+            }
+
+            c <<= 1;
         }
 
-        c <<= 1;
+        s->c2 = s->c1;
+        s->c1 = ctx & 255;
     }
-
-    s->c2 = s->c1;
-    s->c1 = ctx & 255;
 }
 
-u8 decode_byte(state * s) {
-    if (s->c1 == s->c2)
-        ++s->run;
-    else
-        s->run = 0;
-
-    const int f = s->run > 2;
-
-    int ctx = 1;
-
-    while (ctx < 256) {
-        const int p0 = s->C0[ctx];
-        const int p1 = s->C1[s->c1][ctx];
-        const int p2 = s->C1[s->c2][ctx];
-        const int p = ((p0 + p1) * 7 + p2 + p2) >> 4;
-
-        const int j = p >> 12;
-        const int x1 = s->C2[2 * ctx + f][j];
-        const int x2 = s->C2[2 * ctx + f][j + 1];
-        const int ssep = x1 + (((x2 - x1) * (p & 4095)) >> 12);
-
-        const int bit = decodebit(s, ssep * 3 + p);
-
-        if (bit) {
-            s->C0[ctx] = update1(s->C0[ctx], 2);
-            s->C1[s->c1][ctx] = update1(s->C1[s->c1][ctx], 4);
-            s->C2[2 * ctx + f][j] = update1(s->C2[2 * ctx + f][j], 6);
-            s->C2[2 * ctx + f][j + 1] = update1(s->C2[2 * ctx + f][j + 1], 6);
-            ctx += ctx + 1;
-        } else {
-            s->C0[ctx] = update0(s->C0[ctx], 2);
-            s->C1[s->c1][ctx] = update0(s->C1[s->c1][ctx], 4);
-            s->C2[2 * ctx + f][j] = update0(s->C2[2 * ctx + f][j], 6);
-            s->C2[2 * ctx + f][j + 1] = update0(s->C2[2 * ctx + f][j + 1], 6);
-            ctx += ctx;
+void decode_bytes(state * s, u8 * c, s32 size) {
+    for(s32 i = 0; i < size; i++) {
+        if (s->c1 == s->c2)
+            ++s->run;
+        else
+            s->run = 0;
+
+        const int f = s->run > 2;
+
+        int ctx = 1;
+
+        while (ctx < 256) {
+            const int p0 = s->C0[ctx];
+            const int p1 = s->C1[s->c1][ctx];
+            const int p2 = s->C1[s->c2][ctx];
+            const int p = ((p0 + p1) * 7 + p2 + p2) >> 4;
+
+            const int j = p >> 12;
+            const int x1 = s->C2[2 * ctx + f][j];
+            const int x2 = s->C2[2 * ctx + f][j + 1];
+            const int ssep = x1 + (((x2 - x1) * (p & 4095)) >> 12);
+
+            const int bit = decodebit(s, ssep * 3 + p);
+
+            if (bit) {
+                s->C0[ctx] = update1(s->C0[ctx], 2);
+                s->C1[s->c1][ctx] = update1(s->C1[s->c1][ctx], 4);
+                s->C2[2 * ctx + f][j] = update1(s->C2[2 * ctx + f][j], 6);
+                s->C2[2 * ctx + f][j + 1] = update1(s->C2[2 * ctx + f][j + 1], 6);
+                ctx += ctx + 1;
+            } else {
+                s->C0[ctx] = update0(s->C0[ctx], 2);
+                s->C1[s->c1][ctx] = update0(s->C1[s->c1][ctx], 4);
+                s->C2[2 * ctx + f][j] = update0(s->C2[2 * ctx + f][j], 6);
+                s->C2[2 * ctx + f][j + 1] = update0(s->C2[2 * ctx + f][j + 1], 6);
+                ctx += ctx;
+            }
         }
-    }
 
-    s->c2 = s->c1;
-    return s->c1 = ctx & 255;
+        s->c2 = s->c1;
+        c[i] = s->c1 = ctx & 255;
+    }
 }
diff --git a/src/libbz3.c b/src/libbz3.c
index 378517b..8fbaf9d 100644
--- a/src/libbz3.c
+++ b/src/libbz3.c
@@ -164,7 +164,7 @@ PUBLIC_API s32 bz3_encode_block(struct bz3_state * state, u8 * buffer, s32 data_
     begin(state->cm_state);
     state->cm_state->out_queue = b1 + overhead * 4 + 1;
     state->cm_state->output_ptr = 0;
-    for (s32 i = 0; i < data_size; i++) encode_byte(state->cm_state, b2[i]);
+    encode_bytes(state->cm_state, b2, data_size);
     flush(state->cm_state);
     data_size = state->cm_state->output_ptr;
 
@@ -250,7 +250,7 @@ PUBLIC_API s32 bz3_decode_block(struct bz3_state * state, u8 * buffer, s32 data_
     else
         size_src = orig_size;
 
-    for (s32 i = 0; i < size_src; i++) b2[i] = decode_byte(state->cm_state);
+    decode_bytes(state->cm_state, b2, size_src);
     swap(b1, b2);
 
     if(bwt_idx >= size_src) {
tab: 248 wrap: offon