使用libjpeg 压缩yuv420到jpg (内存方式)

来源:互联网 发布:访客网络怎么隐藏 编辑:程序博客网 时间:2024/05/17 10:28
#include <Windows.h>#include <stdio.h>  extern  "C" {#include <jpeglib.h> }  #define WIDTH 352#define HEIGHT 288#define QUALITY 80#define BUFFER_SZIE (WIDTH*HEIGHT*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, TCHAR * argv[], TCHAR * envp[] ){    HANDLE fyuv,fyuvjpg;    BYTE *pSrc ,*pDst;    LONG  lSize = 0;    DWORD  readsize;    DWORD  writesize;      pSrc = new BYTE[BUFFER_SZIE];    fyuv = CreateFile(L"cif.yuv", GENERIC_ALL, 0, NULL, OPEN_EXISTING, 0, NULL);    ReadFile(fyuv , pSrc ,BUFFER_SZIE ,&readsize,NULL);      pDst = new BYTE[BUFFER_SZIE];    lSize = put_jpeg_yuv420p_memory(pDst,pSrc , WIDTH ,HEIGHT);    fyuvjpg = CreateFile(L"cif_yuv.jpg", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);    WriteFile(fyuvjpg, pDst, lSize, &writesize, NULL);      CloseHandle(fyuv);    CloseHandle(fyuvjpg);    return 0;}

0 0
原创粉丝点击