📄 qccentarithmeticencode.3
字号:
SECOND_BLOCK_LENGTH, model, &output_buffer)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncode()", argv[0]); QccErrorExit(); } if (QccENTArithmeticEncodeEnd(model, SECOND_CONTEXT, &output_buffer)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncodeEnd()"); QccErrorExit(); } if (QccBitBufferEnd(&output_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferEnd()", argv[0]); QccErrorExit(); } QccENTArithmeticFreeModel(model); QccExit;}.fi.RE.sp.sp.spDecoder:.RS.nf/* DECODER */#include "QccPack.h"#define FIRST_CONTEXT 0#define SECOND_CONTEXT 1main(int argc, char *argv[]){ int symbol_stream[SYMBOL_STREAM_LENGTH]; QccBitBuffer input_buffer; QccENTArithmeticModel *model = NULL; int num_contexts = 2; int num_symbols[2]; QccInit(argc, argv); QccBitBufferInitialize(&input_buffer); for (context = 0; context < 2; context++) num_symbols[context] = NUM_SYMBOLS; input_buffer.type = QCCBITBUFFER_INPUT; if (QccBitBufferStart(&input_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferStart()", argv[0]); QccErrorExit(); } if ((model = QccENTArithmeticDecodeStart(&input_buffer, num_symbols, 2, NULL, QCCENT_ANYNUMBITS)) == NULL) { QccErrorAddMessage("%s: Error calling QccENTArithmeticDecodeStart()", argv[0]); QccErrorExit(); } if (QccENTArithmeticSetModelContext(model, FIRST_CONTEXT)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticSetModelContext()", argv[0]); QccErrorExit(); } if (QccENTArithmeticDecode(&input_buffer, model, symbol_stream, FIRST_BLOCK_LENGTH)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticDecode()", argv[0]); QccErrorExit(); } if (QccENTArithmeticSetModelContext(model, SECOND_CONTEXT)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticSetModelContext()", argv[0]); QccErrorExit(); } if (QccENTArithmeticDecode(&input_buffer, model, &symbol_stream[FIRST_BLOCK_LENGTH], SECOND_BLOCK_LENGTH)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticDecode()", argv[0]); QccErrorExit(); } if (QccBitBufferEnd(&input_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferEnd()", argv[0]); QccErrorExit(); } QccENTArithmeticFreeModel(model); /* output symbols stream here */ QccExit;}.fi.RE.SS "Multiple-Context Adaptive Arithmetic Coding"Multiple-context adaptive arithmetic coding in which the previous symbolis used as the context of the current symbol. This coder wouldbe a reasonable choice for a Markov process. Note that the numberof contexts is equal to the number of symbols..br.spEncoder:.RS.nf/* ENCODER */#include "QccPack.h"int get_current_context(const int *symbol_stream, int current_symbol){ if ((symbol_stream == NULL) || (current_symbol <= 0)) return(0); return(symbol_stream[current_symbol - 1]);}main(int argc, char *argv[]){ int symbol_stream[SYMBOL_STREAM_LENGTH]; QccBitBuffer output_buffer; QccENTArithmeticModel *model = NULL; int num_contexts = NUM_SYMBOLS; int num_symbols[NUM_SYMBOLS]; QccInit(argc, argv); QccBitBufferInitialize(&output_buffer); for (context = 0; context < NUM_SYMBOLS; context++) num_symbols[context] = NUM_SYMBOLS; /* obtain symbols here */ output_buffer.type = QCCBITBUFFER_OUTPUT; if (QccBitBufferStart(&output_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferStart()", argv[0]); QccErrorExit(); } if ((model = QccENTArithmeticEncodeStart(num_symbols, num_contexts, get_current_context, QCCENT_ANYNUMBITS)) == NULL) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncodeStart()", argv[0]); QccErrorExit(); } if (QccENTArithmeticEncode(symbol_stream, SYMBOL_STREAM_LENGTH, model, &output_buffer)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncode()", argv[0]); QccErrorExit(); } if (QccENTArithmeticEncodeEnd(model, 0, &output_buffer)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncodeEnd()"); QccErrorExit(); } if (QccBitBufferEnd(&output_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferEnd()", argv[0]); QccErrorExit(); } QccENTArithmeticFreeModel(model); QccExit;}.fi.RE.sp.sp.spDecoder:.RS.nf/* DECODER */#include "QccPack.h"int get_current_context(const int *symbol_stream, int current_symbol){ if ((symbol_stream == NULL) || (current_symbol <= 0)) return(0); return(symbol_stream[current_symbol - 1]);}main(int argc, char *argv[]){ int symbol_stream[SYMBOL_STREAM_LENGTH]; QccBitBuffer input_buffer; QccENTArithmeticModel *model = NULL; int num_contexts = NUM_SYMBOLS; int num_symbols[NUM_SYMBOLS]; QccInit(argc, argv); QccBitBufferInitialize(&input_buffer); for (context = 0; context < NUM_SYMBOLS; context++) num_symbols[context] = NUM_SYMBOLS; input_buffer.type = QCCBITBUFFER_INPUT; if (QccBitBufferStart(&input_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferStart()", argv[0]); QccErrorExit(); } if ((model = QccENTArithmeticDecodeStart(&input_buffer, num_symbols, num_contexts, get_current_context, QCCENT_ANYNUMBITS)) == NULL) { QccErrorAddMessage("%s: Error calling QccENTArithmeticDecodeStart()", argv[0]); QccErrorExit(); } if (QccENTArithmeticDecode(&input_buffer, model, symbol_stream, SYMBOL_STREAM_LENGTH)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticDecode()", argv[0]); QccErrorExit(); } if (QccBitBufferEnd(&input_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferEnd()", argv[0]); QccErrorExit(); } QccENTArithmeticFreeModel(model); /* output symbols stream here */ QccExit;}.fi.RE.SS "Single-Context Nonadaptive Arithmetic Coding"Straightforward single-context nonadaptive encoding.Note that adaptive coding is used by default, so we merely needto disable adaption before coding begins..br.spEncoder:.RS.nf/* ENCODER */#include "QccPack.h"main(int argc, char *argv[]){ int symbol_stream[SYMBOL_STREAM_LENGTH]; QccBitBuffer output_buffer; QccENTArithmeticModel *model = NULL; double probabilities[NUM_SYMBOLS]; QccInit(argc, argv); QccBitBufferInitialize(&output_buffer); /* obtain symbols and their probabilities somehow here */ output_buffer.type = QCCBITBUFFER_OUTPUT; if (QccBitBufferStart(&output_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferStart()", argv[0]); QccErrorExit(); } if ((model = QccENTArithmeticEncodeStart(&NUM_SYMBOLS, 1, NULL, QCCENT_ANYNUMBITS)) == NULL) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncodeStart()", argv[0]); QccErrorExit(); } QccENTArithmeticSetModelAdaption(model, QCCENT_NONADAPTIVE); if (QccENTArithmeticSetModelProbabilities(model, probabilities, 0)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticSetModelProbabilities()", argv[0]); QccErrorExit(); } if (QccENTArithmeticEncode(symbol_stream, SYMBOL_STREAM_LENGTH, model, &output_buffer)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncode()", argv[0]); QccErrorExit(); } if (QccENTArithmeticEncodeEnd(model, 0, &output_buffer)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticEncodeEnd()"); QccErrorExit(); } if (QccBitBufferEnd(&output_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferEnd()", argv[0]); QccErrorExit(); } QccENTArithmeticFreeModel(model); QccExit;}.fi.RE.sp.sp.spDecoder:.RS.nf/* DECODER */#include "QccPack.h"main(int argc, char *argv[]){ int symbol_stream[SYMBOL_STREAM_LENGTH]; QccBitBuffer input_buffer; QccENTArithmeticModel *model = NULL; double probabilities[NUM_SYMBOLS]; QccInit(argc, argv); QccBitBufferInitialize(&input_buffer); /* obtain symbol probabilities somehow here */ input_buffer.type = QCCBITBUFFER_INPUT; if (QccBitBufferStart(&input_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferStart()", argv[0]); QccErrorExit(); } if ((model = QccENTArithmeticDecodeStart(&input_buffer, &NUM_SYMBOLS, 1, NULL, QCCENT_ANYNUMBITS)) == NULL) { QccErrorAddMessage("%s: Error calling QccENTArithmeticDecodeStart()", argv[0]); QccErrorExit(); } QccENTArithmeticSetModelAdaption(model, QCCENT_NONADAPTIVE); if (QccENTArithmeticSetModelProbabilities(model, probabilities, 0)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticSetModelProbabilities()", argv[0]); QccErrorExit(); } if (QccENTArithmeticDecode(&input_buffer, model, symbol_stream, SYMBOL_STREAM_LENGTH)) { QccErrorAddMessage("%s: Error calling QccENTArithmeticDecode()", argv[0]); QccErrorExit(); } if (QccBitBufferEnd(&input_buffer)) { QccErrorAddMessage("%s: Error calling QccBitBufferEnd()", argv[0]); QccErrorExit(); } QccENTArithmeticFreeModel(model); /* output symbols stream here */ QccExit;}.fi.RE.SH "NOTES"If.BR QccENTArithmetocEncodeStart()is called using.I target_num_bitsequal to other than.B QCCENT_ANYNUMBITSin order to output exactly .I target_num_bits(in which case,.BR QccENTArithmeticEncodeEnd()is usually.I notcalled at the end of the bitstream),then the last few symbols decoded by.BR QccENTArithmeticDecode()as it nears the end of the bitstream will be validsymbols, but may not be exactly the same as the last few symbolspassed to.BR QccENTArithmeticEncode() .This discrepancyis due to the fact that the arithmeticencoder probably had not completely flushed its state to thebitstream when the.I target_num_bitsthreshold was reached.Thus, the decoder may decode a few symbolserroneously before it realizes that it has encounteredthe end of the bitstream, since the decoderneeds the complete encoder state(which is unknown because it was not flushed tothe bitstream) to decode accurately.Usually, this is not a problem in applications since the.I target_num_bitscapability is most likely only of use in lossy compression, andthe erroneously decoded symbols at the end of thebitstream can be viewed as contributing negligible additional distortionto the lossy representation..SH "SEE ALSO".BR QccENTArithmeticModel (3),.BR QccENTArithmeticGetContext (3),.BR QccBitBuffer (3),.BR QccPackENT (3),.BR QccPack (3).LPI. H. Witten, R. M. Neal, and J. G. Cleary,"Arithmetic Coding for Data Compression,".IR "Communications of the ACM" ,vol. 30, no. 6, pp. 520-540, June 1987..SH AUTHORCopyright (C) 1997-2009 James E. Fowler.\" The programs herein are free software; you can redistribute them an.or.\" modify them under the terms of the GNU General Public License.\" as published by the Free Software Foundation; either version 2.\" of the License, or (at your option) any later version..\" .\" These programs are distributed in the hope that they will be useful,.\" but WITHOUT ANY WARRANTY; without even the implied warranty of.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the.\" GNU General Public License for more details..\" .\" You should have received a copy of the GNU General Public License.\" along with these programs; if not, write to the Free Software.\" Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -