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

📄 jpege_encode.c

📁 motion Jpeg 在SPI DSP平台优化好的代码
💻 C
字号:
////////////////////////////////////////////////////////////////////////////////////////////////////////                      jpege_encode.c (JPEG Encoder 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 "spi_common.h"#include "jpege_context.h"#include "jpege_tables.h"#include "write_bits.h"//////////////////////////////////////////////////////////////////////////////////          Constants////////////////////////////////////////////////////////////////////////////////#define MAX_COEF_BITS 10#ifdef OUTPUT_DEBUG_TO_FILE   FILE *debug_out;#endifvoid huffman_encode_one_block_ref(    BIT_BUFFER *p_bit_buffer,    short *p_block,    short last_dc_val,	DERIVED_HUFF_TBL *p_dc_tbl,    DERIVED_HUFF_TBL *p_ac_tbl,    int insert_zero_byte){    short dc_diff;    short temp;    int num_bits;    short run;    short level;    int k, index;    short zz_block[BLOCK_SIZE];    // Do the zigzag first. This will match kernel code better    for (k = 0; k < BLOCK_SIZE; k++)    {        zz_block[k] = p_block[zigzag[k]];    }    // Encode the DC coefficient difference per section F.1.2.1     dc_diff = temp = zz_block[0] - last_dc_val;    if (dc_diff < 0)    {        temp = -temp;		/* temp is abs value of input */        /* For a negative input, want dc_diff = bitwise complement of abs(input) */        /* This code assumes we are on a two's complement machine */        dc_diff--;    }      // Find the number of bits needed for the magnitude of the coefficient    num_bits = 0;    while (temp) {        num_bits++;        temp >>= 1;    }    // Check for out-of-range coefficient values.    // Since we're encoding a difference, the range limit is twice as much.    if (num_bits > MAX_COEF_BITS + 1)    {        spi_printf ("Magnitute of dct dc coefficient exceed 11 bits\n");        exit (1);    }      write_bits_ref (p_bit_buffer, p_dc_tbl->code_word[num_bits], p_dc_tbl->code_length[num_bits], insert_zero_byte);    // Emit that number of bits of the value, if positive,    // or the complement of its magnitude, if negative.    write_bits_ref (p_bit_buffer, (unsigned short) dc_diff, num_bits, insert_zero_byte);    // Encode the AC coefficients per section F.1.2.2      run = 0;			// r = run length of zeros    for (k = 1; k < BLOCK_SIZE; k++)    {        if ((temp = zz_block[k]) == 0)        {            run++;        }        else        {            // if run length > 15, must emit special run-length-16 codes (0xF0) */            while (run > 15)            {	            write_bits_ref (p_bit_buffer, p_ac_tbl->code_word[0xF0], p_ac_tbl->code_length[0xF0], insert_zero_byte);	            run -= 16;            }            level = temp;            if (level < 0)            {                temp = -temp;   // temp is abs value of input                // This code assumes we are on a two's complement machine                level--;            }                  // Find the number of bits needed for the magnitude of the coefficient            num_bits = 1;		// there must be at least one 1 bit            while (temp >>= 1)            {	            num_bits++;            }            // Check for out-of-range coefficient values            if (num_bits > MAX_COEF_BITS)            {	            spi_printf ("ac coefficient out of range\n");                exit (1);            }                  // Emit Huffman symbol for run length / number of bits            index = (run << 4) + num_bits;            write_bits_ref (p_bit_buffer, p_ac_tbl->code_word[index], p_ac_tbl->code_length[index], insert_zero_byte);            // Emit that number of bits of the value, if positive,            // or the complement of its magnitude, if negative.            write_bits_ref (p_bit_buffer, (unsigned short) level, num_bits, insert_zero_byte);                  run = 0;        }    }      // If the last coef(s) were zero, emit an end-of-block code */    if (run > 0)    {        write_bits_ref (p_bit_buffer, p_ac_tbl->code_word[0], p_ac_tbl->code_length[0], insert_zero_byte);    }}void encode_block (    char *p_in_data,    unsigned short *p_quant_divisor,    DERIVED_HUFF_TBL *p_dc_huff_tbl,    DERIVED_HUFF_TBL *p_ac_huff_tbl,    short *last_dc,    BIT_BUFFER *p_buffer    ){    short coefs[64];    // Forward dct and quantization    fdct_and_quantize_aan_ref (p_in_data, coefs, p_quant_divisor);    #ifdef OUTPUT_DEBUG_TO_FILE    {        int i;        fprintf (debug_out, "-------------------\n");        for (i = 0; i < 64; i++)        {            fprintf (debug_out, "%d: %x\n", i, coefs[i]);        }    }    #endif    huffman_encode_one_block_ref (p_buffer, coefs, *last_dc, p_dc_huff_tbl, p_ac_huff_tbl, false);    *last_dc = coefs[0];}void compose_block (char *p_dst_block, unsigned char *p_src_block, int src_stride){    int i, j;    unsigned char *p_src;        for (j = 0; j < BLOCK_HEIGHT; j++)    {        p_src = p_src_block + j * src_stride;        for (i = 0; i < BLOCK_WIDTH; i++)        {            *p_dst_block++ = *p_src - 128;            p_src++;        }    }}void encode_one_component_ref (JPEGE_CONTEXT *p_jenc, int component_index){    int i, j;    short dc;    unsigned char *p_input;    unsigned char *p_src;    JPEGE_COMPONENT_INFO *p_comp;    char block[BLOCK_SIZE];    BIT_BUFFER *p_bit_buffer;    p_input = p_jenc->p_input_buffer[component_index];    p_comp = &p_jenc->comp_info[component_index];    p_bit_buffer = p_comp->p_bit_buffers;    for (i = 0; i < p_comp->width_in_blocks * p_comp->height_in_blocks; i++)    {        reset_bit_buffer (p_bit_buffer++);    }    p_bit_buffer = p_comp->p_bit_buffers;    dc = 0;    #ifdef OUTPUT_DEBUG_TO_FILE        debug_out = fopen ("dbg_out.txt", "w");    #endif        for (j = 0; j < p_comp->height_in_blocks; j++)    {        for (i = 0; i < p_comp->width_in_blocks; i++)        {                       p_src  = p_input + j * p_comp->scaled_width * BLOCK_HEIGHT + i * BLOCK_WIDTH;                            compose_block (                block,                 p_src,                p_comp->scaled_width                );            #ifdef OUTPUT_DEBUG_TO_FILE                 fprintf (debug_out, "--------- block # %d ----------\n", j * p_comp->width_in_blocks + i);            #endif            encode_block (                block,                p_jenc->quant_tbl[p_comp->quant_tbl_num].aan_divisor,                &p_comp->d_dc_huff_tbl,                &p_comp->d_ac_huff_tbl,                &dc,                p_bit_buffer                );            p_bit_buffer++;        }		dc = 0;    }    #ifdef OUTPUT_DEBUG_TO_FILE        fclose(debug_out);    #endif}void pack_one_bit_buffer (BIT_BUFFER *p_output_buffer, BIT_BUFFER *p_bit_buffer){    int n;		for (n = 0; n < (int)p_bit_buffer->byte_pos; n++)    {        write_bits_ref (p_output_buffer, p_bit_buffer->p_buffer[n], 8, true);    }	write_bits_ref (p_output_buffer, p_bit_buffer->cur_byte >> (8 - p_bit_buffer->bit_pos), p_bit_buffer->bit_pos, true);}void pack_bits (JPEGE_CONTEXT *p_jenc){    int i, k, blocks_per_row, marker, marker_count;	BIT_BUFFER *p_dest_buffer;    JPEGE_COMPONENT_INFO *p_cur_comp;    p_dest_buffer = &p_jenc->output_buffer;#if defined(DEBUG1)	spi_printf("\n Before pack_bits. \n");#endif    for (k = 0; k < p_jenc->num_components; k++)    {        write_single_component_scan_header (p_jenc, k);        p_cur_comp = &p_jenc->comp_info[k];    	blocks_per_row = p_cur_comp->scaled_width / BLOCK_WIDTH;		marker_count = 0;		for (i = 0; i < p_cur_comp->num_blocks; i++)        {            if ((i != 0) && ((i % blocks_per_row) == 0))			{				write_fill_bits_at_reset(p_jenc);				word_align_byte_pos(p_dest_buffer);							// Add the marker for next interval				marker = 0xFFD0 | marker_count; 				marker_count = (marker_count + 1) & 0x7;				write_bytes (p_dest_buffer, 0xFFFF, 2);	 // This is inserted to make it one word & thus keep the byte_pos word aligned				write_bytes (p_dest_buffer, marker, 2);							}			pack_one_bit_buffer (p_dest_buffer, &p_cur_comp->p_bit_buffers[i]);			        }		write_fill_bits_at_reset (p_jenc);		word_align_byte_pos(p_dest_buffer);#if defined(DEBUG1)		spi_printf("\n After one component :  %d    \n", k);#endif	}#if defined(DEBUG1)	spi_printf("\n After pack_bits \n");#endif    #ifdef OUTPUT_DEBUG_TO_FILE    {        int n;        BIT_BUFFER *p_bit_buffer;        #ifdef USE_JPEG_KERNELS        debug_out = fopen ("bit_buf_out_k.txt", "w");        #else        debug_out = fopen ("bit_buf_out_r.txt", "w");        #endif                for (k = 0; k < p_jenc->num_components; k++)        {            fprintf (debug_out, "xxxxx Componet # %d xxxxxxxx\n", k);            p_cur_comp = &p_jenc->comp_info[k];            for (i = 0; i < (int)p_cur_comp->num_blocks; i++)            {                                fprintf (debug_out, "--------- block # %d --------\n", i);                p_bit_buffer = &p_cur_comp->p_bit_buffers[i];                                for (n = 0; n < (int)p_bit_buffer->byte_pos; n++)                {                    fprintf (debug_out, "%d: %x\n", n, p_bit_buffer->p_buffer[n]);                }					fprintf (debug_out, "%d: %x\n", n, p_bit_buffer->cur_byte);            }        }		        fclose (debug_out);    }    #endif}void encode_frame(JPEGE_CONTEXT *p_jenc){    int  k;#if (defined(PROFILE_KERNELS) && (defined(SPI_TARGET_DEVICE)))    spi_safe_mode(2);#endif#if (defined(PROFILE_COMPONENTS) && (defined(SPI_TARGET_DEVICE)))	SPI_PERF_T      enc_component_timer  ;	SPI_PERF_T      pack_rows_timer  ;#endif    // This is a two stage process.    // 1. Encode each component    // 2. Pack bits    for (k = 0; k < p_jenc->num_components; k++)    {#if (defined(PROFILE_COMPONENTS) && (defined(SPI_TARGET_DEVICE)))        spi_perf_init   (&enc_component_timer   , "enc_component_timer") ;	    spi_perf_start   (&enc_component_timer) ;#endif        #ifndef USE_JPEG_KERNELS            encode_one_component_ref (p_jenc, k);        #else            encode_one_component (p_jenc, k);        #endif#if (defined(PROFILE_COMPONENTS) && (defined(SPI_TARGET_DEVICE)))	spi_perf_stop   (&enc_component_timer) ;    spi_perf_print  (&enc_component_timer, 1) ;#endif#if (defined(PROFILE_KERNELS) && (defined(SPI_TARGET_DEVICE)))    spi_runtime_kernel_dpu_perf_print(1);#endif    }#if (defined(PROFILE_COMPONENTS) && (defined(SPI_TARGET_DEVICE)))    spi_perf_init   (&pack_rows_timer       , "pack_rows_timer") ;    spi_perf_start   (&pack_rows_timer) ;#endif#if defined (REF)    pack_bits (p_jenc);#else	pack_bits_sc(p_jenc);#endif#if (defined(PROFILE_COMPONENTS) && (defined(SPI_TARGET_DEVICE)))	spi_perf_stop   (&pack_rows_timer) ;    spi_perf_print  (&pack_rows_timer, 1) ;#endif}void jpege_encode (JPEGE_CONTEXT *p_jenc){    write_soi (p_jenc);             // FFD8 - SOI    write_JFIF_header(p_jenc);      // APP0    write_quant_tables(p_jenc);     // DQT    write_frame_header(p_jenc);     // SOF    write_huffman_tables(p_jenc);   // DHT    encode_frame (p_jenc);#if defined(DEBUG1)	spi_printf("\n After encode_frame. \n");#endif    write_fill_bits (p_jenc);#if defined(DEBUG1)	spi_printf("\n After final fill bits. \n");#endif    write_eoi (p_jenc);#if defined(DEBUG1)	spi_printf("\n After writing end of image. \n");#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -