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) {
