libjpeg 使用

libjpeg

http://libjpeg.sourceforge.net/

libjpeg 是 libjpeg-turbo 和 MozJPEG 的祖宗,这三个库的应用层代码通用。libjpeg使用方法是直接添加 .c 和 .h 文件到工程,其他两个库是通过 cmake 组织源代码,然后通过编译器生成静态链接库和头文件添加到工程

STM32CUBEMX 有 libjpeg 组件,已经整理好 .c 和 .h 

libjpeg 库,第一个要阅读的文件就是 README

libjpeg-turbo

https://github.com/libjpeg-turbo/libjpeg-turbo

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

MozJPEG

https://github.com/mozilla/mozjpeg

 MozJPEG 是 libjpeg-turbo 的补丁,包含了 libjpeg-turbo 所有的功能,并且新增了一些功能。

 

使用 jpeg 指南:

使用 .a文件和 .h文件

编译源码库,生成静态链接库,比如 libjpeg.a,在链接步骤会引用这个库。如果只使用压缩或者解压缩,只会链接相应的部分,不会整个库都链接进去。

不建议用共享库(动态链接库)

 

注意:

1、编译器的路径要添加到环境PATH中,否则会提示:找不到 libwinpthread-1.dll 无法继续执行代码,因为libwinpthread-1.dll在编译器 bin 文件夹下(比如QT的编译器:D:\Qt\Qt5.14.2\Tools\mingw730_64\bin)

2、cmake需要用到make工具,windows下可以用QT编译器路径下的 mingw32-make.exe

3、RGB data (three components per pixel) or grayscale data (one component per pixel)

 

编译配置:

CMAKE_BUILD_TYPE: Release或者Debug,默认是Release

ENABLE_STATIC: 设置是否生成静态库

ENABLE_SHARED: 设置是否生成动态库

WITH_SIMD: 设置是否使用 SIMD 指令

WITH_TURBOJPEG: 是否生成 turbo版本的 jpeg库

 

http://www.voidcn.com/article/p-fwyrdlmp-bdp.html

https://blog.csdn.net/zhizhengguan/article/details/107560858

https://blog.csdn.net/jcq521045349/article/details/79578124

 

使用 make 编译源文件

在 ”Where to build the binaries“ 中打开 cmd,执行 make,然后执行 make install

 

 最后生成的文件放在如下目录:

 

 

 

 

 

 

最后生成的文件如下:

 

 bin文件夹下是各个例子的可执行文件

libjpeg.a
libjpeg API的静态链接库

libjpeg-{version}.dll
DLL的libjpeg API的动态链接库(DLL)

libjpeg.dll.a
libjpeg API的导入库

注:libjpeg-{version}.dll 和 libjpeg.dll.a 配套使用,libjpeg.a单独使用

libturbojpeg.a
TurboJPEG API的静态链接库

libturbojpeg.dll
TurboJPEG API的动态链接库(DLL)

libturbojpeg.dll.a
TurboJPEG API的导入库

其中“{version}” 是 62,7,或8,取决于libjpeg v6b (默认),v7,或v8的emulation是否启用。

 

libjpeg.txt

库使用说明书

tjexample.c

是测试编解码的demo,这里面会先将jpg文件解码到YUV或者BGR,再将其编码成jpg文件

 

参考代码:

YUV422 YUYU 转 JPG

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "libjpeg-turbo-gcc64/include/jpeglib.h"
#include "libjpeg-turbo-gcc64/include/jconfig.h"
#include "libjpeg-turbo-gcc64/include/jerror.h"
#include "libjpeg-turbo-gcc64/include/jmorecfg.h"
#include <QDir>
#include <QTextStream>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    g_str_dir = QDir::currentPath();
//    g_str_dir = ".";
    qDebug() << g_str_dir;

    uint16_t width = 400;
    uint16_t height = 300;
    struct jpeg_compress_struct cinfo;
    struct jpeg_error_mgr jerr;
    JSAMPROW row_pointer[1];
    int i = 0;
    unsigned char *pY, *pU, *pV;
    uchar inputYuv[width * height * 2];
    unsigned char yuvbuf[width * 3];//每个像素3个字节
    uchar *outJpeg = NULL;  //初始化非常重要!!!
    unsigned long outSize = 0;  //初始化非常重要!!!

    read_data_from_YUV_file(inputYuv, width, height);
    qDebug("%02X %02X %02X %02X", inputYuv[0], inputYuv[1], inputYuv[2], inputYuv[3]);
    qDebug("%02X %02X %02X %02X", inputYuv[4], inputYuv[5], inputYuv[6], inputYuv[7]);


    cinfo.err = jpeg_std_error(&jerr);
    jpeg_create_compress(&cinfo);

    jpeg_mem_dest(&cinfo, &outJpeg, &outSize);

    cinfo.image_width = width;//设置输入图片宽度
    cinfo.image_height = height;//设置图片高度
    cinfo.input_components = 3;
    cinfo.in_color_space = JCS_YCbCr;//设置输入图片的格式,支持RGB/YUV/YCC等等
