📄 vtc_pezw_pezw_ac.cpp
字号:
/****************************************************************************//* MPEG4 Visual Texture Coding (VTC) Mode Software *//* *//* This software was jointly developed by the following participants: *//* *//* Single-quant, multi-quant and flow control *//* are provided by Sarnoff Corporation *//* Iraj Sodagar (iraj@sarnoff.com) *//* Hung-Ju Lee (hjlee@sarnoff.com) *//* Paul Hatrack (hatrack@sarnoff.com) *//* Shipeng Li (shipeng@sarnoff.com) *//* Bing-Bing Chai (bchai@sarnoff.com) *//* B.S. Srinivas (bsrinivas@sarnoff.com) *//* *//* Bi-level is provided by Texas Instruments *//* Jie Liang (liang@ti.com) *//* *//* Shape Coding is provided by OKI Electric Industry Co., Ltd. *//* Zhixiong Wu (sgo@hlabs.oki.co.jp) *//* Yoshihiro Ueda (yueda@hlabs.oki.co.jp) *//* Toshifumi Kanamaru (kanamaru@hlabs.oki.co.jp) *//* *//* OKI, Sharp, Sarnoff, TI and Microsoft contributed to bitstream *//* exchange and bug fixing. *//* *//* *//* In the course of development of the MPEG-4 standard, this software *//* module is an implementation of a part of one or more MPEG-4 tools as *//* specified by the MPEG-4 standard. *//* *//* The copyright of this software belongs to ISO/IEC. ISO/IEC gives use *//* of the MPEG-4 standard free license to use this software module or *//* modifications thereof for hardware or software products claiming *//* conformance to the MPEG-4 standard. *//* *//* Those intending to use this software module in hardware or software *//* products are advised that use may infringe existing patents. The *//* original developers of this software module and their companies, the *//* subsequent editors and their companies, and ISO/IEC have no liability *//* and ISO/IEC have no liability for use of this software module or *//* modification thereof in an implementation. *//* *//* Permission is granted to MPEG members to use, copy, modify, *//* and distribute the software modules ( or portions thereof ) *//* for standardization activity within ISO/IEC JTC1/SC29/WG11. *//* *//* Copyright 1995, 1996, 1997, 1998 ISO/IEC *//****************************************************************************//****************************************************************************//* Texas Instruments Predictive Embedded Zerotree (PEZW) Image Codec *//* Developed by Jie Liang (liang@ti.com) *//* */ /* Copyright 1996, 1997, 1998 Texas Instruments *//****************************************************************************//**************************************************************************** File name: PEZW_ac.c Author: Jie Liang (liang@ti.com) Functions: adaptive arithmetic coding functions Revisions: This file was adopted from public domain arithmetic coder with changes suited to PEZW coder.*****************************************************************************/#include <stdio.h>#include <stdlib.h>#include <memory.h>#include "PEZW_ac.hpp"/* size of memory blocks allocated each time running out of buffer for bitstream */#define MemBlocksize 1000#ifndef DEBUG_ZTR_DEC_BS#define DEBUG_ZTR_DEC_BS 0#endif#define Code_value_bits 16#define Top_value (((long)1<<Code_value_bits)-1)#define First_qtr (Top_value/4+1)#define Half (2*First_qtr)#define Third_qtr (3*First_qtr)static void output_bit (Ac_encoder *, int);static void bit_plus_follow (Ac_encoder *, int);static int input_bit (Ac_decoder *);static void update_model (Ac_model *, int);#define error(m) \do { \ fflush (stdout); \ fprintf (stderr, "%s:%d: error: ", __FILE__, __LINE__); \ fprintf (stderr, m); \ fprintf (stderr, "\n"); \ exit (1); \} while (0)#define check(b,m) \do { \ if (b) \ error (m); \} while (0)static voidoutput_bit (Ac_encoder *ace, int bit){ ace->buffer <<=1; if (bit) ace->buffer |= 0x01; ace->bits_to_go -= 1; ace->total_bits += 1; if (ace->bits_to_go==0) { if (ace->fp) putc (ace->buffer, ace->fp); else putc_buffer (ace->buffer, &ace->stream, &ace->original_stream, &ace->space_left); ace->bits_to_go = 8; ace->buffer = 0; } return;}static voidbit_plus_follow (Ac_encoder *ace, int bit){ output_bit (ace, bit); while (ace->fbits > 0) { output_bit (ace, !bit); ace->fbits -= 1; } return;}static intinput_bit (Ac_decoder *acd){ int t; if (acd->bits_to_go==0) { if (acd->fp) acd->buffer = getc (acd->fp); else acd->buffer = getc_buffer(&acd->stream); acd->bits_to_go = 8; } t = ((acd->buffer&0x80)>0); acd->buffer <<=1; acd->bits_to_go -= 1; return t;}static voidupdate_model (Ac_model *acm, int sym){ int i; if (acm->cfreq[0]==acm->Max_frequency) { int cum = 0; acm->cfreq[acm->nsym] = 0; for (i = acm->nsym-1; i>=0; i--) { acm->freq[i] = (acm->freq[i] + 1) / 2; cum += acm->freq[i]; acm->cfreq[i] = cum; } } acm->freq[sym] += 1; for (i=sym; i>=0; i--) acm->cfreq[i] += 1; return;}voidAc_encoder_init (Ac_encoder *ace, unsigned char *fn, int len, int IsStream){ if (IsStream){ ace->stream = fn; ace->original_stream = fn; ace->space_left = len; ace->fp = NULL; } else if (fn) { ace->fp = fopen ((char *)fn, "w"); check (!ace->fp, "arithmetic encoder could not open file"); } else { ace->fp = NULL; } ace->bits_to_go = 8; ace->low = 0; ace->high = Top_value; ace->fbits = 0; ace->buffer = 0; ace->total_bits = 0; return;}voidAc_encoder_done (Ac_encoder *ace){ ace->fbits += 1; if (ace->low < First_qtr) bit_plus_follow (ace, 0); else bit_plus_follow (ace, 1); if (ace->fp){ putc (ace->buffer >> ace->bits_to_go, ace->fp); fclose (ace->fp); } else if (ace->bits_to_go <8) putc_buffer (ace->buffer << ace->bits_to_go, &ace->stream, &ace->original_stream, &ace->space_left); if (DEBUG_ZTR_DEC_BS) fprintf(stdout, "bits to go: %d last byte: %d\n", ace->bits_to_go, *(ace->stream-1)); return;}voidAc_decoder_open (Ac_decoder *acd, unsigned char *fn, int IsStream){ if (IsStream){ acd->stream = fn; acd->fp = NULL; } else { acd->fp = fopen ((char *)fn, "r"); check (!acd->fp, "arithmetic decoder could not open file"); } return;}voidAc_decoder_init (Ac_decoder *acd, unsigned char *fn){ int i; acd->bits_to_go = 0; acd->garbage_bits = 0; acd->value = 0; for (i=1; i<=Code_value_bits; i++) { acd->value = 2*acd->value + input_bit(acd); } acd->low = 0; acd->high = Top_value; return;}voidAc_decoder_done (Ac_decoder *acd){ fclose (acd->fp); return;}voidAc_model_init (Ac_model *acm, int nsym, int *ifreq, int Max_freq, int adapt){ int i; acm->nsym = nsym;#ifndef MODEL_COUNT_LARGE acm->freq = (unsigned char *) (void *) calloc (nsym, sizeof (unsigned char));#else acm->freq = (int *) (void *) calloc (nsym, sizeof (int));#endif check (!acm->freq, "arithmetic coder model allocation failure"); acm->cfreq = (int *) (void *) calloc (nsym+1, sizeof (int)); check (!acm->cfreq, "arithmetic coder model allocation failure"); acm->Max_frequency = Max_freq; acm->adapt = adapt; if (ifreq) { acm->cfreq[acm->nsym] = 0; for (i=acm->nsym-1; i>=0; i--) { acm->freq[i] = ifreq[i]; acm->cfreq[i] = acm->cfreq[i+1] + acm->freq[i]; } if (acm->cfreq[0] > acm->Max_frequency) { int cum = 0; acm->cfreq[acm->nsym] = 0; for (i = acm->nsym-1; i>=0; i--) { acm->freq[i] = (acm->freq[i] + 1) / 2; cum += acm->freq[i]; acm->cfreq[i] = cum; } } if (acm->cfreq[0] > acm->Max_frequency) error ("arithmetic coder model max frequency exceeded"); } else { for (i=0; i<acm->nsym; i++) { acm->freq[i] = 1; acm->cfreq[i] = acm->nsym - i; } acm->cfreq[acm->nsym] = 0; } return;}voidAc_model_save (Ac_model *acm, int *ifreq){ int i; for (i=acm->nsym-1; i>=0; i--) { ifreq[i] = acm->freq[i]; } return;}voidAc_model_done (Ac_model *acm){ acm->nsym = 0; free (acm->freq); acm->freq = NULL; free (acm->cfreq); acm->cfreq = NULL; return;}longAc_encoder_bits (Ac_encoder *ace){ return ace->total_bits;}voidAc_encode_symbol (Ac_encoder *ace, Ac_model *acm, int sym){ long range; check (sym<0||sym>=acm->nsym, "symbol out of range");#ifdef AC_DEBUG printf(" %d ", sym);#endif range = (long)(ace->high-ace->low)+1; ace->high = ace->low + (range*acm->cfreq[sym])/acm->cfreq[0]-1; ace->low = ace->low + (range*acm->cfreq[sym+1])/acm->cfreq[0]; for (;;) { if (ace->high<Half) { bit_plus_follow (ace, 0); } else if (ace->low>=Half) { bit_plus_follow (ace, 1); ace->low -= Half; ace->high -= Half; } else if (ace->low>=First_qtr && ace->high<Third_qtr) { ace->fbits += 1; ace->low -= First_qtr; ace->high -= First_qtr; } else break; ace->low = 2*ace->low; ace->high = 2*ace->high+1; } if (acm->adapt) update_model (acm, sym); return;}intAc_decode_symbol (Ac_decoder *acd, Ac_model *acm){ long range; int cum; int sym; range = (long)(acd->high-acd->low)+1; cum = (((long)(acd->value-acd->low)+1)*acm->cfreq[0]-1)/range; for (sym = 0; acm->cfreq[sym+1]>cum; sym++) /* do nothing */ ; check (sym<0||sym>=acm->nsym, "symbol out of range"); acd->high = acd->low + (range*acm->cfreq[sym])/acm->cfreq[0]-1; acd->low = acd->low + (range*acm->cfreq[sym+1])/acm->cfreq[0]; for (;;) { if (acd->high<Half) { /* do nothing */ } else if (acd->low>=Half) { acd->value -= Half; acd->low -= Half; acd->high -= Half; } else if (acd->low>=First_qtr && acd->high<Third_qtr) { acd->value -= First_qtr; acd->low -= First_qtr; acd->high -= First_qtr; } else break; acd->low = 2*acd->low; acd->high = 2*acd->high+1; acd->value = 2*acd->value + input_bit(acd); } if (acm->adapt) update_model (acm, sym);#ifdef AC_DEBUG printf(" %d ", sym);#endif return sym;}int getc_buffer (unsigned char **stream){ int output; output = **stream; (*stream)++; return(output);}void putc_buffer (int x, unsigned char **buffer_curr, unsigned char **buffer_start, int *space_len){ int len; unsigned char *temp; if (*space_len<=0) { /* reallocate memory */ temp = *buffer_start; len = *buffer_curr-*buffer_start; *buffer_start = (unsigned char *) calloc(len+MemBlocksize, sizeof(char)); memcpy(*buffer_start, temp, len); *buffer_curr = *buffer_start+len; *space_len=MemBlocksize; free(temp); } **buffer_curr=x; (*buffer_curr)++; (*space_len)--; return;}/* adjust decoder buffer pointer to the right byte at the end of the decoding. Returns the bit location for the last bit */ int AC_decoder_buffer_adjust (Ac_decoder *acd){ int bits_to_go; /* rewind 14 bits for buffer */ if (DEBUG_ZTR_DEC_BS) fprintf(stdout, "bits to go: %d \n",acd->bits_to_go); if (acd->bits_to_go>1) acd->stream--; acd->stream--; if (acd->bits_to_go>1) bits_to_go = acd->bits_to_go-2; else bits_to_go = acd->bits_to_go+6; return (bits_to_go);}void AC_free_model (Ac_model *acm){ free(acm->freq); free(acm->cfreq);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -