windows 10上源码编译libjpeg-turbo和使用教程 | compile and use libjpeg-turbo on windows 10

2021-01-29 16:16

阅读:639

标签:compress   before   close   signed   col   org   bytes   iostream   https   

本文首发于个人博客https://kezunlin.me/post/83828674/,欢迎阅读!

compile and use libjpeg-turbo on windows 10

Series

  • compile and use libjpeg-turbo on windows 10
  • compile and use libjpeg-turbo on ubuntu 16.04

Guide

build requirements

Build Requirements

  • cmake 2.8
  • NASM 2.13
  • Visual Studio 2015
  • libjpeg-turbo 1.5.4

(1) If using NASM, 2.05 or later is required for an x86-64 build.

(2) nasm.exe/yasm.exe should be in your PATH.

download

git clone https://github.com/libjpeg-turbo/libjpeg-turbo.git
# or
wget https://codeload.github.com/libjpeg-turbo/libjpeg-turbo/zip/master

install nasm

wget http://www.nasm.us/pub/nasm/releasebuilds/2.13.03rc1/win64/nasm-2.13.03rc1-installer-x64.exe

add C:\Program Files\NASM to env path.

## compile libjpeg

cmake-gui

CMAKE_BUILD_TYPE = Release
ENABLE_SHARED = ON
CMAKE_INSTALL_PREFIX = d:/libjpeg-turbo64
NASM = C:/Program Files/NASM/nasm.exe

configure and generate sln, compile with visual studio 2015 and install.

## usage with cmake

### libjpegturbo-config.cmake
```bash
set(LIBJPEGTURBO_FOUND TRUE) # auto
set(LIBJPEGTURBO_ROOT_DIR "d:/libjpeg-turbo64")

find_path(LIBJPEGTURBO_INCLUDE_DIR NAMES jpeglib.h turbojpeg.h PATHS "${LIBJPEGTURBO_ROOT_DIR}/include")
mark_as_advanced(LIBJPEGTURBO_INCLUDE_DIR) # show entry in cmake-gui

find_library(LIBJPEGTURBO_JPEG_LIBRARY NAMES jpeg.lib PATHS "${LIBJPEGTURBO_ROOT_DIR}/lib")
mark_as_advanced(LIBJPEGTURBO_JPEG_LIBRARY) # show entry in cmake-gui

find_library(LIBJPEGTURBO_TURBOJPEG_LIBRARY NAMES turbojpeg.lib PATHS "${LIBJPEGTURBO_ROOT_DIR}/lib")
mark_as_advanced(LIBJPEGTURBO_TURBOJPEG_LIBRARY) # show entry in cmake-gui

use xxx_INCLUDE_DIRS and xxx_LIBRARIES in CMakeLists.txt

set(LIBJPEGTURBO_INCLUDE_DIRS ${LIBJPEGTURBO_INCLUDE_DIR} )
set(LIBJPEGTURBO_LIBRARIES ${LIBJPEGTURBO_JPEG_LIBRARY} ${LIBJPEGTURBO_TURBOJPEG_LIBRARY} )

message( "libjpegturbo-config.cmake " ${LIBJPEGTURBO_ROOT_DIR})
### CMakeLists.txtbash
find_package(LIBJPEGTURBO REQUIRED)
include_directories(${LIBJPEGTURBO_INCLUDE_DIRS})

add_executable (example_jpeg
${CMAKE_CURRENT_SOURCE_DIR}/src/example/example_jpeg.cpp
)

target_link_libraries (example_jpeg
${LIBJPEGTURBO_LIBRARIES}
)

add_executable (example_turbojpeg
${CMAKE_CURRENT_SOURCE_DIR}/src/example/example_turbojpeg.cpp
)

target_link_libraries (example_turbojpeg
${LIBJPEGTURBO_LIBRARIES}
)
```

Example Code

jpeglib vs turbojpeg

jpeglib

  • include: #include "jpeglib.h"
  • lib: jpeg.lib
  • dll: jpeg62.dll

turbojpeg

  • include: #include "turbojpeg.h"
  • lib: turbojpeg.lib
  • dll: turbojpeg.dll

turbojpeg is (3-5x) faster than jpeglib.

jpeglib

#include 
#include 
#include 

#include "jpeglib.h"

typedef unsigned char BYTE;

