encode YUV420 to jpeg, using libjpeg

#include <stdlib.h>
#include <stdio.h>
#include "jpeglib.h"
#include <setjmp.h>
#include <glib.h>

gboolean jpeg_enc_yv12(guchar* buffer, gint width, gint height, gint quality, char* filename)
{
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    FILE *outfile = NULL;
    gboolean ret = TRUE;
    if(buffer == NULL || width <=0 || height <=0|| filename == NULL)
        return FALSE;
    if ((outfile = fopen(filename, "wb")) == NULL)
    {  
        return FALSE;
    }    
    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);
    jpeg_stdio_dest(&cinfo, outfile);

    cinfo.image_width = width;
    cinfo.image_height = height;
    cinfo.input_components = 3;        
    cinfo.in_color_space = JCS_YCbCr;
    jpeg_set_defaults(&cinfo);
    jpeg_set_quality(&cinfo, quality, TRUE);
    cinfo.raw_data_in = TRUE;  
    
    {
        JSAMPARRAY pp[3];
        JSAMPROW *rpY = (JSAMPROW*)malloc(sizeof(JSAMPROW) * height);
        JSAMPROW *rpU = (JSAMPROW*)malloc(sizeof(JSAMPROW) * height);
        JSAMPROW *rpV = (JSAMPROW*)malloc(sizeof(JSAMPROW) * height);
        int k;
        if(rpY == NULL && rpU == NULL && rpV == NULL)
        {
            ret = FALSE;
            goto exit;
        }
        cinfo.comp_info[0].h_samp_factor =
        cinfo.comp_info[0].v_samp_factor = 2;
        cinfo.comp_info[1].h_samp_factor =
        cinfo.comp_info[1].v_samp_factor =
        cinfo.comp_info[2].h_samp_factor =
        cinfo.comp_info[2].v_samp_factor = 1;
        jpeg_start_compress(&cinfo, TRUE);

        for (k = 0; k < height; k+=2)
        {
            rpY[k]   = buffer + k*width;
            rpY[k+1] = buffer + (k+1)*width;
            rpU[k/2] = buffer+width*height + (k/2)*width/2;
            rpV[k/2] = buffer+width*height*5/4 + (k/2)*width/2;
        }
        for (k = 0; k < height; k+=2*DCTSIZE)
        {
            pp[0] = &rpY[k];
            pp[1] = &rpU[k/2];
            pp[2] = &rpV[k/2];
            jpeg_write_raw_data(&cinfo, pp, 2*DCTSIZE);
        }
        jpeg_finish_compress(&cinfo);
        free(rpY);
        free(rpU);
        free(rpV);
    }
exit:
    fclose(outfile);
    jpeg_destroy_compress(&cinfo);
    return ret;
}

int main()
{
    guchar *buffer = malloc(640*480*3/2);
    jpeg_enc_yv12(buffer, 640, 480, 90, "test.jpg");
    free(buffer);    
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值