jpeg编解码库-libjpeg turbo

上一篇文章分析了jpeg编解码的原理,发展了这么多年,也有了很完善的开源库,这里来记录一下libjpeg turbo库的使用

1.Introduction

libjpeg-turbo图像编解码器,使用了SIMD指令(MMX,SSE2,NEON,AltiVec)来加速x86,x86-64,ARM和PowerPC系统上的JPEG压缩和解压缩。在这样的系统上,libjpeg-turbo的速度通常是libjpeg的2-6倍,其他条件相同。在其他类型的系统上,凭借其高度优化的霍夫曼编码,libjpeg-turbo仍然可以大大超过libjpeg。在许多情况下,libjpeg-turbo的性能可与专有的高速JPEG编解码器相媲美。

2.Install

github下载代码,参考building进行编译
(1) sudo yum -y install nasm
安装nasm,NASM全称The Netwide Assembler,是一款基于80x86和x86-64平台的汇编语言编译程序,其设计初衷是为了实现编译器程序跨平台和模块化的特性
(2)安装libjpeg turbo
cd {build_directory}
cmake -G"Unix Makefiles" [additional CMake flags] {source_directory}
make

3.Test

sudo make test
在这里插入图片描述

4.Demo测试

编译生成的动态链接库在/opt/libjpeg-turbo/lib64目录,因此,使用下列命令设置共享库路径
export LD_LIBRARY_PATH=/opt/libjpeg-turbo/lib64:$LD_LIBRARY_PATH
tjexample.c是测试编解码的demo,这里面会先将jpg文件解码到YUV或者BGR,再将其编码成jpg文件,编译该生成可执行文件
gcc -L /opt/libjpeg-turbo/lib64 -lturbojpeg tjexample_test.c -o tjexample
在这里插入图片描述

5.测试2

上面的demo代码写的比较重,一般解码为BGRX或者YUV平面格式,我们提取这里面的关键代码,这里只做了解码:

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>
#include <math.h>

#include "turbojpeg.h"

const char *subsampName[TJ_NUMSAMP] = {
  "4:4:4", "4:2:2", "4:2:0", "Grayscale", "4:4:0", "4:1:1"
};

const char *colorspaceName[TJ_NUMCS] = {
  "RGB", "YCbCr", "GRAY", "CMYK", "YCCK"
};

int main(int argc, char **argv)
{
    FILE *jpegFile = NULL;
    unsigned long jpegSize;
    int flags = 0;
    int width, height;
    unsigned char *imgBuf = NULL;
    unsigned char *jpegBuf = NULL;
    long size;
    if ((jpegFile = fopen(argv[1], "rb")) == NULL)
    {
        printf("open input file failure\n");
    }
    if (fseek(jpegFile, 0, SEEK_END) < 0 || (size = ftell(jpegFile)) < 0 ||
        fseek(jpegFile, 0, SEEK_SET) < 0)
    {
        printf("determining input file size failure\n");
    }
    if (size == 0)
    {
        printf("determining input file size, Input file contains no data\n");
    }
    jpegSize = (unsigned long)size;
    if ((jpegBuf = (unsigned char *)malloc(jpegSize * sizeof(unsigned char))) == NULL)
    {
        printf("allocating JPEG buffer\n");
    }
    if (fread(jpegBuf, jpegSize, 1, jpegFile) < 1)
    {
        printf("reading input file");
    }
    fclose(jpegFile);
    jpegFile = NULL;


    tjhandle handle = NULL;
    int subsample, colorspace;
    int padding = 1; 
    int ret = 0;

    handle = tjInitDecompress();
    ret = tjDecompressHeader3(handle, jpegBuf, size, &width, &height, &subsample, &colorspace);
    if(ret < 0)
    {
        printf("header file error, errorStr:%s, errorCode:%d\n", tjGetErrorStr(), tjGetErrorCode(handle));
        return -1;
    }
    printf("input image: %d x %d, %s subsampling, %s colorspace\n", width, height, subsampName[subsample], colorspaceName[colorspace]);
    int sw_out_size = width * height * 3;      // We alloc the largest buf to support YUV444.
    unsigned char *sw_out_buf = (unsigned char*)malloc(sw_out_size * sizeof(unsigned char));
    if (sw_out_buf == NULL) {
        printf("sw_out_buf is NULL\n");
    }

    flags |= 0;
    
    //ret<-1表示解码异常,此时通过tjGetErrorCode查看错误码,错误码为0时,表示警告,错误码为-1时表示错误
    int pixelFormat = TJPF_BGRX;
    ret = tjDecompress2(handle, jpegBuf, size, sw_out_buf, width, 0, height, pixelFormat, flags);
    //ret = tjDecompressToYUV2(handle, jpeg_buf, size, dst_buf, *width, padding, *height, flags);
    if ((0 != tjGetErrorCode(handle)) && (ret < 0))
    {
        printf("error : decompress to yuv failed, errorStr:%s, errorCode:%d\n", tjGetErrorStr(), tjGetErrorCode(handle));
        return -1;
    }
    if ((0 == tjGetErrorCode(handle)) && (ret < 0))
        printf("warning : errorStr:%s, errorCode:%d\n", tjGetErrorStr(), tjGetErrorCode(handle));
    tjDestroy(handle);
    
    if (sw_out_buf)
    {
        free(sw_out_buf);
    }
    if (jpegBuf)
    {
        free(jpegBuf);
    }
    return 0;
}

gcc -L /opt/libjpeg-turbo/lib64 -lturbojpeg libjpeg_test.c -o libjpeg_test
./libjpeg_test …/jpegdecoder/4.jpg
在这里插入图片描述
出现上述warning的原因是jpeg文件头有些信息不正确,errorcode=0表示只是warning,解码器会继续解码,但显示的图像可能会有问题。
下面文章来讲讲icc信息和质量参数。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值