www.pudn.com > xiaobo.zip.zip > coder_bp_zt2.c
/***** coder_BP : could get more speed out of arithc and soz arithc could lose its struct and just code from locals ALPHA_REMAP does seem to help speed a bit. The idea of it is to make most common symbols lowest in alpha order, so that the cheezy soz is as fast as possible *****/ #include#include #include #include #include #include "coder.h" extern int tune_param; static int bp_remap[] = {0,1,2,5,3,9,6,11,4,10,7,12,8,13,14,15}; static int bp_unmap[] = {0,1,2,4,8,3,6,10,12,5,9,7,11,13,14,15}; // #define bitModel(bit,P0,PT) do { PT += INC; if (!(bit)) P0 += INC; if ( PT > TOTMAX ) { PT >>= 1; P0 >>= 1; P0++; PT += 2; } } while(0) #define bitModel(bit,P0,PT) do { PT += INC; P0 += ((bit)?0:INC); if ( PT > TOTMAX ) { PT >>= 1; P0 >>= 1; P0++; PT += 2; } } while(0) #define bitEnc(bit,ari,P0,PT) do { arithEncBit(ari,P0,PT,bit); bitModel(bit,P0,PT); } while(0) #define bitDec(bit,ari,P0,PT) do { bit = arithDecBit(ari,P0,PT); bitModel(bit,P0,PT); } while(0) #define INC 20 #define TOTMAX 4000 #define ORDER1_CONTEXTS 5 #define ORDER1_ALPHABET 16 //4 bits #define ORDER1_TOTMAX 15000 #define ORDER1_INC 30 void coderBPZT2_init(coder *c); void coderBPZT2_free(coder *c); void coderBPZT2_flush(coder *c); void coderBPZT2_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); void coderBPZT2_decodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); void coderBPZT2_decodeBandZT_eatZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); void coderBPZT2_decodeBandZT_noZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); void coderBPZT2_decodeBandZT_ZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows); coder coderBPZT2 = { "BP ZT 2", coderBPZT2_init, coderBPZT2_free, NULL,NULL,NULL,NULL, coderBPZT2_encodeBandZT, coderBPZT2_decodeBandZT }; typedef struct { soz ** o1; int zeros_p0[ORDER1_CONTEXTS],zeros_pt[ORDER1_CONTEXTS]; } myInfo; void coderBPZT2_init(coder *c) { myInfo *d; int i; if ( (d = new(myInfo)) == NULL ) errexit("ozero init failed"); c->data = d; if ( (d->o1 = newarray(void *,ORDER1_CONTEXTS)) == NULL ) errexit("Order1_Init failed!"); for(i=0;i o1[i] = sozCreate(c->arith,ORDER1_ALPHABET,ORDER1_TOTMAX,ORDER1_INC)) == NULL ) errexit("context creation failed!"); d->zeros_p0[i] = 1; d->zeros_pt[i] = 2; } } void coderBPZT2_flush(coder *c) { myInfo *d; int i; d = c->data; for(i=0;i o1[i]); d->zeros_p0[i] = 1; d->zeros_pt[i] = 2; } } void coderBPZT2_free(coder *c) { if ( c->data ) { myInfo *d; d = c->data; if ( d->o1 ) { int i; for(i=0;i o1[i] ) sozFree(d->o1[i]); } } free(d); c->data = NULL; } } void coderBPZT2_encodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows) { int x,y,context,block; int *dp,*dpn; soz **o1 = ((myInfo *)me->data)->o1; arithInfo *ari = me->arith; int donemask,nextmask,bitmask; int *zeros_p0,*zeros_pt; bool bottom; zeros_p0 = ((myInfo *)me->data)->zeros_p0; zeros_pt = ((myInfo *)me->data)->zeros_pt; if ( width == (fullw >>1) ) bottom = true; else bottom = false; bitmask = 1< >1;y--;) { dpn = dp + fullw; for(x=width>>1;x--;) { if ( dp[0] & FLAG_CHILD_ZERO ) { // the whole quartet is zero dp[0] -= FLAG_CHILD_ZERO; // it's a zerotree child, don't code dp[1] -= FLAG_CHILD_ZERO; // undo the evil unnecessary work of FindZeroTrees dpn[0] -= FLAG_CHILD_ZERO; dpn[1] -= FLAG_CHILD_ZERO; } else { context = ((dp[0] & donemask)?1:0) + ((dp[1] & donemask)?1:0) + ((dpn[0] & donemask)?1:0) + ((dpn[1] & donemask)?1:0); /*** block = (( dp[0] & bitmask )?1:0) + (( dp[1] & bitmask )?2:0) + (( dpn[0] & bitmask )?4:0) + (( dpn[1] & bitmask )?8:0); ****/ block = ( (dp[0] >>bits) & 1 ) + (( (dp[1] >>bits) & 1 )<<1) + (( (dpn[0] >>bits) & 1 )<<2) + (( (dpn[1] >>bits) & 1 )<<3); sozEncode(o1[context],bp_remap[block]); if ( ! bottom ) { /** code zerotree flags on any zero bits **/ switch(block) { case 15: break; case 14: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 13: if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 12: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 11: if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 10: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 9: if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 8: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 7: if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 6: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 5: if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 4: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 3: if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 2: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 1: if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; case 0: if ( dp[0] & FLAG_ISOLATED_ZERO ) { dp[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dp[1] & FLAG_ISOLATED_ZERO ) { dp[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[0] & FLAG_ISOLATED_ZERO ) { dpn[0] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } if ( dpn[1] & FLAG_ISOLATED_ZERO ) { dpn[1] -= FLAG_ISOLATED_ZERO; bitEnc(0,ari,zeros_p0[context],zeros_pt[context]); } else { bitEnc(1,ari,zeros_p0[context],zeros_pt[context]); } break; } } } dp += 2; dpn += 2; } dp += fullw + fullw - width; } } void coderBPZT2_decodeBandZT(coder *me,int *band,int width,int height,int bits,int fullw,int **rows) { bool bottom; if ( width == (fullw >>1) ) bottom = true; else bottom = false; if ( bottom ) { coderBPZT2_decodeBandZT_noZTs(me,band,width,height,bits,fullw,rows); } else { coderBPZT2_decodeBandZT_ZTs(me,band,width,height,bits,fullw,rows); } } void coderBPZT2_decodeBandZT_noZTs(coder *me,int *band,int width,int height,int bits,int fullw,int **rows) { int x,y,context,block; int *dp,*dpn; soz **o1 = ((myInfo *)me->data)->o1; arithInfo *ari = me->arith; int donemask,nextmask,bitmask; bitmask = 1< data)->o1; arithInfo *ari = me->arith; int donemask,nextmask,bitmask; int offwidth,offheight,*children; int bit,tx,ty; int *zeros_p0,*zeros_pt; zeros_p0 = ((myInfo *)me->data)->zeros_p0; zeros_pt = ((myInfo *)me->data)->zeros_pt; bitmask = 1<