使用libjpeg进行编码之二:对I420YUV实现编码

    xiaoxiao2021-03-29  33

     #include <stdio.h> #include <stdlib.h> #include <iostream> #include <sys/stat.h> #include <string> #include <string.h> using namespace std; extern "C" { #include <jpeglib.h> #include <setjmp.h> #include <jerror.h> } #define WIDTH 320 #define HEIGHT 240 #define QUALITY 80 #define BUFFER_SZIE (WIDTH*HEIGHT*3/2) /* The following declarations and 5 functions are jpeg related * functions used by put_jpeg_grey_memory and put_jpeg_yuv420p_memory */ typedef struct { struct jpeg_destination_mgr pub; JOCTET *buf; size_t bufsize; size_t jpegsize; } mem_destination_mgr; typedef mem_destination_mgr *mem_dest_ptr; METHODDEF(void) init_destination(j_compress_ptr cinfo) { mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; dest->pub.next_output_byte = dest->buf; dest->pub.free_in_buffer = dest->bufsize; dest->jpegsize = 0; } METHODDEF(boolean) empty_output_buffer(j_compress_ptr cinfo) { mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; dest->pub.next_output_byte = dest->buf; dest->pub.free_in_buffer = dest->bufsize; return FALSE; } METHODDEF(void) term_destination(j_compress_ptr cinfo) { mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; dest->jpegsize = dest->bufsize - dest->pub.free_in_buffer; } static GLOBAL(void) jpeg_mem_dest(j_compress_ptr cinfo, JOCTET* buf, size_t bufsize) { mem_dest_ptr dest; if (cinfo->dest == NULL) { cinfo->dest = (struct jpeg_destination_mgr *) (*cinfo->mem->alloc_small)((j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(mem_destination_mgr)); } dest = (mem_dest_ptr) cinfo->dest; dest->pub.init_destination = init_destination; dest->pub.empty_output_buffer = empty_output_buffer; dest->pub.term_destination = term_destination; dest->buf = buf; dest->bufsize = bufsize; dest->jpegsize = 0; } static GLOBAL(int) jpeg_mem_size(j_compress_ptr cinfo) { mem_dest_ptr dest = (mem_dest_ptr) cinfo->dest; return dest->jpegsize; } /* put_jpeg_yuv420p_memory converts an input image in the YUV420P format into a jpeg image and puts * it in a memory buffer. * Inputs: * - input_image is the image in YUV420P format. * - width and height are the dimensions of the image * Output: * - dest_image is a pointer to the jpeg image buffer * Returns buffer size of jpeg image */ static int put_jpeg_yuv420p_memory(unsigned char *dest_image, unsigned char *input_image, int width, int height) { int i, j, jpeg_image_size; JSAMPROW y[16],cb[16],cr[16]; // y[2][5] = color sample of row 2 and pixel column 5; (one plane) JSAMPARRAY data[3]; // t[0][2][5] = color sample 0 of row 2 and column 5 struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; data[0] = y; data[1] = cb; data[2] = cr; cinfo.err = jpeg_std_error(&jerr); // errors get written to stderr jpeg_create_compress(&cinfo); cinfo.image_width = width; cinfo.image_height = height; cinfo.input_components = 3; jpeg_set_defaults (&cinfo); jpeg_set_colorspace(&cinfo, JCS_YCbCr); cinfo.raw_data_in = TRUE; // supply downsampled data cinfo.do_fancy_downsampling = FALSE; // fix segfaulst with v7 cinfo.comp_info[0].h_samp_factor = 2; cinfo.comp_info[0].v_samp_factor = 2; cinfo.comp_info[1].h_samp_factor = 1; cinfo.comp_info[1].v_samp_factor = 1; cinfo.comp_info[2].h_samp_factor = 1; cinfo.comp_info[2].v_samp_factor = 1; jpeg_set_quality(&cinfo, QUALITY, TRUE); cinfo.dct_method = JDCT_FASTEST; jpeg_mem_dest(&cinfo, dest_image, BUFFER_SZIE); // data written to mem jpeg_start_compress (&cinfo, TRUE); for (j = 0; j < height; j += 16) { for (i = 0; i < 16; i++) { y[i] = input_image + width * (i + j); if (i%2 == 0) { cb[i/2] = input_image + width * height + width / 2 * ((i + j) / 2); cr[i/2] = input_image + width * height + width * height / 4 + width / 2 * ((i + j) / 2); } } jpeg_write_raw_data(&cinfo, data, 16); } jpeg_finish_compress(&cinfo); jpeg_image_size = jpeg_mem_size(&cinfo); jpeg_destroy_compress(&cinfo); return jpeg_image_size; } int main( int argc, char **argv ) { FILE *fyuv=NULL; FILE *fyuvjpg=NULL; unsigned char *pSrc =NULL ; unsigned char *pDst =NULL; int lSize = 0; std::string input_yuv_name=""; if (NULL!=argv[1]) { input_yuv_name = argv[1]; } else { std::cout<<"Input YUV is NULL!!"<<std::endl; return -1; } fyuv = fopen(input_yuv_name.c_str(),"r"); pSrc = (unsigned char *)malloc (BUFFER_SZIE); pDst = (unsigned char *)malloc (BUFFER_SZIE); memset(pSrc,BUFFER_SZIE, 0 ); memset(pDst,BUFFER_SZIE, 0 ); if( fread(pSrc, BUFFER_SZIE,1 ,fyuv) >1) { std::cerr<<"Error occur in stat function !!"<<std::endl; } lSize = put_jpeg_yuv420p_memory(pDst, pSrc , WIDTH ,HEIGHT); std::string output_yuv_name="Encoded.jpeg"; fyuvjpg =fopen(output_yuv_name.c_str(),"w"); fwrite(pDst,BUFFER_SZIE, 1 ,fyuvjpg); if (NULL != pSrc) { free(pSrc); pSrc=NULL; } if (NULL != pDst) { free(pDst); pDst=NULL; } fclose(fyuv); fclose(fyuvjpg); return 0; }

    linux  make file:

    #Make file for JPEG encoder #target type and test program directory TARGET_TYPE = EXECUTABLE #compiler COMPILER = g++                                                            

    PRJ_PATH = /home/dahu/development/libjpeg/SourceCode/dev-code/encoder test := encode420                                                                                                             #flags LIBS:=   -lpthread -lm -lgcc -lstdc++  -L/usr/local/lib/ -ljpeg

    INCLS :=  -I/usr/local/include/  CFLAGS := -g -O0 -Wall -DDEBUG_ONLY                                                    #files

    #target control ifeq ($(TARGET_TYPE),EXECUTABLE)  TARGET = Jpeg420Encoder  CLIENT_SOURCES := $(test).cpp    CLIENT_OBJS := $(CLIENT_SOURCES:.cpp=.o)       TARGETCMD = $(COMPILER)  $(INCLS) $(CFLAGS) -o $@ $^ $(LIBS) else  @echo "ERROR !! You have to assign right TARGET_TYPE= EXECUTABLE!" endif

    .PHONY: all   all: $(TARGET)                                                       $(TARGET):$(CLIENT_OBJS)  $(TARGETCMD)   #clean clean:  @rm -rfv  Jpeg420Encoder *.o 

    运行:

    ./Jpeg420Encoder jpeg_320_240_420.0.yuv

    可在当前目录下找到编好的jpeg文件

    转载请注明原文地址: https://ju.6miu.com/read-664917.html

    最新回复(0)