bool CompressJPEG(
    /*IN*/BYTE *src, int width, int height, int depth,
    /*OUT*/BYTE **dst, unsigned long *dstLen
)
{
    // NOTICE: dst space must be created outside before passing in.
    struct jpeg_compress_struct jcs;
    struct jpeg_error_mgr jem;
    jcs.err = jpeg_std_error(&jem);

    jpeg_create_compress(&jcs);
    jpeg_mem_dest(&jcs, dst, dstLen);
    jcs.image_width = width;
    jcs.image_height = height;
    jcs.input_components = depth;
    jcs.in_color_space = JCS_RGB;

    jpeg_set_defaults(&jcs);
    jpeg_set_quality(&jcs, 80, true);

    jcs.jpeg_color_space = JCS_YCbCr;
    jcs.comp_info[0].h_samp_factor = 2;
    jcs.comp_info[0].v_samp_factor = 2;

    jpeg_start_compress(&jcs, TRUE);
    JSAMPROW row_pointer[1];
    int row_stride = jcs.image_width*jcs.num_components;
    while (jcs.next_scanline lOutSize to contain valid dst buffer.
    unsigned char *pOutBuffer = new unsigned char[nImgSize]; // new dst buffer
    unsigned long lOutSize = 0;

    // (2) compress to mem
    compress_jpeg_to_mem(
        pRawImage, width, height, channel, J_COLOR_SPACE::JCS_GRAYSCALE, 90,
        &pOutBuffer, &lOutSize
    );

    std::cout  buffer(size);
    //ifs.read(&buffer.front(), size);
    BYTE *src = new BYTE[size];
    ifs.read((char*)src, size);

    // (1) decompress from mem
    BYTE *dst = NULL; // raw image buffer allocated inside **decompress** function
    unsigned long dstLen;
    int width, height, channel, color_space;

    // allocate dst inside function
    decompress_jpeg_from_mem(
        src,size,
        &dst, &dstLen, &width, &height, &channel, &color_space
    );

    std::cout  lOutSize to contain valid dst buffer.
        unsigned char *pOutBuffer = new unsigned char[srcLen]; // new dst buffer
        unsigned long lOutSize = 0;

        // (2) compress to mem
        compress_jpeg_to_mem(
            src, width, height, channel, J_COLOR_SPACE::JCS_GRAYSCALE, 90,
            &pOutBuffer, &lOutSize
        );

        // (3) free memory
        delete[] pOutBuffer;
    }

    time_t end = time(NULL);
    std::cout 

turbojpeg

#include 
#include 
#include 
#include 

#include "turbojpeg.h"

typedef unsigned char BYTE;

void save_buffer_to_file(const char *filename,BYTE* buffer,unsigned long size)
{
    FILE *outfile;
    if ((outfile = fopen(filename, "wb")) != NULL) {
        fwrite(buffer, size, 1, outfile);
        fclose(outfile);
    }
    else
    {
        fprintf(stderr, "can't open %s\n", filename);
        exit(1);
    }
}

/*
* Compress image buffer to a JPEG image in memory.
*
* @@input
*
* @param : [src] pointer to an image buffer that will be compressed.
* @param : 
*
* @@output
* @param : [dst] pointer to an image buffer that will receive the compressed image.
           This variable should be passed in with NULL, and will be allocated by 
           TurboJPEG(either by tjAlloc(),or by the Compress/Decompress) method 
           So we need to use tjFree() to free memory allocated after we are done 
           working on dst.
* @param : [dstLen] size of dst image buffer in bytes. This should be passed in with
           value 0.
*
* @@return
* @param void
*
* @@demo
*  
        BYTE *dst = NULL;
        unsigned long dstLen = 0;
        tj_compress_jpeg_to_mem(
            ....,
            &dst,&dstLen
        )
*/
void tj_compress_jpeg_to_mem(
    /*IN*/BYTE *src, int width, int height, int pixelFormat, int subsamp, int quality, int flags,
    /*OUT*/BYTE **dst, unsigned long *dstLen
)
{
    // NOTICE : we must use tjAlloc() and tjFree() to allocate dst buffer.
    // for compress, we let **tjCompress2** allocate dst buffer.
    // for decompress, we allocate dst buffer by ourself.

    tjhandle handle = tjInitCompress();
    //tjCompress2(handle, src, width, 0/*pitch*/, height, TJPF::TJPF_GRAY,
    //  &pOutBuffer, &lOutSize, TJSAMP::TJSAMP_GRAY, quality,
    //  TJFLAG_FASTDCT); //TJFLAG_FASTDCT

    tjCompress2(
        handle, src, width, 0/*pitch*/, height, pixelFormat,
        dst, dstLen, subsamp, quality, flags
    );

    tjDestroy(handle);
}

void tj_compress_gray_jpeg_to_mem(
    /*IN*/BYTE *src, int width, int height, int quality,
    /*OUT*/BYTE **dst, unsigned long *dstLen
)
{
    int pixelFormat = TJPF::TJPF_GRAY;
    int subsamp = TJSAMP::TJSAMP_GRAY;
    int flags = TJFLAG_FASTDCT;

    tj_compress_jpeg_to_mem(
        src, width, height, pixelFormat, subsamp, quality, flags,
        dst, dstLen
    );
}

void tj_compress_gray_jpeg_to_file(
    /*IN*/BYTE *src, int width, int height, int quality,
    /*OUT*/const char* dst_filename
)
{
    int pixelFormat = TJPF::TJPF_GRAY;
    int subsamp = TJSAMP::TJSAMP_GRAY;
    int flags = TJFLAG_FASTDCT;

    // (1) init dst memory buffer
    BYTE *dst = NULL; // memory allocated by TurboJPEG tjAlloc()
    unsigned long dstLen = 0;

    // (2) compress
    tj_compress_jpeg_to_mem(
        src, width, height, pixelFormat, subsamp, quality, flags,
        &dst, &dstLen
    );

    // (3) write buffer to file
    save_buffer_to_file(dst_filename, dst, dstLen);

    // (4) free memory allocated by TurboJPEG
    tjFree(dst);
}


/*
* Compress image buffer to a JPEG image in memory.
*
* @@input
*
* @param : [src] pointer to an image buffer that will be compressed.
* @param :
*
* @@output
* @param : [dst] pointer to an image buffer that will receive the decompressed image.
           This variable should be passed in with NULL, and will be allocated in
           method by new[]. So we need to use delete[] to free memory allocated 
           after we are done working on dst.
* @param : [dstLen] size of dst image buffer in bytes. This should be passed in with
            value 0.
*
* @@return
* @param void
*
* @@demo
*
        BYTE *dst = NULL;
        unsigned long dstLen = 0;
        tj_decompress_jpeg_from_mem(
        ....,
        &dst,&dstLen
        )
*/
void tj_decompress_jpeg_from_mem(
    /*IN*/BYTE *src, unsigned long srcLen,int tjPixelFormat,int flags,
    /*OUT*/BYTE **dst, unsigned long *dstLen, int *width, int *height, int *components, int *jpegSubsamp, int *jpegColorspace)
{
    tjhandle handle = tjInitDecompress();
    tjDecompressHeader3(handle, src, srcLen, width, height, jpegSubsamp, jpegColorspace);

    (*components) = tjPixelSize[(TJPF)tjPixelFormat]; // 1 for GRAY,3 for RGB
    (*dstLen) = (*width) * (*height) * (*components);

    BYTE *tmp_dst = new BYTE[*dstLen]; /* Allocate out buffer */

    tjDecompress2(
        handle, src, srcLen, 
        tmp_dst, *width, 0/*pitch*/, *height, tjPixelFormat, flags
    );
    tjDestroy(handle);

    (*dst) = tmp_dst; // pass dst out
}

void tj_decompress_gray_jpeg_from_mem(
    /*IN*/BYTE *src, unsigned long srcLen,
    /*OUT*/BYTE **dst, unsigned long *dstLen, int *width, int *height, int *components
)
{
    int pixelFormat = TJPF::TJPF_GRAY;
    int flags = TJFLAG_ACCURATEDCT;
    int subsamp,colorspace; // no use for now  (3 TJSAMP::TJSAMP_GRAY, 2 TJCS::TJCS_GRAY)

    tj_decompress_jpeg_from_mem(
        src, srcLen, pixelFormat, flags,
        dst, dstLen, width, height, components, &subsamp, &colorspace
    );
}

void tj_decompress_gray_jpeg_from_file(
    /*IN*/const char* src_filename,
    /*OUT*/BYTE **dst, unsigned long *dstLen, int *width, int *height, int *components
)
{
    // (0) read src memory buffer from file
    std::ifstream ifs(src_filename, std::ios_base::binary | std::ios_base::in);
    ifs.seekg(0, std::ios::end);
    uint64_t srcLen = ifs.tellg();
    ifs.seekg(0, std::ios::beg);

    BYTE *src = new BYTE[srcLen];
    ifs.read((char*)src, srcLen);

    // (2) decompress  
    int pixelFormat = TJPF::TJPF_GRAY;
    int flags = TJFLAG_ACCURATEDCT;
    int subsamp, colorspace; // no use for now  (3 TJSAMP::TJSAMP_GRAY, 2 TJCS::TJCS_GRAY)

    tj_decompress_jpeg_from_mem(
        src, srcLen, pixelFormat, flags,
        dst, dstLen, width, height, components, &subsamp, &colorspace
    );

    // (3) free src memory buffer
    delete[] src;

    // (4) pass out dst buffer 
}


void test_compress()
{
    int width = 2000;
    int height = 1000;
    int channel = 1;

    unsigned long srcLen = width * height * channel;
    unsigned char * src = new unsigned char[srcLen]; // new buffer
    memset(src, 0, srcLen);
    for (int i = 100; i 

Reference

  • example.c
  • building
  • turbo offical doc
  • compress and decompress jpeg
  • opencv imdecode to libjpeg-turbo (good)
  • tjcompress and tjdecompress

History

  • 20180201: created.
  • 20180202: add example code.

Copyright

  • Post author: kezunlin
  • Post link: https://kezunlin.me/post/83828674/
  • Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

windows 10上源码编译libjpeg-turbo和使用教程 | compile and use libjpeg-turbo on windows 10

标签:compress   before   close   signed   col   org   bytes   iostream   https   

原文地址:https://www.cnblogs.com/kezunlin/p/11840754.html


评论


亲,登录后才可以留言!