在做算法的过程中经常终端传来的是jpeg图片,需要将jpeg解码为yuv再进行处理。这里使用jpeg-6b交叉编译,然后进行解码,下面是解码的过程:
#include <ctype.h>
#include <errno.h>
#include <unistd.h>
#include <setjmp.h>
#include <sys/stat.h>
#include <stdio.h>
#include <string.h>
#include <time.h>#include <stdlib.h>
#include <string.h>#include "jpeglib.h"#include <setjmp.h>#include "decode.h"struct my_error_mgr {struct jpeg_error_mgr pub;  /* "public" fields */jmp_buf setjmp_buffer;  /* for return to caller */
};typedef struct my_error_mgr * my_error_ptr;void my_decompress_error_exit (j_common_ptr cinfo)
{/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */my_error_ptr myerr = (my_error_ptr) cinfo->err;/* Always display the message. *//* We could postpone this until after returning, if we chose. */(*cinfo->err->output_message) (cinfo);/* Return control to the setjmp point */longjmp(myerr->setjmp_buffer, 1);
}
int decode_jpeg_file (char *frame,int frame_size,char *decoded_frame,int *decoded_frame_size,int *decoded_width,int *decoded_height,int color_space)
{struct jpeg_decompress_struct cinfo;struct my_error_mgr jerr;FILE *infile, *outfile;JSAMPARRAY buffer;      /* Output row buffer */int row_stride;     /* physical row width in output buffer */int finished = 1;int chromaWidth, chromaHeight;int yMask,xMask;int x,y;int width,height;unsigned char *pixels=NULL,*rgbPixels=NULL, *src=NULL;unsigned char *yPixels=NULL, *uPixels=NULL, *vPixels=NULL;unsigned char *yPtr=NULL, *uPtr=NULL, *vPtr=NULL;cinfo.err = jpeg_std_error(&jerr.pub);jerr.pub.error_exit = my_decompress_error_exit;if (setjmp(jerr.setjmp_buffer)) {jpeg_destroy_decompress(&cinfo);//fclose(infile);return -1;}jpeg_create_decompress(&cinfo);//jpeg_stdio_src(&cinfo, infile);jpeg_stdio_buffer_src(&cinfo,(unsigned char *)(frame),frame_size);(void) jpeg_read_header(&cinfo, TRUE);/*set parameters for decompression */cinfo.out_color_space = JCS_YCbCr;(void) jpeg_start_decompress(&cinfo);width  = cinfo.output_width;height = cinfo.output_height;*decoded_width = width;*decoded_height = height;pixels = (unsigned char *)malloc(width*height*3);if(pixels==NULL)printf("Malloc pixels failed!!!!\n");memset(pixels, 0, width * height * 3);src = rgbPixels = pixels;/* JSAMPLEs per row in output buffer */row_stride = cinfo.output_width * cinfo.output_components;/* Make a one-row-high sample array that will go away when done with image */buffer = (*cinfo.mem->alloc_sarray)((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);printf("cinfo.output_width:%d\n",cinfo.output_width);printf("cinfo.output_height:%d\n",cinfo.output_height);printf("cinfo.output_components:%d\n",cinfo.output_components);while (cinfo.output_scanline < cinfo.output_height){int num_rows = jpeg_read_scanlines(&cinfo, buffer, 1);//   printf("cinfo.output_scanline:%d\n",cinfo.output_scanline);// printf("num_rows:%d\n",num_rows);//   printf("\t\tcinfo.output_components:%d\n",cinfo.output_components);// getchar();if (num_rows == 0) {finished = 0;break;}if (cinfo.output_components == 1) {        // greyscaleunsigned int i;unsigned char *in = (unsigned char *)(*buffer);for (i = 0; i < width * num_rows; ++i){*pixels++ = *in; // red   b*pixels++ = *in; // green  g*pixels++ = *in; // blue  r++in;}} else if (cinfo.output_components == 3) { // RGBmemcpy(rgbPixels, (*buffer), num_rows * width * 3);rgbPixels += num_rows * width * 3;//memcpy(pixels, (*buffer), num_rows * width * 3);//pixels += num_rows * width * 3;}}rgbPixels = pixels;if(finished){printf("jpeg_finish_decompress!\n");(void) jpeg_finish_decompress(&cinfo);}printf("\n");jpeg_destroy_decompress(&cinfo);printf("jpeg_destroy_decompress finished! \n");//  fwrite(yPixels, 1, width * height, outfile);
//  fwrite(uPixels, 1, chromaWidth*chromaHeight, outfile);
//  fwrite(vPixels, 1, chromaWidth*chromaHeight, outfile);//    fwrite(rgbPixels, 1, width * height*3, outfile);//if( NULL !=infile)//{//  fclose(infile);//}//if(NULL != outfile)//{//   fclose(outfile);//}/*if(width!=352||height!=288){printf("Decoded img:wid=%d,hgt=%d\tError!!!!!!!not 352*288!!!!\n",width,height);return -1;}else*/if (color_space == DECODE_COLOR_Y||color_space == DECODE_COLOR_GRAY){yPixels = (unsigned char*)malloc(height * width);if(yPixels==NULL)printf("Malloc yPixels fail!!!\n");yPtr = yPixels;for(y = 0; y < height; y++){for(x = 0; x < width; x++){  *yPtr++ = *rgbPixels++;rgbPixels += 2;                   }}memcpy(decoded_frame, yPixels, height * width );*decoded_frame_size = height * width;} else if (color_space == DECODE_COLOR_YUV420){chromaWidth = width/2;chromaHeight = height/2;printf("color_space DECODE_COLOR_YUV420! \n");yMask = xMask = 1;yPixels = (unsigned char*)malloc(width * height);if(yPixels==NULL)printf("Malloc yPixels fail!!!\n");uPixels = (unsigned char*)malloc(chromaWidth*chromaHeight); if(uPixels==NULL)printf("Malloc uPixels fail!!!\n");vPixels = (unsigned char*)malloc(chromaWidth*chromaHeight);        if(vPixels==NULL)printf("Malloc vPixels fail!!!\n");yPtr = yPixels;uPtr = uPixels;vPtr = vPixels;for(y = 0; y < height; y++){for(x = 0; x < width; x++){ *yPtr++ = *rgbPixels++;if((y & yMask) == 0 && (x & xMask) == 0){*uPtr++ = *rgbPixels++;*vPtr++ = *rgbPixels++;   }else{rgbPixels += 2;}                }}memcpy(decoded_frame, yPixels, height * width );memcpy(decoded_frame+height * width, uPixels, chromaHeight * chromaWidth );memcpy(decoded_frame+height * width+chromaHeight * chromaWidth, vPixels, chromaHeight * chromaWidth );*decoded_frame_size = height * width/2*3;printf("decoded_frame:%d\n", *decoded_frame_size);rgbPixels=NULL;}else if (color_space == DECODE_COLORYUV444){chromaWidth = width;chromaHeight = height;yPixels = (unsigned char*)malloc(height * width);if(yPixels==NULL)printf("Malloc yPixels fail!!!\n");uPixels = (unsigned char*)malloc(chromaWidth*chromaHeight);   if(uPixels==NULL)printf("Malloc uPixels fail!!!\n");vPixels = (unsigned char*)malloc(chromaWidth*chromaHeight);        if(vPixels==NULL)printf("Malloc vPixels fail!!!\n");yPtr = yPixels;uPtr = uPixels;vPtr = vPixels;for(y = 0; y < height; y++){for(x = 0; x < width; x++){ *yPtr++ = *rgbPixels++;*uPtr++ = *rgbPixels++;*vPtr++ = *rgbPixels++;                    }}memcpy(decoded_frame, yPixels, height * width );memcpy(decoded_frame+height * width, uPixels, height * width );memcpy(decoded_frame+2*height * width, vPixels, height * width );*decoded_frame_size = height * width*3;}if( NULL !=pixels){free(pixels);pixels =  NULL;}if( NULL !=yPixels){free(yPixels);yPixels = NULL;}if( NULL !=uPixels){free(uPixels);uPixels = NULL;}if( NULL !=vPixels){free(vPixels);vPixels = NULL;}if( NULL !=rgbPixels){rgbPixels = NULL;}return 0;
}

需要注意的是,jpeg-6b解码好像只能用gcc编译,用g++会出错,我通常是将其封装成库,用gcc编译,然后在c++中调用。

使用jpeg库将jpeg图像解码为yuv相关推荐

  1. Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头

    注:分析Tiny Jpeg Decoder源代码的文章: Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头 Tiny Jpeg Decoder (JPEG解码程序) ...

  2. Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 2:解码数据

    注:分析Tiny Jpeg Decoder源代码的文章: Tiny Jpeg Decoder (JPEG解码程序) 源代码分析 1:解码文件头 Tiny Jpeg Decoder (JPEG解码程序) ...

  3. 使用libjpeg进行JPEG图像解码

     如题:如何对test.jpg进行解码? 注:这里使用libjpeg库进行图像解码.也可以不使用libjpeg库,但是比较繁琐. 直接上代码: #include "jpeglib.h&q ...

  4. 简单易用的图像解码库介绍 —— stb_image

    原文链接:简单易用的图像解码库介绍 -- stb_image 说到图像解码库,最容易想起的就是 libpng 和 libjpeg 这两个老牌图像解码库了. libpng 和 libjpeg 分别各自对 ...

  5. QT入门第十天 QT安装和使用alsa库和jpeg库实现音视频录制

    QT入门第十天QT安装和使用alsa库和jpeg库实现音视频录制 第一章 ALSA库的移植和使用 1.ALSA简介 2.移植ALSA (1)移植步骤 3.把移植好的库下载到开发板配置 4.使用移植好的 ...

  6. linux编译安装jpeg,Linux下JPEG库安装脚本(转)

    Linux下JPEG库安装脚本(转)[@more@]该脚本用于在Linux下安装JPEG库,在安装GD库的时候如果没有JPEG库,GD将不能生成JPEG格式的图象. 作者: 何志强#----where ...

  7. 使用libexif开源库修改jpeg相片exif信息

    使用libexif开源库修改jpeg相片exif信息 libexif简介 一.读exif信息 二.写exif信息 说明 例:修改exif中GPS海拔高度 libexif简介 libexif是一个开源的 ...

  8. The Independent JPEG Group‘s JPEG software

    =========================================== 1998 年 3 月 27 日第 6b 版的自述文件 ============================= ...

  9. JPEG系列二 JPEG文件中的EXIF(下)

    https://blog.csdn.net/shelldon/article/details/54407534 EXIF格式介绍(下) JPEG图片中的EXIF信息是以TIFF格式保存的,关于TIFF ...

最新文章

  1. 仓库货位卡标识牌_仓储管理中的货位与标识管理
  2. Linux 学习_在Linux下面安装eclipse
  3. .NET Pet Shop 4.0案例研究预览篇
  4. 有关软件开发中的一些想法
  5. oracle和mysql数据实时同步_异构数据源的CDC实时同步系统——最终选型实战
  6. @程序员,解读 5G 中性命攸关的时延! | 技术头条
  7. Node JS Buffer使用理解
  8. Dynamics CRM 2015中的SSRS Report集成配置
  9. 第14章 系统异常情况记录
  10. 删除Visual Studio最近的项目(收藏)
  11. 慕课软件质量保证与测试(第二章.课后作业)
  12. Windows 10 下使用 telnet 客户端/服务端工具进行连接
  13. IOS开发—系统定位
  14. ubuntu linux指南 管理篇,Ubuntu Linux指南:管理篇 译者序
  15. python:maya 一个人性化的时间处理库
  16. 《网络攻防第二周作业》
  17. WinMerge 过滤器用法
  18. 多波段 “均值标准距”的计算
  19. Simulink建模:一阶滤波模型
  20. MySQL-间隙锁-加锁规则

热门文章

  1. x5-fullscreen_HTML5 FullScreen API简介
  2. 用DELPHI开发DirectX游戏 (转)
  3. 上线“金睛”平台 绿色直播自律联盟迎来第二批成员
  4. 控制教程 —— 介绍篇:1.建模
  5. 对安全研究人员和渗透测试人员有用的Firefox 插件
  6. python画黑白线条_女朋友要你给她画个素描?不要慌,教你用Python分分钟弄出来!...
  7. 无字天书之Python第十二页(迭代器基础)
  8. 【软件】大企业ERP选型的方法
  9. event_log之am_pss
  10. mui 搜索框图标左对齐