📄 jpgdec.c
字号:
/******************************************************************************
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2003 Intel Corporation. All Rights Reserved.
//
// Description:
// Intel(R) Integrated Performance Primitives Sample Code JPEG Decoder
//
******************************************************************************/
#include <stdio.h>
#include <malloc.h>
#include "sampjpeg.h"
/******************************************************************************
// Name: decoder_init_alloc_jpeg
// Description:
// This function does the prepare work for the JPEG decoding, including:1.
// Parse JPEG header; 2. Read in the JPEG data; 3. Load the table for
// requantization and huffman decoding.
// Input Arguments:
// src - File Pointer to the source JPEG file
// Output Arguments:
// dec_state - Pointer to the decoder state structure, its content
// will be initialized in this function
// picture - Pointer to the output picture in BMP format. The buffer
// in it will be allocatedin this function.
// bitstream - Pointer to the input JPEG bitstream. Its buffers will
// be allocated in this function.
// Returns:
// SAMPLE_STATUS_NOERR - No error
// SAMPLE_STATUS_NOMEM_ERR - Memory error
// SAMPLE_STATUS_NOTSUPPORTED_ERR - Not supported input
******************************************************************************/
sample_status decoder_init_alloc_jpeg(FILE *src, jpeg_dec_state *dec_state,
sample_bitstream *bitstream,
sample_picture *picture)
{
int file_length;
sample_status status;
int i;
/* Read the JPEG file into the bitstream buffer */
/* Get the file size */
fseek(src, 0, SEEK_END);
file_length = ftell(src);
if(0 == file_length) {
return SAMPLE_STATUS_BITSTREAM_ERR;
}
fseek(src, 0, SEEK_SET);
/* Malloc the buffer for input */
bitstream->bs_buffer = NULL;
bitstream->bs_buffer = malloc(file_length);
if(NULL == bitstream->bs_buffer) {
return SAMPLE_STATUS_NOMEM_ERR;
}
bitstream->bs_cur_byte = bitstream->bs_buffer;
bitstream->bs_bytelen = file_length;
bitstream->bs_cur_bitoffset = 0;
fread(bitstream->bs_buffer, 1, file_length, src);
/* Parse the JPEG file header */
status = read_jpeg_header((char **)&bitstream->bs_cur_byte, dec_state);
if(SAMPLE_STATUS_NOERR != status) {
return status;
}
/* Initialize the quantization table */
ippiDCTQuantInvTableInit_JPEG_8u16u(
(Ipp8u *)SAMPLE_ALIGN8(dec_state->tmp_lum_quant_table),
(Ipp16u *)SAMPLE_ALIGN8(dec_state->lum_quant_table));
ippiDCTQuantInvTableInit_JPEG_8u16u(
(Ipp8u *)SAMPLE_ALIGN8(dec_state->tmp_chrom_quant_table),
(Ipp16u *)SAMPLE_ALIGN8(dec_state->chrom_quant_table));
/* Initialize the huffman table */
ippiDecodeHuffmanSpecInit_JPEG_8u(dec_state->lum_dc_huffbits,
dec_state->lum_dc_huffvalues, &(dec_state->lum_dc_huffmansize_table));
ippiDecodeHuffmanSpecInit_JPEG_8u(dec_state->lum_ac_huffbits,
dec_state->lum_ac_huffvalues, &(dec_state->lum_ac_huffmansize_table));
ippiDecodeHuffmanSpecInit_JPEG_8u(dec_state->chrom_dc_huffbits,
dec_state->chrom_dc_huffvalues, &(dec_state->chrom_dc_huffmansize_table));
ippiDecodeHuffmanSpecInit_JPEG_8u(dec_state->chrom_ac_huffbits,
dec_state->chrom_ac_huffvalues, &(dec_state->chrom_ac_huffmansize_table));
/*
// Read the SOI information.
// Since the decoder only support baseline interleave mode, only decode
// the SOI once
*/
status = read_sos((char **)&bitstream->bs_cur_byte);
if(SAMPLE_STATUS_NOERR != status) {
return status;
}
/* Malloc the buffer for the output picture */
picture->pic_width = dec_state->width;
picture->pic_height = dec_state->height;
picture->pic_plane_step[0] = dec_state->width * 3;
picture->pic_plane_num = 1;
picture->pic_channel_num = 3;
picture->pic_format = 0;
picture->pic_plane[0] = (Ipp8u *)malloc(picture->pic_plane_step[0] *
picture->pic_height);
/* Malloc the buffer for the working buffer in decoder state structure */
dec_state->work_buf = NULL;
dec_state->work_buf = (short *)malloc((JPEG_MCU_SIZE + 7) * 2);
/* Reset the DC prediction values */
for(i = 0; i < 3; i ++) {
dec_state->dc_pred[i] = 0;
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: decode_jpeg
// Description:
// This function decodes the JPEG stream into BGR format raw data.
// Input Arguments:
// bitstream - Pointer to the input JPEG bitstream.
// dec_state - Pointer to the decoder state structure.
// Output Arguments:
// picture - Pointer to the output raw BGR data.
// Returns
// SAMPLE_STATUS_NOERR - No error
******************************************************************************/
sample_status decode_jpeg(sample_bitstream *bitstream, sample_picture *picture,
jpeg_dec_state *dec_state)
{
int x_num, y_num;
int i, j;
int used_bits_len = 0;
int marker = 0;
int valid_pre_fetched_bits = 0;
unsigned int pre_fetched_bits = 0;
Ipp8u *dst_buf, *buf;
Ipp16s *work_buf;
Ipp16s *mcu_blocks[3];
x_num = dec_state->height >> 4;
y_num = dec_state->width >> 4;
/* Decode the huffman coefficient */
buf = (Ipp8u *)picture->pic_plane[0] + picture->pic_plane_step[0] *
(picture->pic_height - 1);
work_buf = (Ipp16s *)SAMPLE_ALIGN8(dec_state->work_buf);
for(i = 0; i < x_num; i ++) {
dst_buf = buf;
for(j = 0; j < y_num; j ++) {
/* Decode huffman coefficient for luminance */
ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(bitstream->bs_cur_byte,
&used_bits_len, &work_buf[0], &dec_state->dc_pred[0],
&marker, &pre_fetched_bits, &valid_pre_fetched_bits,
&dec_state->lum_dc_huffmansize_table,
&dec_state->lum_ac_huffmansize_table);
ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(bitstream->bs_cur_byte,
&used_bits_len, &work_buf[64], &dec_state->dc_pred[0],
&marker, &pre_fetched_bits, &valid_pre_fetched_bits,
&dec_state->lum_dc_huffmansize_table,
&dec_state->lum_ac_huffmansize_table);
ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(bitstream->bs_cur_byte,
&used_bits_len, &work_buf[128], &dec_state->dc_pred[0],
&marker, &pre_fetched_bits, &valid_pre_fetched_bits,
&dec_state->lum_dc_huffmansize_table,
&dec_state->lum_ac_huffmansize_table);
ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(bitstream->bs_cur_byte,
&used_bits_len, &work_buf[192], &dec_state->dc_pred[0],
&marker, &pre_fetched_bits, &valid_pre_fetched_bits,
&dec_state->lum_dc_huffmansize_table,
&dec_state->lum_ac_huffmansize_table);
/* Decode huffman coefficient for chrominance */
ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(bitstream->bs_cur_byte,
&used_bits_len, &work_buf[256], &dec_state->dc_pred[1],
&marker, &pre_fetched_bits, &valid_pre_fetched_bits,
&dec_state->chrom_dc_huffmansize_table,
&dec_state->chrom_ac_huffmansize_table);
ippiDecodeHuffman8x8_Direct_JPEG_1u16s_C1(bitstream->bs_cur_byte,
&used_bits_len, &work_buf[320], &dec_state->dc_pred[2],
&marker, &pre_fetched_bits, &valid_pre_fetched_bits,
&dec_state->chrom_dc_huffmansize_table,
&dec_state->chrom_ac_huffmansize_table);
/* Requantization and inverse DCT transformation */
/* For luminance blocks */
ippiDCTQuantInv_JPEG_16s(&work_buf[0], &work_buf[0],
(Ipp16u *)SAMPLE_ALIGN8(dec_state->lum_quant_table));
ippiDCTQuantInv_JPEG_16s(&work_buf[64], &work_buf[64],
(Ipp16u *)SAMPLE_ALIGN8(dec_state->lum_quant_table));
ippiDCTQuantInv_JPEG_16s(&work_buf[128], &work_buf[128],
(Ipp16u *)SAMPLE_ALIGN8(dec_state->lum_quant_table));
ippiDCTQuantInv_JPEG_16s(&work_buf[192], &work_buf[192],
(Ipp16u *)SAMPLE_ALIGN8(dec_state->lum_quant_table));
/* For chrominance blocks */
ippiDCTQuantInv_JPEG_16s(&work_buf[256], &work_buf[256],
(Ipp16u *)SAMPLE_ALIGN8(dec_state->chrom_quant_table));
ippiDCTQuantInv_JPEG_16s(&work_buf[320], &work_buf[320],
(Ipp16u *)SAMPLE_ALIGN8(dec_state->chrom_quant_table));
/* YUV to BGR conversion: BGR888 is the destination format */
mcu_blocks[0] = work_buf;
mcu_blocks[1] = work_buf + JPEG_BLOCK_SIZE * 4;
mcu_blocks[2] = mcu_blocks[1] + JPEG_BLOCK_SIZE;
ippiYCbCr411ToBGRLS_MCU_16s8u_P3C3R((const Ipp16s **)mcu_blocks,
dst_buf, -dec_state->step);
dst_buf += JPEG_MCU_LINE * 3; /* BGR takes 3 bytes */
}
buf -= picture->pic_plane_step[0] * JPEG_MCU_LINE;
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: decoder_free_jpeg
// Description:
// This function free the buffer malloced in the initialization function
// Input arguments:
// stream - Pointer to the JPEG bitstream
// picture - Pointer to the raw BGR plane structure
// dec_state - Pointer to the JPEG decoder structure
// Returns:
// SAMPLE_STATUS_NOERR - No error
******************************************************************************/
sample_status decoder_free_jpeg(sample_bitstream *stream,
sample_picture *picture,
jpeg_dec_state *dec_state)
{
/* Free the buffer in bitstream */
if(NULL != stream->bs_buffer) {
free(stream->bs_buffer);
stream->bs_buffer = NULL;
stream->bs_cur_byte = NULL;
stream->bs_bytelen = 0;
}
/* Free the buffer in picture structure */
if(NULL != picture->pic_plane) {
free(picture->pic_plane[0]);
picture->pic_plane[0] = NULL;
picture->pic_width = 0;
picture->pic_height = 0;
picture->pic_plane_step[0] = 0;
picture->pic_plane_num = 0;
picture->pic_channel_num = 0;
picture->pic_format = 0;
}
/* Free the buffer in decoder state structure */
if(NULL != dec_state->work_buf) {
free(dec_state->work_buf);
dec_state->work_buf = NULL;
}
return SAMPLE_STATUS_NOERR;
}
/* EOF */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -