实例介绍
rgb编码成jpeg,验证通过的
/******************************************************************************
// 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 Encoder
//
******************************************************************************/
#include <stdio.h>
#include <malloc.h>
#include "sampjpeg.h"
/******************************************************************************
// Name: encoder_init_alloc_jpeg
// Description:
// This function does the prepare work for the JPEG encoding, including:1.
// Parse BMP header; 2. Read in the BMP data; 3 Convert the BGR data into
// YUV format. 4. Load the table for quantization and huffman encoding.
// Input Arguments:
// src - File Pointer to the source BMP file
// quality_ind - Quality indicator. 1: high quality; 0: low quality
// Output Arguments:
// enc_state - Pointer to the encoder state structure, its content
// will be initialized in this function
// picture - Pointer to the source picture in YUV format. The buffer
// in it will be allocated and filled with YUV data in this
// function.
// bitstream - Pointer to the output 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_ERR - Other errors
******************************************************************************/
sample_status encoder_init_alloc_jpeg(FILE *src, int quality_ind,
jpeg_enc_state *enc_state,
sample_picture *picture,
sample_bitstream *bitstream)
{
int data_size;
int x_num, y_num;
int i, j;
int num_bytes;
void *rgb_buffer = NULL;
void *src_buf, *buf;
Ipp16s *dst_buf[3];
int yuv_size;
int color_mode;
int data32;
short *buffer;
sample_status status;
Ipp8u *quant_table1, *table1;
Ipp8u *quant_table2, *table2;
/* Read the BMP file for format information */
status = read_bmp_file(src, enc_state, &color_mode, &data_size);
if(SAMPLE_STATUS_NOERR != status) {
return status;
}
/* Malloc the buffer for RGB data */
if(JPEG_BGR888 == color_mode) {
rgb_buffer = (Ipp8u *)malloc(data_size 7);
num_bytes = 3;
} else {
rgb_buffer = (Ipp16u *)malloc(data_size 7);
num_bytes = 2;
}
if(rgb_buffer == NULL) {
return SAMPLE_STATUS_NOMEM_ERR;
}
src_buf = (int *)SAMPLE_ALIGN8(rgb_buffer);
data32 = fread(src_buf, 1, data_size, src);
if(data32 != data_size) {
return SAMPLE_STATUS_ERR;
}
/* Malloc the buffer for Y, Cb, Cr */
yuv_size = enc_state->width * enc_state->height;
yuv_size = yuv_size (yuv_size >> 1);
/*
// Malloc the buffer for encoder input and output.
// Half of the buffer is used for YUV, another half is used for
// Output bitstream;
*/
enc_state->in_buf = NULL;
enc_state->out_buf = NULL;
enc_state->in_buf = (short *)malloc(yuv_size * 2);
buffer = (short *)SAMPLE_ALIGN8(enc_state->in_buf);
/* Initialize the input structure */
picture->pic_plane[0] = buffer;
picture->pic_width = enc_state->width;
picture->pic_height = enc_state->height;
picture->pic_plane_step[0] = enc_state->width;
picture->pic_plane_num = 1;
/*
// Assign the buffer for encoder ouput bitstream
// It is assumed that the output size will not be larger than
// input size a lot
*/
enc_state->out_buf = (short *)malloc(yuv_size * 3);
buffer = enc_state->out_buf;
bitstream->bs_buffer = (unsigned char *)buffer;
bitstream->bs_bytelen = yuv_size * 3;
bitstream->bs_cur_byte = bitstream->bs_buffer;
bitstream->bs_cur_bitoffset = 0;
/*
// Check if the picture width and height is multiple of 16, if not,
// return not supported information
*/
if(enc_state->width & 0xf) {
return SAMPLE_STATUS_NOTSUPPORTED_ERR;
}
if(enc_state->height & 0xf) {
return SAMPLE_STATUS_NOTSUPPORTED_ERR;
}
/* Do the color conversion, from BGR to Y:U:V = 4:1:1 */
/*
// x_num is the horizontal MCU number.
// x_num = width / 16
// y_num is the vertical MCU number
// y_num = height / 16;
*/
x_num = enc_state->width >> 4;
y_num = enc_state->height >> 4;
/* Jump to the last MCU line */
src_buf = (char *)src_buf (y_num * JPEG_MCU_LINE - 1) * enc_state->step;
buf = src_buf;
/* Prepare the Y, U, V block pointer */
dst_buf[0] = picture->pic_plane[0];
dst_buf[1] = dst_buf[0] (64 << 2);
dst_buf[2] = dst_buf[1] 64;
for(i = 0; i < y_num; i ) {
src_buf = buf;
for(j = 0; j < x_num; j ) {
if(JPEG_BGR888 == color_mode) {
ippiBGRToYCbCr411LS_MCU_8u16s_C3P3R((Ipp8u *)src_buf,
-(enc_state->step), dst_buf);
/* Move to next MCU */
src_buf = (char *)src_buf JPEG_MCU_LINE * num_bytes;
dst_buf[0] = 6 * JPEG_BLOCK_SIZE;
dst_buf[1] = 6 * JPEG_BLOCK_SIZE;
dst_buf[2] = 6 * JPEG_BLOCK_SIZE;
} else if (JPEG_BGR555 == color_mode) {
ippiBGR555ToYCbCr411LS_MCU_16u16s_C3P3R((const Ipp16u *)src_buf,
-(enc_state->step),
dst_buf);
/* Move to next MCU */
src_buf = (char *)src_buf JPEG_MCU_LINE * num_bytes;
dst_buf[0] = 6 * JPEG_BLOCK_SIZE;
dst_buf[1] = 6 * JPEG_BLOCK_SIZE;
dst_buf[2] = 6 * JPEG_BLOCK_SIZE;
} else {
ippiBGR565ToYCbCr411LS_MCU_16u16s_C3P3R((const Ipp16u *)src_buf,
-(enc_state->step), dst_buf);
/* Move to next MCU */
src_buf = (char *)src_buf JPEG_MCU_LINE * num_bytes;
dst_buf[0] = 6 * JPEG_BLOCK_SIZE;
dst_buf[1] = 6 * JPEG_BLOCK_SIZE;
dst_buf[2] = 6 * JPEG_BLOCK_SIZE;
}
}
/* Move to next line of slice */
buf = (char *)buf - JPEG_MCU_LINE * enc_state->step;
}
enc_state->color_mode = color_mode;
/*
// Notes:
// In above code, because the input BMP file is stored up-bottom
// inverted, so the src_buf storage order is also inverted. To make
// it normal, the color conversion begins from the buffer end, and
// step back to the buffer beginning. After the color conversion,
// the pixel in the dst_buf is in normal up-down order.
// Besides, the dst_buf contains the components in order of:
// Y block, Y block, Y block, Y block, U block, V block
*/
free(rgb_buffer); /* This buffer is no longer in use */
/* Set the quality indicator */
enc_state->quality = quality_ind;
/* Load the quantization table according to the quality indication*/
/*
// Because of the DCT and quantization are integrated to enhance the
// performance, the raw quantization tables must be modified by the
// DCT coefficients.
*/
/*
// The quality is indicated by quality_ind, its values can be:
// 1: high quality encoding; 0: low quality encoding
*/
quant_table1 = malloc((JPEG_BLOCK_SIZE 4) * 2);
table1 = (Ipp8u *)SAMPLE_ALIGN8(quant_table1);
quant_table2 = malloc((JPEG_BLOCK_SIZE 4)* 2);
table2 = (Ipp8u *)SAMPLE_ALIGN8(quant_table2);
if(1 == quality_ind) {
for(i = 0; i < 64; i ) {
table1[i] = h_lum_quant_table[i];
table2[i] = h_chrom_quant_table[i];
}
} else {
for(i = 0; i < 64; i ) {
table1[i] = l_lum_quant_table[i];
table2[i] = l_chrom_quant_table[i];
}
}
ippiDCTQuantFwdTableInit_JPEG_8u16u(table1,
(Ipp16u *)SAMPLE_ALIGN8(enc_state->lum_quant_table));
ippiDCTQuantFwdTableInit_JPEG_8u16u(table2,
(Ipp16u *)SAMPLE_ALIGN8(enc_state->chrom_quant_table));
free(quant_table1);
free(quant_table2);
/* Load and init the huffman table, use the default huffman table */
ippiEncodeHuffmanSpecInit_JPEG_8u(lum_dc_huffbits, lum_dc_huffvalues,
&(enc_state->lum_dc_huffmansize_table));
ippiEncodeHuffmanSpecInit_JPEG_8u(lum_ac_huffbits, lum_ac_huffvalues,
&(enc_state->lum_ac_huffmansize_table));
ippiEncodeHuffmanSpecInit_JPEG_8u(chrom_dc_huffbits, chrom_dc_huffvalues,
&(enc_state->chrom_dc_huffmansize_table));
ippiEncodeHuffmanSpecInit_JPEG_8u(chrom_ac_huffbits, chrom_ac_huffvalues,
&(enc_state->chrom_ac_huffmansize_table));
/*
// Allocate the work buffer, this work buffer will be used as temporary
// buffer for DCT-quantization output and huffman encoding input
*/
enc_state->work_buf = NULL;
enc_state->work_buf = (short *)malloc((JPEG_MCU_SIZE 7) * 2);
/* Reset the DC prediction value */
for(i = 0; i < 3; i ) {
enc_state->dc_pred[i] = 0;
}
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: encode_jpeg
// Description:
// This function encodes the input YUV data into JPEG format bitstream.
// Input Arguments:
// src_picture - Pointer to the source picture in YUV format.
// enc_state - Pointer to the encoder state structure.
// Output Arguments:
// dst_stream - Pointer to the output JPEG bitstream.
// Returns
// SAMPLE_STATUS_NOERR - No error
******************************************************************************/
sample_status encode_jpeg(sample_picture *src_picture,
sample_bitstream *dst_stream,
jpeg_enc_state *enc_state)
{
int i, j;
int x_num;
int y_num;
short *tmp_buf;
short *in_buf;
int used_bits_len = 0;
int used_byte_len;
/* Write the head of JPEG */
write_head_information(dst_stream, enc_state);
/* Put the SOS and the table information into the bitstream */
write_sos_information(dst_stream);
/* Compute the MCU number in x and y direction */
x_num = enc_state->width >> 4;
y_num = enc_state->height >> 4;
tmp_buf = (Ipp16s *)SAMPLE_ALIGN8(enc_state->work_buf);
in_buf = src_picture->pic_plane[0];
for(i = 0; i < y_num; i ) {
for(j = 0; j < x_num; j ) {
/* First, the DCT transformation will be called followed by
the quantization */
/*
// The DCT and quantization are performed on each Y block and Cb,
// Cr block. For this program only support Y:Cb:Cr = 4:1:1 mode.
// There will be 6 DCT-quantization operations for each MCU
*/
/* DCT-quantization for 4 Y blocks */
ippiDCTQuantFwd_JPEG_16s(in_buf, tmp_buf,
(Ipp16u *)SAMPLE_ALIGN8(enc_state->lum_quant_table));
ippiDCTQuantFwd_JPEG_16s(&in_buf[64], &tmp_buf[64],
(Ipp16u *)SAMPLE_ALIGN8(enc_state->lum_quant_table));
ippiDCTQuantFwd_JPEG_16s(&in_buf[128], &tmp_buf[128],
(Ipp16u *)SAMPLE_ALIGN8(enc_state->lum_quant_table));
ippiDCTQuantFwd_JPEG_16s(&in_buf[192], &tmp_buf[192],
(Ipp16u *)SAMPLE_ALIGN8(enc_state->lum_quant_table));
/* DCT-quantization for Cb block */
ippiDCTQuantFwd_JPEG_16s(&in_buf[256], &tmp_buf[256],
(Ipp16u *)SAMPLE_ALIGN8(enc_state->chrom_quant_table));
/* DCT-quantization for Cr block */
ippiDCTQuantFwd_JPEG_16s(&in_buf[320], &tmp_buf[320],
(Ipp16u *)SAMPLE_ALIGN8(enc_state->chrom_quant_table));
in_buf = JPEG_MCU_SIZE;
/* Now huffman encode the quantized coefficient */
/* First encode the 4 luminance(Y) blocks */
ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1 (tmp_buf,
dst_stream->bs_cur_byte,
&used_bits_len,
&(enc_state->dc_pred[0]),
&(enc_state->lum_dc_huffmansize_table),
&(enc_state->lum_ac_huffmansize_table));
ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1 (&tmp_buf[64],
dst_stream->bs_cur_byte,
&used_bits_len,
&(enc_state->dc_pred[0]),
&(enc_state->lum_dc_huffmansize_table),
&(enc_state->lum_ac_huffmansize_table));
ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1 (&tmp_buf[128],
dst_stream->bs_cur_byte,
&used_bits_len,
&(enc_state->dc_pred[0]),
&(enc_state->lum_dc_huffmansize_table),
&(enc_state->lum_ac_huffmansize_table));
ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1 (&tmp_buf[192],
dst_stream->bs_cur_byte,
&used_bits_len,
&(enc_state->dc_pred[0]),
&(enc_state->lum_dc_huffmansize_table),
&(enc_state->lum_ac_huffmansize_table));
/* Huffman encode the chrominance(Cb) block */
ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1 (&tmp_buf[256],
dst_stream->bs_cur_byte,
&used_bits_len,
&(enc_state->dc_pred[1]),
&(enc_state->chrom_dc_huffmansize_table),
&(enc_state->chrom_ac_huffmansize_table));
/* Huffman encode the chrominance(Cr) block */
ippiEncodeHuffman8x8_Direct_JPEG_16s1u_C1 (&tmp_buf[320],
dst_stream->bs_cur_byte,
&used_bits_len,
&(enc_state->dc_pred[2]),
&(enc_state->chrom_dc_huffmansize_table),
&(enc_state->chrom_ac_huffmansize_table));
}
}
/* Put EOI mark to the end of stream */
used_byte_len = used_bits_len >> 3;
/*
// Check if the last byte is completely filled, if not, stuff it and move
// to the next byte for writing
*/
if(used_bits_len & 0x7) {
used_byte_len = 1;
}
dst_stream->bs_cur_byte = used_byte_len;
*dst_stream->bs_cur_byte = 0xff; /* Write the high part of EOI */
*dst_stream->bs_cur_byte = JPEG_MARKER_EOI;
return SAMPLE_STATUS_NOERR;
}
/******************************************************************************
// Name: encoder_free_jpeg
// Description:
// This function free the buffer malloced in the initialization function
// Input arguments:
// enc_state - Pointer to the JPEG encoder structure
// Returns:
// SAMPLE_STATUS_NOERR - No error
******************************************************************************/
sample_status encoder_free_jpeg(jpeg_enc_state *enc_state)
{
if(NULL != enc_state->in_buf) {
free(enc_state->in_buf);
}
enc_state->in_buf = NULL;
if(NULL != enc_state->out_buf) {
free(enc_state->out_buf);
}
enc_state->out_buf = NULL;
if(NULL != enc_state->work_buf) {
free(enc_state->work_buf);
}
enc_state->work_buf = NULL;
return SAMPLE_STATUS_NOERR;
}
/* EOF */
标签: 编码
相关软件
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明


网友评论
我要评论