📄 jpege_context.c
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////////// jpege_context.c (JPEG Encoder context functions 'C' File)//// Notice: COPYRIGHT (C) STREAM PROCESSORS, INC. 2005-2007// THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE SPI// END-USER LICENSE AGREEMENT (EULA). THE PROGRAM MAY ONLY// BE USED IN A MANNER EXPLICITLY SPECIFIED IN THE EULA,// WHICH INCLUDES LIMITATIONS ON COPYING, MODIFYING,// REDISTRIBUTION AND WARANTIES. UNAUTHORIZED USE OF THIS// PROGRAM IS STRICTLY PROHIBITED. YOU MAY OBTAIN A COPY OF// THE EULA FROM WWW.STREAMPROCESSORS.COM. // ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #includes ////////////////////////////////////////////////////////////////////////////////#include <stdio.h>#include <string.h>#include "spi_common.h"#include "jpege_context.h"#include "jpege_tables.h"#include "write_bits.h"////////////////////////////////////////////////////////////////////////////////// Constants////////////////////////////////////////////////////////////////////////////////#define MAX_SCALE 100#define HALF_SCALE 50extern void derive_huffman_table( JPEGE_HUFF_TBL *p_huff_tbl, DERIVED_HUFF_TBL *p_d_huff_tbl);extern void set_huffman_table (JPEGE_HUFF_TBL *p_huff_table, unsigned char *p_bits, unsigned char *p_values);JPEGE_STATUS jpege_set_input_image ( JPEGE_CONTEXT *p_jenc, unsigned char *p_buf[MAX_NUM_COMPONENTS]){ int i; for (i = 0; i < p_jenc->num_components; i++) { // check that the input buffer is valid SPI_ASSERT (p_buf[i] != NULL); p_jenc->p_input_buffer[i] = p_buf[i]; } for (i = p_jenc->num_components; i < MAX_NUM_COMPONENTS; i++) { p_jenc->p_input_buffer[i] = NULL; } return STATUS_SUCCESS;}void jpege_set_output_buffer ( JPEGE_CONTEXT *p_jenc, unsigned char *p_buffer, int buffer_size){ p_jenc->output_buffer.bit_pos = 0; p_jenc->output_buffer.byte_pos = 0; p_jenc->output_buffer.cur_byte = 0; p_jenc->output_buffer.buffer_size = buffer_size; p_jenc->output_buffer.p_buffer = p_buffer;}JPEGE_STATUS jpege_set_component( JPEGE_CONTEXT *p_jenc, int component_index, int component_id, int h_samp_factor, int v_samp_factor, int qtable_index, int dc_huffman_table_index, int ac_huffman_table_index ){ int i; int num_blocks, padded_num_blocks; int xscale, yscale; int s_width, s_height; JPEGE_STATUS status = STATUS_SUCCESS; JPEGE_COMPONENT_INFO *p_comp_info; p_comp_info = &p_jenc->comp_info[component_index]; p_comp_info->component_index = component_index; p_comp_info->component_id = component_id;/* input format related */ p_comp_info->h_samp_factor = h_samp_factor; p_comp_info->v_samp_factor = v_samp_factor;/* input format and size related */ xscale = p_jenc->max_h_sample_factor / h_samp_factor; yscale = p_jenc->max_v_sample_factor / v_samp_factor; s_width = (p_jenc->encode_width + xscale - 1) / xscale; s_height = (p_jenc->encode_height + yscale - 1) / yscale; p_comp_info->scaled_width = (s_width + BLOCK_WIDTH - 1) & ~(BLOCK_WIDTH - 1); p_comp_info->scaled_height = (s_height + BLOCK_HEIGHT - 1) & ~(BLOCK_HEIGHT - 1); p_comp_info->actual_width = (s_width); p_comp_info->actual_height = (s_height); p_comp_info->width_in_blocks = p_comp_info->scaled_width / BLOCK_WIDTH; p_comp_info->height_in_blocks = p_comp_info->scaled_height / BLOCK_WIDTH; num_blocks = p_comp_info->width_in_blocks * p_comp_info->height_in_blocks; p_comp_info->num_blocks = num_blocks; // For efficient parallel operation, pad the memory buffers to a multiple of SPI_LANES. padded_num_blocks = ((p_comp_info->height_in_blocks + SPI_LANES - 1) & ~(SPI_LANES - 1)) * p_comp_info->width_in_blocks; p_comp_info->padded_num_blocks = padded_num_blocks; if ((p_comp_info->p_bit_buffers = (BIT_BUFFER *) spi_malloc (padded_num_blocks * sizeof (BIT_BUFFER))) == NULL) { spi_printf ("\n Malloc for p_bit_buffers for %d component failed.\n",component_index); return STATUS_FAIL; } if ((p_comp_info->p_mem_buffer = (unsigned char *) spi_malloc (padded_num_blocks * BLOCK_BIT_BUFFER_SIZE)) == NULL) { spi_printf ("\n Malloc for p_mem_buffer for %d component failed.\n",component_index); return STATUS_FAIL; } for (i = 0; i < num_blocks; i++) { p_comp_info->p_bit_buffers[i].buffer_size = BLOCK_BIT_BUFFER_SIZE; p_comp_info->p_bit_buffers[i].p_buffer = p_comp_info->p_mem_buffer + i * BLOCK_BIT_BUFFER_SIZE; reset_bit_buffer (&p_comp_info->p_bit_buffers[i]); }/* Table related */ p_comp_info->quant_tbl_num = qtable_index; p_comp_info->ac_huff_tbl_num = ac_huffman_table_index; p_comp_info->dc_huff_tbl_num = dc_huffman_table_index; if ((p_comp_info->d_dc_huff_tbl.code_length = (unsigned char *) spi_malloc (DERIVED_DC_TABLE_LENGTH * sizeof (unsigned short))) == NULL) { spi_printf ("\n Malloc for d_dc_huff_tbl.code_length for %d component failed.\n",component_index); return STATUS_FAIL; } if ((p_comp_info->d_dc_huff_tbl.code_word = (unsigned short *) spi_malloc (DERIVED_DC_TABLE_LENGTH * sizeof (unsigned short))) == NULL) { spi_printf ("\n Malloc for d_dc_huff_tbl.code_word for %d component failed.\n",component_index); return STATUS_FAIL; } if ((p_comp_info->d_ac_huff_tbl.code_length = (unsigned char *) spi_malloc (DERIVED_AC_TABLE_LENGTH * sizeof (unsigned short))) == NULL) { spi_printf ("\n Malloc for d_ac_huff_tbl.code_length for %d component failed.\n",component_index); return STATUS_FAIL; } if ((p_comp_info->d_ac_huff_tbl.code_word = (unsigned short *) spi_malloc (DERIVED_AC_TABLE_LENGTH * sizeof (unsigned short))) == NULL) { spi_printf ("\n Malloc for d_ac_huff_tbl.code_word for %d component failed.\n",component_index); return STATUS_FAIL; } derive_huffman_table (&p_jenc->dc_huff_tbl[dc_huffman_table_index], &p_comp_info->d_dc_huff_tbl); derive_huffman_table (&p_jenc->ac_huff_tbl[ac_huffman_table_index], &p_comp_info->d_ac_huff_tbl); return status;}// Code is modified from IJGvoid compute_divisor_aan (unsigned char *p_quant_table, unsigned short *p_divisors){ // For AA&N IDCT method, divisors are equal to quantization // coefficients scaled by scalefactor[row]*scalefactor[col], where // scalefactor[0] = 1 // scalefactor[k] = cos(k*PI/16) * sqrt(2) for k=1..7 static const short aan_scales[BLOCK_SIZE] = { /* precomputed values scaled up by 14 bits */ 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, 22725, 31521, 29692, 26722, 22725, 17855, 12299, 6270, 21407, 29692, 27969, 25172, 21407, 16819, 11585, 5906, 19266, 26722, 25172, 22654, 19266, 15137, 10426, 5315, 16384, 22725, 21407, 19266, 16384, 12873, 8867, 4520, 12873, 17855, 16819, 15137, 12873, 10114, 6967, 3552, 8867, 12299, 11585, 10426, 8867, 6967, 4799, 2446, 4520, 6270, 5906, 5315, 4520, 3552, 2446, 1247 }; int i; int frac_const; // Instead of using a divide, we use ((1 << DIV_CONST_BITS) / divisor), // where divisor = p_quant_table * aan_scales >> (AAN_CONST_BITS - 3), 3 gives further scale factor of 8 // Note, shifting up by up to 15 can keep the range within 16 bits. If DIV_CONST_BITS > 15 then 32 bit precision is required frac_const = 1 << (DIV_CONST_BITS + AAN_QCONST_BITS - 3); for (i = 0; i < BLOCK_SIZE; i++) { if (p_quant_table[i] == 0) // this should not happen { spi_printf ("quant table has zero element\n"); exit (1); } p_divisors[i] = (unsigned short) (frac_const / (p_quant_table[i] * aan_scales[i])); }}void scale_quant_table( JPEGE_QUANT_TBL *p_quant_table, int scale_factor){ int i; unsigned short new_quant; unsigned char *p_basic_table; unsigned char *p_scaled_table; #ifdef USE_JPEG_KERNELS short swap; int j, i0, i1; #endif SPI_ASSERT (p_quant_table != NULL); p_basic_table = p_quant_table->basic_table; p_scaled_table = p_quant_table->scaled_table; for (i = 0; i < BLOCK_SIZE; i++) { new_quant = (unsigned short)((*p_basic_table++ * scale_factor + 50) / 100); if (new_quant <= 0) new_quant = 1; if (new_quant > 255) new_quant = 255; *p_scaled_table++ = (unsigned char)new_quant; } compute_divisor_aan (p_quant_table->scaled_table, p_quant_table->aan_divisor); #ifdef USE_JPEG_KERNELS // transpose quantize table because the coefficients are transposed in the kernels for (j = 0; j < BLOCK_HEIGHT; j++) { for (i = j + 1; i < BLOCK_WIDTH; i++) { i0 = j * BLOCK_WIDTH + i; i1 = i * BLOCK_WIDTH + j; swap = p_quant_table->aan_divisor[i0]; p_quant_table->aan_divisor[i0] = p_quant_table->aan_divisor[i1]; p_quant_table->aan_divisor[i1] = swap; } } #endif p_quant_table->table_sent = false;}//////////////////////////////////////////////////////////////////void jpege_set_quality ( JPEGE_CONTEXT *p_jenc, int quality)//// Description: This is the same quality to scale_factor translation as the IJG code.//////////////////////////////////////////////////////////////////{ int i; // scale quality first if (quality <= 0) quality = 1; if (quality > 100) quality = 100; if (quality < 50) { p_jenc->quant_scale_factor = 5000 / quality; } else { p_jenc->quant_scale_factor = 200 - quality * 2; } if (p_jenc->quant_scale_factor == 0) { p_jenc->quant_scale_factor = 1; } for (i = 0; i < p_jenc->num_components; i++) { scale_quant_table (&p_jenc->quant_tbl[p_jenc->comp_info[i].quant_tbl_num], p_jenc->quant_scale_factor); }}void set_quant_table (JPEGE_QUANT_TBL *p_quant_table, unsigned char *p_basic_table){ int i; unsigned char *p_dst_tbl; SPI_ASSERT (p_quant_table != NULL); p_dst_tbl = p_quant_table->basic_table; for (i = 0; i < BLOCK_SIZE; i++) { *p_dst_tbl++ = *p_basic_table++; }}void jpege_add_quant_table( JPEGE_CONTEXT *p_jenc, int table_index, unsigned char *p_basic_table){ SPI_ASSERT (p_jenc != NULL); SPI_ASSERT (p_basic_table != NULL); SPI_ASSERT (table_index < MAX_NUM_QUANT_TBLS); set_quant_table (&p_jenc->quant_tbl[table_index], p_basic_table); scale_quant_table (&p_jenc->quant_tbl[table_index], p_jenc->quant_scale_factor);}void jpege_add_huff_table ( JPEGE_CONTEXT *p_jenc, int table_type, int table_index, unsigned char *p_code_length, unsigned char *p_values){ int i; SPI_ASSERT (p_jenc != NULL); SPI_ASSERT (p_code_length != NULL); SPI_ASSERT (p_values != NULL); SPI_ASSERT (table_type == 0 || table_type == 1); SPI_ASSERT (table_index < MAX_NUM_DC_HUFF_TBLS); switch (table_type) { case 0: // dc table set_huffman_table (&p_jenc->dc_huff_tbl[table_index], p_code_length, p_values); for (i = 0; i < p_jenc->num_components; i++) { if (p_jenc->comp_info[i].dc_huff_tbl_num == table_index) { derive_huffman_table (&p_jenc->dc_huff_tbl[table_index], &p_jenc->comp_info[i].d_dc_huff_tbl); } } break; case 1: // ac table set_huffman_table (&p_jenc->ac_huff_tbl[table_index], p_code_length, p_values); for (i = 0; i < p_jenc->num_components; i++) { if (p_jenc->comp_info[i].dc_huff_tbl_num == table_index) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -