yuv to jpeg

int write_JPEG_file (char * filename, unsigned char* yuvData, int quality,int image_width,int image_height)
{
     struct jpeg_compress_struct cinfo;
 
     struct jpeg_error_mgr jerr;
 
     FILE * outfile;    // target file 
     JSAMPROW row_pointer[1];  // pointer to JSAMPLE row[s] 
     int row_stride;    // physical row width in image buffer
     JSAMPIMAGE  buffer;
 
     unsigned char *pSrc,*pDst;
 
     int band,i,buf_width[3],buf_height[3];
     cinfo.err = jpeg_std_error(&jerr);
 
     jpeg_create_compress(&cinfo);
 
 
     if ((outfile = fopen(filename, "wb")) == NULL) {
         fprintf(stderr, "can't open %s\n", filename);
         exit(1);
     }
     jpeg_stdio_dest(&cinfo, outfile);
 
 
     cinfo.image_width = image_width;  // image width and height, in pixels
     cinfo.image_height = image_height;
     cinfo.input_components = 3;    // # of color components per pixel
     cinfo.in_color_space = JCS_RGB;  //colorspace of input image
 
     jpeg_set_defaults(&cinfo);
 
     jpeg_set_quality(&cinfo, quality, TRUE );
 
     //////////////////////////////
     cinfo.raw_data_in = TRUE;
     cinfo.jpeg_color_space = JCS_YCbCr;
     cinfo.comp_info[0].h_samp_factor = 2;
     cinfo.comp_info[0].v_samp_factor = 2;
     /////////////////////////
 
     jpeg_start_compress(&cinfo, TRUE);
 
     buffer = (JSAMPIMAGE) (*cinfo.mem->alloc_small) ((j_common_ptr) &cinfo,
                                 JPOOL_IMAGE, 3 * sizeof(JSAMPARRAY)); 
     for(band=0; band <3; band++)
     {
         buf_width[band] = cinfo.comp_info[band].width_in_blocks * DCTSIZE;
         buf_height[band] = cinfo.comp_info[band].v_samp_factor * DCTSIZE;
         buffer[band] = (*cinfo.mem->alloc_sarray) ((j_common_ptr) &cinfo,
                                 JPOOL_IMAGE, buf_width[band], buf_height[band]);
     } 
 
     unsigned char *rawData[3];
     rawData[0]=yuvData;
     rawData[1]=yuvData+image_width*image_height;
     rawData[2]=yuvData+image_width*image_height*5/4;
 
     int src_width[3],src_height[3];
     for(int i=0;i<3;i++)
     {
         src_width[i]=(i==0)?image_width:image_width/2;
         src_height[i]=(i==0)?image_height:image_height/2;
     }
 
     //max_line一般为16,外循环每次处理16行数据。
     int max_line = cinfo.max_v_samp_factor*DCTSIZE; 
     for(int counter=0; cinfo.next_scanline < cinfo.image_height; counter++)
     {   
         //buffer image copy.
         for(band=0; band <3; band++)  //每个分量分别处理
         {
              int mem_size = src_width[band];//buf_width[band];
              pDst = (unsigned char *) buffer[band][0];
              pSrc = (unsigned char *) rawData[band] + counter*buf_height[band] * src_width[band];//buf_width[band];  //yuv.data[band]分别表示YUV起始地址
 
              for(i=0; i <buf_height[band]; i++)  //处理每行数据
              {
                   memcpy(pDst, pSrc, mem_size);
                   pSrc += src_width[band];//buf_width[band];
                   pDst += buf_width[band];
              }
         }
         jpeg_write_raw_data(&cinfo, buffer, max_line);
     }
 
 
     jpeg_finish_compress(&cinfo);
 
     fclose(outfile);
 
     jpeg_destroy_compress(&cinfo);
 
     return 0;
}


你可能感兴趣的:(yuv to jpeg)