/* * This expansion routine demonstrates the basic algorithm used for * decompression in this article. It first goes to the modeling * module and gets the scale for the current context. (Note that * the scale is fixed here, since this is not an adaptive model). * It then asks the arithmetic decoder to give a high and low * value for the current input number scaled to match the current * range. Finally, it asks the modeling unit to convert the * high and low values to a symbol. */ void expand() { FILE *compressed_file; SYMBOL s; char c; int count; compressed_file=fopen( "software/benchmarks/data/test_comp.cmp", "rb" ); if ( compressed_file == NULL ) error_exit( "Could not open output file" ); puts( "Decoding..." ); printf( "Incoming characters: " ); initialize_input_bitstream(); initialize_arithmetic_decoder( compressed_file ); for ( ; ; ) { s.scale = 11; count = get_current_count( &s ); c = convert_symbol_to_int( count, &s ); if ( c == '\0' ) break; remove_symbol_from_stream( compressed_file, &s ); putc( c, stdout ); } putc( '\n', stdout ); }
/* * The main loop for expansion is very similar to the expansion * routine used in the simpler compression program, ARITH1E.C. The * routine first has to initialize the the arithmetic coder and the * model. The decompression loop differs in a couple of respect. * First of all, it handles the special ESCAPE character, by * removing them from the input bit stream but just throwing them * away otherwise. Secondly, it handles the special FLUSH character. * Once the main decoding loop is done, the cleanup code is called, * and the program exits. * */ void ExpandFile(BIT_FILE *input,FILE *output,int argc,char *argv[]) { SYMBOL s; int c; int count; initialize_options( argc, argv ); initialize_model(); initialize_arithmetic_decoder( input ); for ( ; ; ) { do { get_symbol_scale( &s ); count = get_current_count( &s ); c = convert_symbol_to_int( count, &s ); remove_symbol_from_stream( input, &s ); } while ( c == ESCAPE ); if ( c == DONE ) break; if ( c != FLUSH ) putc( (char) c, output ); else flush_model(); update_model( c ); add_character_to_model( c ); } }
static int decode(AVCodecContext * avctx, void *outdata, int *outdata_size, AVPacket *avpkt) { AVFrame *frame = avctx->coded_frame; MscDecoderContext * mscDecoderContext; MscCodecContext * mscContext; GetBitContext gb; int lastNonZero, value, arithCoderIndex = -1, keyFrame; mscDecoderContext = avctx->priv_data; mscContext = &mscDecoderContext->mscContext; if (frame->data[0]) { avctx->release_buffer(avctx, frame); } frame->reference = 0; if (avctx->get_buffer(avctx, frame) < 0) { av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); return AVERROR(ENOMEM); } keyFrame = isKeyFrame(avctx->frame_number); if (avctx->frame_number == 0) { av_image_alloc(mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, frame->width, frame->height, PIX_FMT_YUV420P, 128); } if (!keyFrame) { av_image_copy(frame->data, frame->linesize, mscContext->referenceFrame->data, mscContext->referenceFrame->linesize, PIX_FMT_YUV420P, frame->width, frame->height); } frame->key_frame = 1; frame->pict_type = AV_PICTURE_TYPE_I; // init encoded data bit buffer init_get_bits(&gb, avpkt->data, avpkt->size * 8); initialize_arithmetic_decoder(&gb); for (int mb_x = 0; mb_x < mscContext->mb_width; mb_x++) { for (int mb_y = 0; mb_y < mscContext->mb_height; mb_y++) { for (int n = 0; n < 6; ++n) { mscContext->dsp.clear_block(mscContext->block[n]); lastNonZero = decode_arith_symbol(&mscContext->lastZeroCodingModel, &gb); if (lastNonZero > 0) { arithCoderIndex = decode_arith_symbol(&mscContext->arithModelIndexCodingModel, &gb); } for (int i = 0; i <= lastNonZero; ++i) { int arithCoderBits = i == 0 ? ARITH_CODER_BITS : arithCoderIndex; value = decode_arith_symbol(&mscContext->arithModels[arithCoderBits], &gb); mscContext->block[n][scantab[i]] = value - mscContext->arithModelAddValue[arithCoderBits]; } // if (avctx->frame_number == 0 && mb_x == 3 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Quantized x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } dequantize(mscContext->block[n], mscContext, keyFrame); // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "Dequantized x=%d, y=%d, n=%d\n", mb_x, mb_y, n); // print_debug_block(avctx, mscContext->block[n]); // } } // if (avctx->frame_number == 0 && mb_x == 0 && mb_y == 0) { // av_log(avctx, AV_LOG_INFO, "IDCT x=%d, y=%d, n=%d\n", mb_x, mb_y, 0); // print_debug_block(avctx, mscContext->block[0]); // } if (keyFrame) { idct_put_block(mscContext, frame, mb_x, mb_y); } else { idct_add_block(mscContext, frame, mb_x, mb_y); } copy_macroblock(frame, mscContext->referenceFrame, mb_x, mb_y); } } emms_c(); *outdata_size = sizeof(AVFrame); *(AVFrame *) outdata = *frame; return avpkt->size; }
/** * Decompresses the data in an input file and writes it in a new file. * @param[in] filename name and path of the input file. * @param[in] output name and path of the output file. * @param[in] see if see will be used. */ static void unzip(char *filename, char *output, BOOL see) { FILE *output_file, *compressed_file; int i, header, parts, part; Uint textlen = 0; decoderTree_t tree; initDecoderTreeStack(); compressed_file = fopen(filename, "rb"); if (!compressed_file) { perror( "Could not open input file"); exit(1); } if (!output) { output = strrchr(filename, '.'); if (output) { *output = '\0'; } else { strcat(filename, ".out"); } output = filename; } output_file = fopen(output, "wb"); if (!output_file) { perror( "Could not open output file"); exit(1); } /* check magic */ header = getc(compressed_file) << 8; header += getc(compressed_file); if (header != MAGIC) { fprintf(stderr, "Invalid compressed file\n"); exit(1); } /* read parts */ parts = getc(compressed_file); initialize_input_bitstream(); initialize_arithmetic_decoder(compressed_file); readAlphabet(compressed_file); setMaxCount(); for (part = 1; part <= parts; part++) { printf("---------- part %d ---------------\n", part); /* read textlen */ for (textlen=0, i=3; i>=0; i--) { textlen += readByte(compressed_file) << (8 * i); } /*if (part == 1) {*/ tree = readDecoderTree(compressed_file); /*}*/ printf("Tree built\n"); printf("Textlen: %ld\n", textlen); printf("FSM...\n"); /*if (part == 1) {*/ DEBUGCODE(printDecoderTree(tree)); makeDecoderFsm(tree); DEBUGCODE(printDecoderTree(tree)); /*}*/ printf("Decoding...\n"); decode(tree, textlen, compressed_file, output_file, see); } /*freeDecoderTree(tree);*/ fclose(compressed_file); fclose(output_file); }