⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 write_bits.c

📁 motion Jpeg 在SPI DSP平台优化好的代码
💻 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 + -