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

来源:互联网 发布:mac压缩pdf文件大小 编辑:程序博客网 时间:2024/06/06 00:45

#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文件

0 0