📄 write_bits.c
字号:
//////////////////////////////////////////////////////////////////////////////////////////////////////// write_bits.c (JPEG Encoder Bitstream 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 "spi_common.h"#include "jpege_context.h"#include "string.h"#include "jpege_tables.h"void reset_bit_buffer (BIT_BUFFER *p_bit_buffer){ SPI_ASSERT (p_bit_buffer != NULL); p_bit_buffer->bit_pos = 0; p_bit_buffer->byte_pos = 0; p_bit_buffer->cur_byte = 0;}void write_bytes (BIT_BUFFER *p_bit_buffer, unsigned int value, int num_bytes){ int i, shift; SPI_ASSERT (p_bit_buffer != NULL); SPI_ASSERT (p_bit_buffer->bit_pos == 0); SPI_ASSERT (p_bit_buffer->cur_byte == 0); SPI_ASSERT (num_bytes <= 4); shift = (num_bytes - 1) * 8; for (i = 0; i < num_bytes; i++) { *(p_bit_buffer->p_buffer + p_bit_buffer->byte_pos) = (unsigned char) (value >> shift) & 0xff; p_bit_buffer->byte_pos++; shift -= 8; } p_bit_buffer->bit_pos = 0; p_bit_buffer->cur_byte = 0;}void write_soi (JPEGE_CONTEXT *p_jenc) // FFD8 - SOI{ write_bytes (&p_jenc->output_buffer, 0xFFD8, 2);}void write_eoi (JPEGE_CONTEXT *p_jenc){ write_bytes (&p_jenc->output_buffer, 0xFFD9, 2);}void write_JFIF_header (JPEGE_CONTEXT *p_jenc) // APP0info()//Nothing to overwrite for APP0info{ BIT_BUFFER *p_bit_buffer; p_bit_buffer = &p_jenc->output_buffer; write_bytes (p_bit_buffer, 0xFFE0, 2); // marker write_bytes (p_bit_buffer, 16, 2); // length. default 16 with no thumbnails write_bytes (p_bit_buffer, 'J', 1); write_bytes (p_bit_buffer, 'F', 1); write_bytes (p_bit_buffer, 'I', 1); write_bytes (p_bit_buffer, 'F', 1); write_bytes (p_bit_buffer, 0, 1); write_bytes (p_bit_buffer, p_jenc->jfif_info.major_version, 1); write_bytes (p_bit_buffer, p_jenc->jfif_info.minor_version, 1); write_bytes (p_bit_buffer, p_jenc->jfif_info.density_unit, 1); write_bytes (p_bit_buffer, p_jenc->jfif_info.x_density, 2); write_bytes (p_bit_buffer, p_jenc->jfif_info.y_density, 2); write_bytes (p_bit_buffer, 0, 1); // no thumbnails write_bytes (p_bit_buffer, 0, 1);}void write_quant_table (JPEGE_CONTEXT *p_jenc, int table_index){ int i; BIT_BUFFER *p_bit_buffer; unsigned char *p_table; if (p_jenc->quant_tbl[table_index].table_sent == true) { return; } p_jenc->quant_tbl[table_index].table_sent = true; p_bit_buffer = &p_jenc->output_buffer; write_bytes (p_bit_buffer, 0xFFDB, 2); // marker write_bytes (p_bit_buffer, BLOCK_SIZE + 2 + 1, 2); // length write_bytes (p_bit_buffer, table_index, 1); p_table = &p_jenc->quant_tbl[table_index].scaled_table[0]; for (i = 0; i < BLOCK_SIZE; i++) { write_bytes (p_bit_buffer, p_table[zigzag[i]] & 0xff, 1); // note, quatable is in zigzag order }}void write_quant_tables (JPEGE_CONTEXT *p_jenc){ int i; for (i = 0; i < p_jenc->num_components; i++) { write_quant_table (p_jenc, p_jenc->comp_info[i].quant_tbl_num); } /* unsigned table_index_flags; table_index_flags = p_jenc->active_qtables; for (i = 0; i < MAX_NUM_QUANT_TBLS; i++) { if (table_index_flags & 1) { write_quant_table (p_jenc, i); table_index_flags >>= 1; } }*/}void write_frame_header(JPEGE_CONTEXT *p_jenc) // SOF{ int i; BIT_BUFFER *p_bit_buffer; JPEGE_COMPONENT_INFO *p_comp; p_bit_buffer = &p_jenc->output_buffer; write_bytes (p_bit_buffer, 0xFFC0, 2); // SOF marker. baseline. (0xFFC2 for progressive, 0xFFC1 for non-basline huffman) write_bytes (p_bit_buffer, 3 * p_jenc->num_components + 2 + 5 + 1, 2); //length write_bytes (p_bit_buffer, p_jenc->data_precision, 1); write_bytes (p_bit_buffer, p_jenc->image_height, 2); write_bytes (p_bit_buffer, p_jenc->image_width, 2); write_bytes (p_bit_buffer, p_jenc->num_components, 1); for (i = 0; i < p_jenc->num_components; i++) { p_comp = &p_jenc->comp_info[i]; write_bytes (p_bit_buffer, p_comp->component_id, 1); write_bytes (p_bit_buffer, (p_comp->h_samp_factor << 4) + p_comp->v_samp_factor, 1); write_bytes (p_bit_buffer, p_comp->quant_tbl_num, 1); }}void write_huffman_table (JPEGE_CONTEXT *p_jenc, int table_index, int is_ac, int table_id) // DHT{ JPEGE_HUFF_TBL *p_huff_tbl; BIT_BUFFER *p_bit_buffer; int length, i; p_bit_buffer = &p_jenc->output_buffer; if (is_ac) { if (p_jenc->ac_huff_tbl[table_index].table_sent == true) { return; } p_huff_tbl = &p_jenc->ac_huff_tbl[table_index]; table_id += 0x10; // output index has AC bit set p_jenc->ac_huff_tbl[table_index].table_sent = true; } else { if (p_jenc->dc_huff_tbl[table_index].table_sent == true) { return; } p_huff_tbl = &p_jenc->dc_huff_tbl[table_index]; p_jenc->dc_huff_tbl[table_index].table_sent = true; } write_bytes (p_bit_buffer, 0xFFC4, 2); // DHT marker length = 0; for (i = 1; i <= 16; i++) { length += p_huff_tbl->bits[i]; } write_bytes (p_bit_buffer, length + 2 + 1 + 16, 2); // length write_bytes (p_bit_buffer, table_id, 1); for (i = 1; i <= 16; i++) { write_bytes (p_bit_buffer, p_huff_tbl->bits[i], 1); } for (i = 0; i < length; i++) { write_bytes (p_bit_buffer, (unsigned int) p_huff_tbl->huffval[i], 1); }}void write_huffman_tables (JPEGE_CONTEXT *p_jenc) // DHT{ int i; for (i = 0; i < p_jenc->num_components; i++) { write_huffman_table (p_jenc, p_jenc->comp_info[i].dc_huff_tbl_num, 0, i); write_huffman_table (p_jenc, p_jenc->comp_info[i].ac_huff_tbl_num, 1, i); } /* unsigned table_index_flags; table_index_flags = p_jenc->active_dc_huff_tbls; for (i = 0; i < MAX_NUM_DC_HUFF_TBLS; i++) { if (table_index_flags & 1) { write_huffman_table (p_jenc, i, 0, i); table_index_flags >>= 1; } } table_index_flags = p_jenc->active_ac_huff_tbls; for (i = 0; i < MAX_NUM_AC_HUFF_TBLS; i++) { if (table_index_flags & 1) { write_huffman_table (p_jenc, i, 1, i); table_index_flags >>= 1; } }*/}void write_scan_header (JPEGE_CONTEXT *p_jenc){ int i; BIT_BUFFER *p_bit_buffer; JPEGE_COMPONENT_INFO *p_comp; p_bit_buffer = &p_jenc->output_buffer; write_bytes (p_bit_buffer, 0xFFDA, 2); // SOS marker write_bytes (p_bit_buffer, p_jenc->comps_in_scan * 2 + 2 + 1 + 3, 2); // length write_bytes (p_bit_buffer, p_jenc->comps_in_scan, 1); for (i = 0; i < p_jenc->comps_in_scan; i++) { p_comp = &p_jenc->comp_info[i]; //TODO write_bytes (p_bit_buffer, p_comp->component_id, 1); write_bytes (p_bit_buffer, (p_comp->dc_huff_tbl_num << 4) + p_comp->ac_huff_tbl_num, 1); } // Write Ss, Se, Ah, Al for baseline write_bytes (p_bit_buffer, 0, 1); // Ss write_bytes (p_bit_buffer, 63, 1); // Se write_bytes (p_bit_buffer, 0, 1); // (Ah << 4) + Al}void word_align_byte_pos(BIT_BUFFER *p_bit_buffer){ int i, stuff_bytes; SPI_ASSERT (p_bit_buffer != NULL); SPI_ASSERT (p_bit_buffer->bit_pos == 0); SPI_ASSERT (p_bit_buffer->cur_byte == 0); stuff_bytes = (4 - (p_bit_buffer->byte_pos & 0x3)) & 0x3; for (i = 0; i < stuff_bytes; i++) { write_bytes (p_bit_buffer, 0xFF, 1); }}void write_single_component_scan_header (JPEGE_CONTEXT *p_jenc, int component_index){ BIT_BUFFER *p_bit_buffer; JPEGE_COMPONENT_INFO *p_comp; p_bit_buffer = &p_jenc->output_buffer; p_comp = &p_jenc->comp_info[component_index]; //TODO // align the position of the byte to be written in the bitstream to word boundary by stuffing "FF"'s word_align_byte_pos(p_bit_buffer); // IMPORTANT NOTE : We kno that we right 16 bytes i.e. 4 words in the header below // So the data following this is going to start at word boundary // In case this header is changed, the place where "word_align_byte_pos" is called // needs to be changed // Adding marker segment which specifies "restart interval definition " per scan write_bytes (p_bit_buffer, 0xFFDD, 2); // DRI marker write_bytes (p_bit_buffer, 0x0004, 2); // Lr marker //write_bytes (p_bit_buffer, (0), 2); // Ri marker write_bytes (p_bit_buffer, (p_comp->scaled_width / BLOCK_WIDTH), 2); // Ri marker : MCU length / reset interval = one row of image write_bytes (p_bit_buffer, 0xFFDA, 2); // SOS marker write_bytes (p_bit_buffer, 1 * 2 + 2 + 1 + 3, 2); // length // number of components in scan = 1 write_bytes (p_bit_buffer, 1, 1); write_bytes (p_bit_buffer, p_comp->component_id, 1); write_bytes (p_bit_buffer, (p_comp->dc_huff_tbl_num << 4) + p_comp->ac_huff_tbl_num, 1); // Write Ss, Se, Ah, Al for baseline write_bytes (p_bit_buffer, 0, 1); // Ss write_bytes (p_bit_buffer, 63, 1); // Se write_bytes (p_bit_buffer, 0, 1); // (Ah << 4) + Al}// non byte aligned writesvoid write_bits_ref(BIT_BUFFER *p_bit_buffer, unsigned short value, unsigned char length, int insert_zero_byte){ unsigned char bit_pos, next_bit_pos; unsigned char cur_byte; unsigned char append_value; signed char len; SPI_ASSERT (length <= 16); len = (signed char) length; cur_byte = p_bit_buffer->cur_byte; // new bit position after the write next_bit_pos = (p_bit_buffer->bit_pos + (unsigned char)(length & 0x7)) & 0x7; bit_pos = p_bit_buffer->bit_pos; // get ready to write a byte. p_bit_buffer->bit_pos = 0; p_bit_buffer->cur_byte = 0; // shift value to be aligned at the top value = value << (16 - len); while (len > 0) { // take top 8 bits and shift to align with current byte append_value = (unsigned char)((value >> 8) & 0xff) >> bit_pos; cur_byte |= append_value; // shift remaining to the top value = value << (8 - bit_pos); len = len + bit_pos - 8; if (len >= 0) { write_bytes (p_bit_buffer, cur_byte, 1); if ((cur_byte == 0xff) && (insert_zero_byte == true)) {#if defined(DEBUG1) spi_printf("\n %d \t %x", p_bit_buffer->byte_pos-1, *(p_bit_buffer->p_buffer + p_bit_buffer->byte_pos - 1) ); #endif // insert zero if "ff" is writting in the bitstream write_bytes (p_bit_buffer, 0, 1); } cur_byte = 0; bit_pos = 0; } } p_bit_buffer->cur_byte = cur_byte; p_bit_buffer->bit_pos = next_bit_pos;}void write_fill_bits (JPEGE_CONTEXT *p_jenc){ BIT_BUFFER *p_bit_buffer; unsigned char num_fill_bits; p_bit_buffer = &p_jenc->output_buffer; num_fill_bits = 8 - p_bit_buffer->bit_pos; write_bits_ref (p_bit_buffer, 0xffff, num_fill_bits, false);}void write_fill_bits_at_reset (JPEGE_CONTEXT *p_jenc){ BIT_BUFFER *p_bit_buffer; unsigned char num_fill_bits; p_bit_buffer = &p_jenc->output_buffer; num_fill_bits = (8 - p_bit_buffer->bit_pos) & 0x7; write_bits_ref (p_bit_buffer, 0xffff, num_fill_bits, true);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -