libjpeg-turbo支持直接从JPEG解压成YUV格式,或者反之。这也是我当初想研究它的一个动力。

看了头文件注释,它是支持YUV444(即宏TJSAMP_444),YUV422(即宏TJSAMP_422),YUV420(即宏TJSAMP_420),YUV400(即宏TJSAMP_440),YUV411(即宏TJSAMP_411)。可惜的是,只支持平面格式(plane),对于交织的如UYVY或特别的如NV12(即YUV420SP)或NV16(即YUV422SP),都没看到有支持。在sourceforge上看邮件列表,发现有些描述,但还没研究过,看发布的源码,也未见有说明,估计是不支持的。

本文简单介绍如何从JPEG解压成YUV格式,以及如何将YUV压缩成JPEG。

libjpeg-turbo使用tjBufSizeYUV2函数计算YUV大小,开始时没注意第二个参数pad,默认传递0,发现没效果,而传1或4,却是可以的。解压后的YUV的格式,是由JPEG图片的采样格式决定的,如果JPEG本身是YUV420,则解压得到的YUV,就是YUV420格式。

示例代码如下:

int tjpeg2yuv(unsigned char* jpeg_buffer, int jpeg_size, unsigned char** yuv_buffer, int* yuv_size, int* yuv_type)
{tjhandle handle = NULL;int width, height, subsample, colorspace;int flags = 0;int padding = 1; // 1或4均可,但不能是0int ret = 0;handle = tjInitDecompress();tjDecompressHeader3(handle, jpeg_buffer, jpeg_size, &width, &height, &subsample, &colorspace);printf("w: %d h: %d subsample: %d color: %d\n", width, height, subsample, colorspace);flags |= 0;*yuv_type = subsample;// 注:经测试,指定的yuv采样格式只对YUV缓冲区大小有影响,实际上还是按JPEG本身的YUV格式来转换的*yuv_size = tjBufSizeYUV2(width, padding, height, subsample);*yuv_buffer =(unsigned char *)malloc(*yuv_size);if (*yuv_buffer == NULL){printf("malloc buffer for rgb failed.\n");return -1;}ret = tjDecompressToYUV2(handle, jpeg_buffer, jpeg_size, *yuv_buffer, width,padding, height, flags);if (ret < 0){printf("compress to jpeg failed: %s\n", tjGetErrorStr());}tjDestroy(handle);return ret;
}int tyuv2jpeg(unsigned char* yuv_buffer, int yuv_size, int width, int height, int subsample, unsigned char** jpeg_buffer, unsigned long* jpeg_size, int quality)
{tjhandle handle = NULL;int flags = 0;int padding = 1; // 1或4均可,但不能是0int need_size = 0;int ret = 0;handle = tjInitCompress();flags |= 0;need_size = tjBufSizeYUV2(width, padding, height, subsample);if (need_size != yuv_size){printf("we detect yuv size: %d, but you give: %d, check again.\n", need_size, yuv_size);return 0;}ret = tjCompressFromYUV(handle, yuv_buffer, width, padding, height, subsample, jpeg_buffer, jpeg_size, quality, flags);if (ret < 0){printf("compress to jpeg failed: %s\n", tjGetErrorStr());}tjDestroy(handle);return ret;
}

另外,该库也支持从RGB转换成YUV,或反之。调用相应的函数即可,不再详述。示例代码如下:

int trgb2yuv(unsigned char* rgb_buffer, int width, int height, unsigned char** yuv_buffer, int* yuv_size, int subsample)
{tjhandle handle = NULL;int flags = 0;int padding = 1; // 1或4均可,但不能是0int pixelfmt = TJPF_RGB;int ret = 0;handle = tjInitCompress();flags |= 0;*yuv_size = tjBufSizeYUV2(width, padding, height, subsample);*yuv_buffer =(unsigned char *)malloc(*yuv_size);if (*yuv_buffer == NULL){printf("malloc buffer for rgb failed.\n");return -1;}ret = tjEncodeYUV3(handle, rgb_buffer, width, 0, height, pixelfmt, *yuv_buffer, padding, subsample, flags);if (ret < 0){printf("encode to yuv failed: %s\n", tjGetErrorStr());}tjDestroy(handle);return ret;
}int tyuv2rgb(unsigned char* yuv_buffer, int yuv_size, int width, int height, int subsample, unsigned char** rgb_buffer, int* rgb_size)
{tjhandle handle = NULL;int flags = 0;int padding = 1; // 1或4均可,但不能是0int pixelfmt = TJPF_RGB;int need_size = 0;int ret = 0;handle = tjInitDecompress();flags |= 0;need_size = tjBufSizeYUV2(width, padding, height, subsample);if (need_size != yuv_size){printf("we detect yuv size: %d, but you give: %d, check again.\n", need_size, yuv_size);return -1;}*rgb_size = width*height*tjPixelSize[pixelfmt];*rgb_buffer =(unsigned char *)malloc(*rgb_size);if (*rgb_buffer == NULL){printf("malloc buffer for rgb failed.\n");return -1;}ret = tjDecodeYUV(handle, yuv_buffer, padding, subsample, *rgb_buffer, width, 0, height, pixelfmt, flags);if (ret < 0){printf("decode to rgb failed: %s\n", tjGetErrorStr());}tjDestroy(handle);return ret;
}

