📄 jbg_encode.asm
字号:
.section program;
#include "jbig.h"
_jbig_encode_init:
.global _jbig_encode_init;
// JBIG output SDE
// link 0x10;
p0 = r0;
m2 = r0; // VENC_STATE = r0
m3 = r1; // VARENC_STATE = r1
l0 = 0; // i0 and i1 will be used to load. So the relavant L reg should be zero.
i2 = 0; // Y_STORAGE = 0
a1 = a0 = 0 || p1 = [PSTRIPES];
r0 = r0 -|- r0 || r1 = [PSDE];
m0 = r0; // LTP_OLD = 0
r1 += 20; // Current SDE = original SDE + 20 bytes
m1 = r1; // SRC_SDE = [PSDE] (Original sde pointer)
b0 = r1; // Initially, CUR_SDE = SRC_SDE.
r1 = -r1;
b3 = r1; // b3 = -SRC_SDE
r0 = [PXD];
r1 = [PYD];
r2 = r0;
l3 = r1; // hy = [PYD]
r2 = r2 >> 3 || r0 = [PLHP];
i3 = r0; // HP_STORAGE = [PLHP] (Original pointer)
a1 = r0; // SRC_HP
b1 = r2; // b1 = HBPL
r0 = r0 - r2;
l2 = r0; // l2 for lhp1(the upper line of hp)
r2 = -r2;
b2 = r2; // b2 = N_HBPL
p0 = VARENC_STATE;
rts;
_jbig_encode_init.end:
_jbig_encode:
// Encode an SDE
//< arith_encode initialization
.global _jbig_encode;
[--sp] = (r7:4, p5:3);
p0 = VARENC_STATE;
HP_STORAGE = r0;
i0 = VARENC_STATE;
r7 = 0;
[i0++] = r7; // c = 0
r7.h = 1;
r7 = r7 -|- r7 || [i0++] = r7; // a = 0x10000
[i0++] = r7; // sc = 0
r7 = 11;
[i0++] = r7; // ct = 11
r7 = -1(x);
[i0++] = r7; // buffer = -1
//> arith_encode_init ends
Y = Y_STORAGE; // Y = r4
// In this situation, 8 lines per stripe.
r0 = 8;
a0 = r0;
ENCODE_LAYER:
r0 = a0;
cc = r0 <= 0;
if cc jump ENCODE_LAYER_END;
r0 += -1;
a0 = r0;
r0 = HY;
cc = Y < r0;
if !cc jump ENCODE_LAYER_END;
// Typical prediction
r0 = a1.w;
r1 = HP1;
r2 = HBPL;
r2 = r2 << 4;
r2 = r0 + r2;
cc = r2 == r1;
if cc r1 = r0;
HP1 = r1;
i0 = HP_STORAGE;
p2 = HBPL;
p2 = p2 >> 2; // Attention! 4 bytes loop!
cc = Y == 0;
if cc jump DO_ZERO_COMPARE;
i1 = HP1;
BEGIN_DUAL_COMARE:
loop DO_DUAL_COMPARISON lc1 = p2;
loop_begin DO_DUAL_COMPARISON;
r0 = [i0++] || r1 = [i1++];
cc = r0 == r1;
LTP = cc;
if !cc jump TP_END;
loop_end DO_DUAL_COMPARISON;
jump TP_END;
DO_ZERO_COMPARE:
loop DO_ZERO_COMPARISON lc1 = p2;
loop_begin DO_ZERO_COMPARISON;
r0 = [i0++];
cc = r0 == 0;
LTP = cc;
if !cc jump TP_END;
loop_end DO_ZERO_COMPARISON;
TP_END:
// finally, an arithmetic encode is necessary.
p5 = 0x0e5(z); // for cx
r4 = LTP_OLD;
cc = r4 == LTP;
LTP_OLD = LTP;
r3 = cc; // for pseudo pix
#include "arith_encode_for_tp.h" // call arith_enocde
r0 = LTP_OLD;
cc = r0;
if !cc jump PREDICTION_END;
p3 = HP_STORAGE;
p1 = HBPL;
p3 = p3 + p1; // hp = hp + hbpl;
HP_STORAGE = p3;
p3 = HP1;
p3 = p3 + p1;
HP1 = p3;
Y = Y_STORAGE;
Y += 1;
Y_STORAGE = Y;
jump ENCODE_LAYER;
PREDICTION_END:
LINE_H1 = 0;
LINE_H2 = 0;
_P1 = HP_STORAGE;
Y = Y_STORAGE;
cc = Y == 0;
if cc jump ENCODE_LINE;
_Q1 = HP1;
LINE_H2 = b[_Q1](z);
LINE_H2 <<= 8;
// Encode line
ENCODE_LINE:
p3 = HBPL;
loop ENCODE_LINE_LOOP lc0 = p3;
loop_begin ENCODE_LINE_LOOP;
r7 = b[_P1](z);
LINE_H1 = LINE_H1 | r7;
r6 = lc0;
cc = r6 <= 1;
if cc jump MODEL_TEMPLATE;
cc = Y <= 0;
if cc jump MODEL_TEMPLATE;
p3 = _Q1; // line_h2 |= *(hp - hbpl + 1)
p3 += 1;
r7 = b[p3](z);
LINE_H2 = LINE_H2 | r7;
MODEL_TEMPLATE:
p3 = 8;
loop ENCODE_PIXEL lc1 = p3;
loop_begin ENCODE_PIXEL;
LINE_H2 <<= 1;
LINE_H1 <<= 1;
i0 = LINE_H1;
i1 = LINE_H2;
r7 = 0x0e06(z);
LINE_H2 = extract(LINE_H2, r7.l)(z);
LINE_H2 = LINE_H2 << 4;
r7 = 0x0904(z); // bittst
r6 = extract(LINE_H1, r7.l)(z); // may be used here
LINE_H2 = LINE_H2 | r6;
p5 = LINE_H2; // p5 for cx;
r7 = 0x0801;
r3 = extract(LINE_H1, r7.l)(z); // r3 for pix
#include "arith_encode.h"
LINE_H1 = i0;
LINE_H2 = i1;
loop_end ENCODE_PIXEL;
HP = HP_STORAGE;
HP += 1;
HP_STORAGE = HP;
_Q1 = HP1;
_Q1 += 1;
HP1 = _Q1;
Y = Y_STORAGE;
loop_end ENCODE_LINE_LOOP;
Y += 1;
Y_STORAGE = Y;
// loop_end ENCODE_LAYER;
jump ENCODE_LAYER;
//> Encode lowest resolution layer ends
ENCODE_LAYER_END:
/*
lb0 = [sp++];
lt0 = [sp++];
lc0 = [sp++];
*/
// loop_end ENCODE_SDE;
// unlink;
// Arithmetic encode flush
// find the s->c in the coding interval with the largest
// number of trailing zero bits
TEMP = 1;
CUR_SDE = CUR_SDE_SAVE;
A_REG = [PA_REG];
TEMP = A_REG - TEMP(ns) || C_REG = [PC_REG];
TEMP = TEMP + C_REG(ns) || FCT = [PCT];
r5.l = 0; // TEMP = TEMP & 0xffff0000
cc = TEMP < C_REG;
if !cc jump FLUSH_FIRST_JUMP;
r6 = 0x8000(z);
C_REG = TEMP + R6;
jump FLUSH_SEND_REMAIN;
// else
FLUSH_FIRST_JUMP:
C_REG = TEMP;
FLUSH_SEND_REMAIN:
// send remaining bytes to output
C_REG <<= FCT;
TEMP = TEMP -|- TEMP || BUF = [PBUF];
r5.h = 0xf800;
TEMP = TEMP & C_REG;
cc = TEMP == 0;
if cc jump FLUSH_SECOND_JUMP;
// one final overflow has to be handled
cc = BUF < 0;
if cc jump FLUSH_OUTPUT_ZERO;
TEMP = BUF;
TEMP += 1;
r6 = r6 -|- r6 || b[CUR_SDE++] = TEMP;
r1 = 0xff(z);
cc = TEMP == r1;
if !cc jump FLUSH_OUTPUT_ZERO;
b[CUR_SDE++] = r6;
FLUSH_OUTPUT_ZERO:
r5.h = 0x07ff;
r5.l = 0xf800;
TEMP = C_REG & TEMP;
cc = TEMP == 0;
if cc jump FLUSH_OUTPUT_FINAL_BYTES;
TEMP = TEMP -|- TEMP || FSC = [PSC];
FLUSH_WRITE_REMAIN:
cc = FSC <= 0;
if cc jump FLUSH_OUTPUT_FINAL_BYTES;
FSC += -1;
b[CUR_SDE++] = TEMP;
jump FLUSH_WRITE_REMAIN;
FLUSH_SECOND_JUMP:
cc = BUF < 0;
if cc jump FLUSH_SECOND_SCLOOP;
b[CUR_SDE++] = BUF;
FLUSH_SECOND_SCLOOP:
r6 = r6 -|- r6 || FSC = [PSC];
TEMP = 0xff(z);
FLUSH_WRITE_DUAL_BYTE:
cc = FSC <= 0;
if cc jump FLUSH_OUTPUT_FINAL_BYTES;
FSC += -1;
b[CUR_SDE++] = TEMP;
b[CUR_SDE++] = r6;
jump FLUSH_WRITE_DUAL_BYTE;
FLUSH_OUTPUT_FINAL_BYTES:
r5.h = 0x07ff;
r5.l = 0xf800;
TEMP = TEMP & C_REG;
cc = TEMP == 0;
if cc jump FLUSH_END;
TEMP = C_REG >> 19;
r6 = 0xff(z);
TEMP = TEMP & r6;
r7 = r7 -|- r7 || b[CUR_SDE++] = TEMP;
cc = TEMP == r6;
if !cc jump FLUSH_FINAL_FIRST;
b[CUR_SDE++] = r7;
FLUSH_FINAL_FIRST:
r5.h = 7;
r5.l = 0xf800;
TEMP = C_REG & TEMP;
cc = TEMP == 0;
if cc jump FLUSH_END;
TEMP = C_REG >> 11;
TEMP = TEMP & r6;
b[CUR_SDE++] = TEMP;
cc = TEMP == r6;
if !cc jump FLUSH_END;
b[CUR_SDE++] = r7;
FLUSH_END:
// CUR_SDE_SAVE = CUR_SDE;
REMOVE_ZEROS:
p2 = b3;
p2 = CUR_SDE + p2; // p2 = CUR_SDE - SRC_SDE
cc = p2 == 0;
if cc jump REMOVE_ZEROS_END;
CUR_SDE += -1;
loop REMOVE_ZEROS_LOOP lc0 = p2;
loop_begin REMOVE_ZEROS_LOOP;
r0 = b[CUR_SDE--](z);
cc = r0 == 0;
if !cc jump OUTSIDE_JUDGE;
loop_end REMOVE_ZEROS_LOOP;
OUTSIDE_JUDGE:
CUR_SDE += 2;
r1 = 0xff(z);
cc = r0 == r1;
if !cc jump REMOVE_ZEROS_END;
r1 = 0;
b[CUR_SDE++] = r1;
REMOVE_ZEROS_END:
r0 = 0xff(z);
b[CUR_SDE++] = r0;
r0 = 0x02;
b[CUR_SDE++] = r0;
CUR_SDE_SAVE = CUR_SDE;
r0 = HP_STORAGE;
(r7:4, p5:3) = [sp++];
rts;
// jump ENCODE_SDE;
_jbig_encode.end:
_jbig_encode_end:
.global _jbig_encode_end;
r0 = CUR_SDE_SAVE;
r1 = SRC_SDE;
p0 = VENC_STATE;
r0 = r0 - r1(ns);
r0 += 20;
[PSDE_INDEX] = r0;
rts;
_jbig_encode_end.end:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -