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

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

compile and use libjpeg-turbo on windows 10

Series

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 FilesNASM 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

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.txt

 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 <iostream>
#include <fstream>
#include <ctime>

#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<jcs.image_height)
    {
        row_pointer[0] = &src[jcs.next_scanline*row_stride];
        jpeg_write_scanlines(&jcs, row_pointer, 1);
    }
    jpeg_finish_compress(&jcs);
    jpeg_destroy_compress(&jcs);

    return true;
}

bool DeompressJPEG(
    /*IN*/BYTE *src, unsigned long srcLen,
    /*OUT*/BYTE **dst, unsigned long *dstLen, int *width, int *height, int *depth
)
{
    // NOTICE: dst space will be created inside.
    struct jpeg_decompress_struct cinfo;
    struct jpeg_error_mgr jerr;

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

    jpeg_mem_src(&cinfo,src,srcLen);
    jpeg_read_header(&cinfo,TRUE);

    jpeg_start_decompress(&cinfo);
    (*width) = cinfo.output_width;
    (*height) = cinfo.output_height;
    (*depth) = cinfo.num_components;
    (*dstLen) = (*width)*(*height)*(*depth);
    BYTE *tmp_dst = new BYTE[*dstLen];

    JSAMPROW row_pointer[1];
    int row_stride = cinfo.image_width*cinfo.num_components;
    while (cinfo.output_scanline<cinfo.output_height)
    {
        row_pointer[0] = &tmp_dst[cinfo.output_scanline*row_stride];
        jpeg_read_scanlines(&cinfo,row_pointer,1);
    }
    jpeg_finish_decompress(&cinfo);
    jpeg_destroy_decompress(&cinfo);
    *dst = tmp_dst;

    return true;
}

void compress_jpeg_to_file(
    /*IN*/BYTE *src,int width, int height, int components, int color_space,int quality,
    /*OUT*/char *dst_filename
)
{
    /* This struct contains the JPEG compression parameters and pointers to
    * working space (which is allocated as needed by the JPEG library).
    * It is possible to have several such structures, representing multiple
    * compression/decompression processes, in existence at once.  We refer
    * to any one struct (and its associated working data) as a "JPEG object".
    */
    struct jpeg_compress_struct cinfo;
    /* This struct represents a JPEG error handler.  It is declared separately
    * because applications often want to supply a specialized error handler
    * (see the second half of this file for an example).  But here we just
    * take the easy way out and use the standard error handler, which will
    * print a message on stderr and call exit() if compression fails.
    * Note that this struct must live as long as the main JPEG parameter
    * struct, to avoid dangling-pointer problems.
    */
    struct jpeg_error_mgr jerr;
    /* More stuff */
    FILE *outfile;                /* target file */
    JSAMPROW row_pointer[1];      /* pointer to JSAMPLE row[s] */
    int row_stride;               /* physical row width in image buffer */

    /* Step 1: allocate and initialize JPEG compression object */

    /* We have to set up the error handler first, in case the initialization
    * step fails.  (Unlikely, but it could happen if you are out of memory.)
    * This routine fills in the contents of struct jerr, and returns jerr's
    * address which we place into the link field in cinfo.
    */
    cinfo.err = jpeg_std_error(&jerr);
    /* Now we can initialize the JPEG compression object. */
    jpeg_create_compress(&cinfo);

    /* Step 2: specify data destination (eg, a file) */
    /* Note: steps 2 and 3 can be done in either order. */

    /* Here we use the library-supplied code to send compressed data to a
    * stdio stream.  You can also write your own code to do something else.
    * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that
    * requires it in order to write binary files.
    */
    if ((outfile = fopen(dst_filename, "wb")) == NULL) {
        fprintf(stderr, "can't open %s\n", dst_filename);
        exit(1);
    }
    jpeg_stdio_dest(&cinfo, outfile);

    /* Step 3: set parameters for compression */

    /* First we supply a description of the input image.
    * Four fields of the cinfo struct must be filled in:
    */
    cinfo.image_width = width;      /* image width and height, in pixels */
    cinfo.image_height = height;
    cinfo.input_components = components;           /* # of color components per pixel */
    cinfo.in_color_space = (J_COLOR_SPACE)color_space;       /* colorspace of input image */
    /* Now use the library's routine to set default compression parameters.
    * (You must set at least cinfo.in_color_spac
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值