以上代码示例,二级指针均在函数内分配内存,需要调用者自行释放,否则会有内存泄漏。

李迟 7.8




libjpeg学习4:libjpeg-turbo之YUV相关推荐

  1. libjpeg学习2:内存篇

    前面文章说到到libjpeg的使用示例,里面的例子实际上是文件的操作,即解压JPEG文件,因为libjpeg有对FILE操作的函数,所以代码直接用jpeg_stdio_src(&cinfo, ...

  2. libjpeg学习3:turbojpeg试用

    turbojpeg针对ARM和X86对了优化,宣称其速度是libjpeg的2到4倍.下载其源码,值得称赞的地方是其例子,单元测试很到位.另外是它的注释,或者说是html说明文件,对于宏.函数都有详细的 ...

  3. libjpeg学习1:简单使用示例

    libjpeg这个库主要用于处理jpeg数据,比如将RGB压缩成JPEG,或者将JPEG解压为RGB.其实早在4年前已经接触过,但一直没写过这方面的文章.后来想想还是有必要写出来,至少可以证明自己搞过 ...

  4. libjpeg用法linux压缩,libjpeg学习1:简单使用示例

    #include #include #include #include #include #include #include // jpeg库头文件必须放到stdio.h后面 #include &qu ...

  5. android 编译 libjpeg,Android 编译libjpeg

    之前需要将yuv转换为jpg图像,查看网上说libjpeg-turbo比libjpeg快2-3倍,但是在Android手机上实践了一下,需要40-60个ms,这个虽然比以前的300ms好多了,但是还是 ...

  6. 视频编解码学习(六):YUV格式学习

    1.YUV格式详解 参考文章 : http://blog.csdn.NET/linweig/article/details/5515928 http://www.cnblogs.com/azraell ...

  7. 【数字视频编码基础学习】像素格式RGB/YUV

    一.RGB概述 R:red,G:Green,B:Blue,即红绿蓝--色光三原色(加法三原色),通过不同比例相加,可产生多种颜色. 补:除色光三原色外,还有另一种颜料三原色(减法三原色),即看到的印刷 ...

  8. unity解码4k图片过慢,使用turbojpeg加速,使用opencl加速,使用libjpeg,使用v4l2

    后记: 果然贻笑大方,libjpeg也不记得哪个文章说最新版是1996年的,还煞有介事的给了一个1996年以后再没更新过的所谓官网,实际上libjpeg一直有维护和更新,支持到的最新版vs比我用的还要 ...

  9. Android压缩图片和libjpeg库

    前言 Fjpeg使用 Fjpeg 注意 如何使用 如何压缩图片只改变在硬盘的存储大小 如何改变图片分辨率让其Bitmap对象可以加载到内存中 关于重载版本 开始学习之旅 补充知识的结论 修改图片分辨率 ...

最新文章

  1. Java基础笔记(入门,语法基础,流程控制,数组)
  2. code blocks 快捷键
  3. apollo芯片_ADAS/AD主控芯片研究:集成趋势下的短板与变革
  4. 如何加减单元格指定数字_Word如何做加减乘除?你学会这个公式就会了
  5. spark整合MySQL
  6. 2021云栖大会开源引力峰会发布的战略合作,Grafana服务到底是什么?
  7. 微软开源模糊测试平台 OneFuzz
  8. 最简单的排序算法(C和C++实现)
  9. python3.7模块内容_python3.7 time模块
  10. TThread类详解转
  11. 计算机网络管理员高级操作技能考核试卷,高级计算机维修工操作技能考核试卷...
  12. android 二级 滚动,android使用 ScrollerView 实现 可上下滚动的分类栏实例
  13. java生产环境增量发版陷阱【原】
  14. 高斯赛德尔潮流计算c语言编程,高斯赛德尔法潮流计算
  15. 西门子s7删除注册表,西门子S7200编程软件卸载步骤
  16. python制作3d相册代码_python中Matplotlib实现绘制3D图的示例代码
  17. Fiddler使用和数据抓包
  18. 企业网络规划和设计方案
  19. antd 日期组件出现了英文
  20. pythonc语言基础_D17——C语言基础学PYTHON

热门文章

  1. CSS也能控制表格的交替颜色
  2. 海康威视第一季度营收165亿元 净利润22.84亿元
  3. 官方揭晓iQOO 9正反面宣传照:挖孔直屏+巨型三摄相机模组
  4. Siri为什么越来越蠢?
  5. iPhone 13临近发布,富士康需要在9月底前再招聘20万名工人
  6. iPhone 13或将配备更大容量电池 售价与iPhone 12基本相当
  7. 苹果新iPad Pro代工订单或将推升富士康4月份营收
  8. 瑞银:将京东目标价上调至110美元 维持“买入”评级
  9. 阿里巴巴美股股价大跌:创在美上市以来最大单日跌幅
  10. “贵妇”必备的高价糖水,我给燕窝上了10年智商税