//-------------------------------------------------------------------------------------- // MQ-CODER // referred to // j2000 by David Janssens // jasper by Image Power // // modified by ida datoshi '02/08/06 //-------------------------------------------------------------------------------------- // 使用法 // MQ-ENCODER // // 初期化 // // MQ_Encoder mq_enc; // mq_enc.init_enc(out); // 出力先のポインタをセット // mq_enc.resetstates(); // 遷移表の初期化 // // 符合化 // // mq_enc.encbyte(in[i]); // バイト単位の符合化 // もしくは // mq_enc.encode(in[i]); // ビット単位の符合化 // をデータ分だけ繰り返す // // コンテキストの変更 // mq_enc.setcurctx(int ctxno); // // 終了時処理 // mq_enc.flush(); // 計算途中もすべて出力する // MQ-DECODER // // 初期化 // // MQ_Decoder mq_dec; // mq_dec.init_dec(in,size);// 入力データのポインタとサイズをセット // mq_dec.resetstates(); // 遷移表の初期化 // // 複合化 // // out[i]=mq_dec.decbyte();// バイト単位の符合化 // もしくは // out[i]=mq_dec.decode(); // ビット単位の符合化 // をデータ分だけ繰り返す // // コンテキストの変更 // mq_dec.setcurctx(int ctxno); #ifndef __m_mqcod_h__ #define __m_mqcod_h__ #define MQC_NUMCTXS 32 //----------------------------------------------------------- // MQコーダ遷移表 typedef struct mqc_state_s { unsigned int qeval; int mps; struct mqc_state_s *nmps; struct mqc_state_s *nlps; } mqc_state_t; 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]}, {0x3401, 1, &mqc_states[5], &mqc_states[13]}, {0x1801, 0, &mqc_states[6], &mqc_states[18]}, {0x1801, 1, &mqc_states[7], &mqc_states[19]}, {0x0ac1, 0, &mqc_states[8], &mqc_states[24]}, {0x0ac1, 1, &mqc_states[9], &mqc_states[25]}, {0x0521, 0, &mqc_states[10], &mqc_states[58]}, {0x0521, 1, &mqc_states[11], &mqc_states[59]}, {0x0221, 0, &mqc_states[76], &mqc_states[66]}, {0x0221, 1, &mqc_states[77], &mqc_states[67]}, {0x5601, 0, &mqc_states[14], &mqc_states[13]}, {0x5601, 1, &mqc_states[15], &mqc_states[12]}, {0x5401, 0, &mqc_states[16], &mqc_states[28]}, {0x5401, 1, &mqc_states[17], &mqc_states[29]}, {0x4801, 0, &mqc_states[18], &mqc_states[28]}, {0x4801, 1, &mqc_states[19], &mqc_states[29]}, {0x3801, 0, &mqc_states[20], &mqc_states[28]}, {0x3801, 1, &mqc_states[21], &mqc_states[29]}, {0x3001, 0, &mqc_states[22], &mqc_states[34]}, {0x3001, 1, &mqc_states[23], &mqc_states[35]}, {0x2401, 0, &mqc_states[24], &mqc_states[36]}, {0x2401, 1, &mqc_states[25], &mqc_states[37]}, {0x1c01, 0, &mqc_states[26], &mqc_states[40]}, {0x1c01, 1, &mqc_states[27], &mqc_states[41]}, {0x1601, 0, &mqc_states[58], &mqc_states[42]}, {0x1601, 1, &mqc_states[59], &mqc_states[43]}, {0x5601, 0, &mqc_states[30], &mqc_states[29]}, {0x5601, 1, &mqc_states[31], &mqc_states[28]}, {0x5401, 0, &mqc_states[32], &mqc_states[28]}, {0x5401, 1, &mqc_states[33], &mqc_states[29]}, {0x5101, 0, &mqc_states[34], &mqc_states[30]}, {0x5101, 1, &mqc_states[35], &mqc_states[31]}, {0x4801, 0, &mqc_states[36], &mqc_states[32]}, {0x4801, 1, &mqc_states[37], &mqc_states[33]}, {0x3801, 0, &mqc_states[38], &mqc_states[34]}, {0x3801, 1, &mqc_states[39], &mqc_states[35]}, {0x3401, 0, &mqc_states[40], &mqc_states[36]}, {0x3401, 1, &mqc_states[41], &mqc_states[37]}, {0x3001, 0, &mqc_states[42], &mqc_states[38]}, {0x3001, 1, &mqc_states[43], &mqc_states[39]}, {0x2801, 0, &mqc_states[44], &mqc_states[38]}, {0x2801, 1, &mqc_states[45], &mqc_states[39]}, {0x2401, 0, &mqc_states[46], &mqc_states[40]}, {0x2401, 1, &mqc_states[47], &mqc_states[41]}, {0x2201, 0, &mqc_states[48], &mqc_states[42]}, {0x2201, 1, &mqc_states[49], &mqc_states[43]}, {0x1c01, 0, &mqc_states[50], &mqc_states[44]}, {0x1c01, 1, &mqc_states[51], &mqc_states[45]}, {0x1801, 0, &mqc_states[52], &mqc_states[46]}, {0x1801, 1, &mqc_states[53], &mqc_states[47]}, {0x1601, 0, &mqc_states[54], &mqc_states[48]}, {0x1601, 1, &mqc_states[55], &mqc_states[49]}, {0x1401, 0, &mqc_states[56], &mqc_states[50]}, {0x1401, 1, &mqc_states[57], &mqc_states[51]}, {0x1201, 0, &mqc_states[58], &mqc_states[52]}, {0x1201, 1, &mqc_states[59], &mqc_states[53]}, {0x1101, 0, &mqc_states[60], &mqc_states[54]}, {0x1101, 1, &mqc_states[61], &mqc_states[55]}, {0x0ac1, 0, &mqc_states[62], &mqc_states[56]}, {0x0ac1, 1, &mqc_states[63], &mqc_states[57]}, {0x09c1, 0, &mqc_states[64], &mqc_states[58]}, {0x09c1, 1, &mqc_states[65], &mqc_states[59]}, {0x08a1, 0, &mqc_states[66], &mqc_states[60]}, {0x08a1, 1, &mqc_states[67], &mqc_states[61]}, {0x0521, 0, &mqc_states[68], &mqc_states[62]}, {0x0521, 1, &mqc_states[69], &mqc_states[63]}, {0x0441, 0, &mqc_states[70], &mqc_states[64]}, {0x0441, 1, &mqc_states[71], &mqc_states[65]}, {0x02a1, 0, &mqc_states[72], &mqc_states[66]}, {0x02a1, 1, &mqc_states[73], &mqc_states[67]}, {0x0221, 0, &mqc_states[74], &mqc_states[68]}, {0x0221, 1, &mqc_states[75], &mqc_states[69]}, {0x0141, 0, &mqc_states[76], &mqc_states[70]}, {0x0141, 1, &mqc_states[77], &mqc_states[71]}, {0x0111, 0, &mqc_states[78], &mqc_states[72]}, {0x0111, 1, &mqc_states[79], &mqc_states[73]}, {0x0085, 0, &mqc_states[80], &mqc_states[74]}, {0x0085, 1, &mqc_states[81], &mqc_states[75]}, {0x0049, 0, &mqc_states[82], &mqc_states[76]}, {0x0049, 1, &mqc_states[83], &mqc_states[77]}, {0x0025, 0, &mqc_states[84], &mqc_states[78]}, {0x0025, 1, &mqc_states[85], &mqc_states[79]}, {0x0015, 0, &mqc_states[86], &mqc_states[80]}, {0x0015, 1, &mqc_states[87], &mqc_states[81]}, {0x0009, 0, &mqc_states[88], &mqc_states[82]}, {0x0009, 1, &mqc_states[89], &mqc_states[83]}, {0x0005, 0, &mqc_states[90], &mqc_states[84]}, {0x0005, 1, &mqc_states[91], &mqc_states[85]}, {0x0001, 0, &mqc_states[90], &mqc_states[86]}, {0x0001, 1, &mqc_states[91], &mqc_states[87]}, {0x5601, 0, &mqc_states[92], &mqc_states[92]}, {0x5601, 1, &mqc_states[93], &mqc_states[93]}, }; //----------------------------------------------------------- // MQデコーダ class MQ_Decoder{ protected: unsigned int creg; // The C 符号レジスタ unsigned int areg; // The A 被加算数 unsigned int ctreg; // The CT バイトカウンタ unsigned char *p_start; // 開始ポインタ unsigned char *p_end; // 終了ポインタ unsigned char *bp; mqc_state_t **mqc_curctx; // 現在のコンテキスト mqc_state_t *mqc_ctxs[MQC_NUMCTXS]; public: //--------------------------------------------------------+ // 初期化 void initalize(unsigned char *ptr,int length){ setcurctx(0); p_start=ptr; p_end=ptr+length; bp=ptr; creg=*bp<<16; bytein(); creg<<=7; ctreg-=7; areg=0x8000; } //--------------------------------------------------------+ // コンテキストの選択 void setcurctx(int ctxno) { mqc_curctx=&mqc_ctxs[ctxno]; } //--------------------------------------------------------+ // コンテキストのセット void setstate(int ctxno, int msb, int prob) { mqc_ctxs[ctxno]=&mqc_states[msb+(prob<<1)]; } //--------------------------------------------------------+ // 1byteデコード unsigned char decbyte() { int byte=0; for(int i=0;i<8;i++){ byte=byte|(decode()<<(7-i)); } return byte; } //--------------------------------------------------------+ // 複合化 int decode() { int d=0; areg-=(*mqc_curctx)->qeval; if ((creg>>16)<(*mqc_curctx)->qeval) { d=lpsexchange(); renormd(); } else { creg-=(*mqc_curctx)->qeval<<16; if ((areg&0x8000)==0) { d=mpsexchange(); renormd(); } else { d=(*mqc_curctx)->mps; } } return d; } protected: //--------------------------------------------------------+ // 遷移表の初期化 void resetstates() { int i; for (i=0; i0x8f) { creg+=0xff00; ctreg=8; } else { bp++; creg+=tmp<<9; ctreg=7; } } else { bp++; creg+=tmp<<8; ctreg=8; } } else { creg+=0xff00; ctreg=8; } } //--------------------------------------------------------+ // 1符合化 int mpsexchange() { int d=0; if (areg<(*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; } //--------------------------------------------------------+ // 0符合化 int lpsexchange() { int d=0; if (areg<(*mqc_curctx)->qeval) { areg=(*mqc_curctx)->qeval; d=(*mqc_curctx)->mps; *mqc_curctx=(*mqc_curctx)->nmps; } else { areg=(*mqc_curctx)->qeval; d=1-(*mqc_curctx)->mps; *mqc_curctx=(*mqc_curctx)->nlps; } return d; } //--------------------------------------------------------+ // 再正規化 void renormd() { do { if (ctreg==0) { bytein(); } areg<<=1; creg<<=1; ctreg--; } while (areg<0x8000); } }; //--------------------------------------------------------------------------------------------------- // MQエンコーダ class MQ_Encoder{ protected: unsigned int creg; // The C 符号レジスタ unsigned int areg; // The A 被加算数 unsigned int ctreg; // The CT バイトカウンタ unsigned char *p_start; // 開始ポインタ unsigned char *bp; mqc_state_t **mqc_curctx; // 現在のコンテキスト mqc_state_t *mqc_ctxs[MQC_NUMCTXS]; public: //--------------------------------------------------------+ // 初期化 void init_enc(unsigned char *ptr) { setcurctx(0); areg=0x8000; creg=0; bp=ptr-1; ctreg=12; if (*bp==0xff) { ctreg=13; } p_start=ptr; } //--------------------------------------------------------+ // 符合化 void encode(int d) { if ((*mqc_curctx)->mps==d) { codemps(); } else { codelps(); } } //--------------------------------------------------------+ // 遷移表の初期化 void resetstates() { int i; for (i=0; i>(7-i))&1);} } protected: //--------------------------------------------------------+ // コンストラクタ MQ_Encoder() { mqc_curctx=NULL; memset(mqc_ctxs,NULL,32); creg=0; areg=0; ctreg=0; resetstates(); } //--------------------------------------------------------+ // バイト出力 void byteout() { if (*bp==0xff) { bp++; *bp=creg>>20; creg&=0xfffff; ctreg=7; } else { if ((creg&0x8000000)==0) { bp++; *bp=creg>>19; creg&=0x7ffff; ctreg=8; } else { (*bp)++; if (*bp==0xff) { creg&=0x7ffffff; bp++; *bp=creg>>20; creg&=0xfffff; ctreg=7; } else { bp++; *bp=creg>>19; creg&=0x7ffff; ctreg=8; } } } } //--------------------------------------------------------+ // 再正規化 void renorme() { do { areg<<=1; creg<<=1; ctreg--; if (ctreg==0) { byteout(); } } while ((areg&0x8000)==0); } //--------------------------------------------------------+ // 1符合化 void codemps() { areg-=(*mqc_curctx)->qeval; if ((areg&0x8000)==0) { if (areg<(*mqc_curctx)->qeval) { areg=(*mqc_curctx)->qeval; } else { creg+=(*mqc_curctx)->qeval; } *mqc_curctx=(*mqc_curctx)->nmps; renorme(); } else { creg+=(*mqc_curctx)->qeval; } } //--------------------------------------------------------+ // 0符合化 void codelps() { areg-=(*mqc_curctx)->qeval; if (areg<(*mqc_curctx)->qeval) { creg+=(*mqc_curctx)->qeval; } else { areg=(*mqc_curctx)->qeval; } *mqc_curctx=(*mqc_curctx)->nlps; renorme(); } //--------------------------------------------------------+ // ビットセット void setbits() { unsigned int tempc=creg+areg; creg|=0xffff; if (creg>=tempc) { creg-=0x8000; } } //--------------------------------------------------------+ // 終了処理 void flush() { setbits(); creg<<=ctreg; byteout(); creg<<=ctreg; byteout(); if (*bp!=0xff) { bp++; } } //--------------------------------------------------------+ // デバッグ用終端符号(要らなかった) void endmark() { *bp=0xff; *(bp+1)=0xac; } }; #endif