//    cinfo.dct_method = JDCT_ISLOW;
    jpeg_set_defaults(&cinfo);//其它参数设置为默认的!
    jpeg_set_quality(&cinfo, 40, TRUE);//设置转化图片质量,范围0-100
    jpeg_start_compress(&cinfo, TRUE);

    pY = inputYuv;
    pU = inputYuv + 1;
    pV = inputYuv + 3;

    /*  0   1   2   3     4   5   6   7
     * Y00 U00 Y01 V00   Y02 U01 Y03 V01
     * Y10 U10 Y11 V10   Y12 U11 Y13 V11
     */

    while (cinfo.next_scanline < cinfo.image_height)
    {
        uint16_t index = 0;
        for (i = 0; i < width; i += 2)
        {//输入的YUV图片格式为标准的YUV444格式,所以需要把YUV422转化成YUV444.
            yuvbuf[index++] = *pY;
            yuvbuf[index++] = *pU;
            yuvbuf[index++] = *pV;
            pY += 2;
            yuvbuf[index++] = *pY;
            yuvbuf[index++] = *pU;
            yuvbuf[index++] = *pV;
            pY += 2;
            pU += 4;
            pV += 4;
        }
        row_pointer[0] = yuvbuf;
        jpeg_write_scanlines(&cinfo, row_pointer, 1);//单行图片转换压缩
    }

    jpeg_finish_compress(&cinfo);

    QFile fileBin_write_crc("./test.jpg");
    if(!fileBin_write_crc.open(QIODevice::WriteOnly))
    {
        qDebug() << "fail: open test.jpg";
        return;
    }

    fileBin_write_crc.write((const char *)outJpeg, outSize);
    fileBin_write_crc.close();

    if(NULL != outJpeg)
    {
        free(outJpeg);
        outJpeg = NULL;
    }
    jpeg_destroy_compress(&cinfo);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::read_data_from_YUV_file(uchar *buffer, uint16_t width, uint16_t height)
{

    uchar *buf = buffer;

    QFile yuv_file(g_str_dir + "/YUV422_YUYV.yuv");
    if(!yuv_file.open(QIODevice::ReadOnly))
    {
        qDebug() << "bin 文件未找到!!!!!!!!!!!";
        return;
    }

    QByteArray data;
    unsigned long i = 0;
    while(!yuv_file.atEnd())
    {
        data = yuv_file.read(4);
        *(buf++) = static_cast<uchar>(data[0]);
        *(buf++) = static_cast<uchar>(data[1]);
        *(buf++) = static_cast<uchar>(data[2]);
        *(buf++) = static_cast<uchar>(data[3]);
        i = i + 4;
        if(i >= width * height * 2)
            break;
    }
    yuv_file.close();
}

 

toolchain file for cross-compiling

set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_VERSION 1)
set(CMAKE_SYSTEM_PROCESSOR cortex-r5)


set(GCC_INSTALL_ROOT D:/company/document/EC600S/ql-sdk/ql-cross-tool/win32/owtoolchain/gcc-arm-none-eabi)
set(CMAKE_SYSROOT ${GCC_INSTALL_ROOT}/arm-none-eabi)

set(CMAKE_C_COMPILER ${GCC_INSTALL_ROOT}/bin/arm-none-eabi-gcc.exe)
set(CMAKE_CXX_COMPILER ${GCC_INSTALL_ROOT}/bin/arm-none-eabi-g++.exe)


set(CMAKE_C_FLAGS "--specs=nosys.specs")
set(STDLIB ${GCC_INSTALL_ROOT}/arm-none-eabi/lib/thumb/v7/nofp/libm.a)
link_libraries("${STDLIB}")

set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

 

posted @ 2021-03-12 15:12  流水灯  阅读(75)  评论(0编辑  收藏  举报