Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,18 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
# External dependencies
set(EXTERNALPROJECT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

option(USE_SYSTEM_LIBS "Use system-provided libraries" OFF)

option(USE_SYSTEM_ZLIB "Use system-provided ZLib library" OFF)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.zlib.cmake)

option(USE_SYSTEM_YATO "Use system-provided Yato library" OFF)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.yato.cmake)

option(USE_SYSTEM_LIBJPEG "Use system-provided LibJPEG library" OFF)
option(FREEIMAGE_WITH_LIBJPEG "Compile with the LibJPEG backend" ON)
option(FREEIMAGE_WITH_LIBJPEG_TRANSFORMS "LibJPEG lossless transforms" ON)

if (FREEIMAGE_WITH_LIBJPEG)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.jpeg.cmake)
endif()
Expand All @@ -44,31 +52,37 @@ if (FREEIMAGE_WITH_LIBOPENJPEG)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.openjpeg.cmake)
endif()

option(USE_SYSTEM_LIBOPENEXR "Use system-provided OpenEXR library" OFF)
option(FREEIMAGE_WITH_LIBOPENEXR "Compile with the LibOpenEXR backend" ON)
if (FREEIMAGE_WITH_LIBOPENEXR)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.openexr.cmake)
endif()

option(USE_SYSTEM_LIBPNG "Use system-provided LibPNG library" OFF)
option(FREEIMAGE_WITH_LIBPNG "Compile with the LibPNG backend" ON)
if (FREEIMAGE_WITH_LIBPNG)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.png.cmake)
endif()

option(USE_SYSTEM_LIBTIFF "Use system-provided LibTIFF library" OFF)
option(FREEIMAGE_WITH_LIBTIFF "Compile with the LibTIFF backend" ON)
if (FREEIMAGE_WITH_LIBTIFF)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.tiff.cmake)
endif()

option(USE_SYSTEM_LIBWEBP "Use system-provided LibWEBP library" OFF)
option(FREEIMAGE_WITH_LIBWEBP "Compile with the LibWEBP backend" ON)
if (FREEIMAGE_WITH_LIBWEBP)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.webp.cmake)
endif()

option(USE_SYSTEM_LIBRAW "Use system-provided LibRAW library" OFF)
option(FREEIMAGE_WITH_LIBRAW "Compile with the LibRAW backend" ON)
if (FREEIMAGE_WITH_LIBRAW)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.raw.cmake)
endif()

option(USE_SYSTEM_LIBHEIF "Use system-provided LibHEIF library" OFF)
option(FREEIMAGE_WITH_LIBHEIF "Compile with the LibHEIF backend" ON)
if (FREEIMAGE_WITH_LIBHEIF)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.heif.cmake)
Expand Down
3 changes: 3 additions & 0 deletions Source/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@ endif()

if (FREEIMAGE_WITH_LIBJPEG)
target_compile_definitions(FreeImage PUBLIC "-DFREEIMAGE_WITH_LIBJPEG=1")
if (FREEIMAGE_WITH_LIBJPEG_TRANSFORMS)
target_compile_definitions(FreeImage PUBLIC "-DFREEIMAGE_WITH_LIBJPEG_TRANSFORMS=1")
endif()
target_link_libraries(FreeImage PRIVATE LibJPEG)
list(APPEND freeimage_plugins Plugins/PluginJPEG.cpp)
endif()
Expand Down
5 changes: 3 additions & 2 deletions Source/FreeImage/ZLibInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
#include "zlib.h"
#include "FreeImage.h"
#include "Utilities.h"
#include "zutil.h" /* must be the last header because of error C3163 in VS2008 (_vsnprintf defined in stdio.h) */

constexpr uint8_t GZIP_OS_UNKNOWN = 255;

/**
Compresses a source buffer into a target buffer, using the ZLib library.
Expand Down Expand Up @@ -115,7 +116,7 @@ FreeImage_ZLibGZip(uint8_t *target, uint32_t target_size, uint8_t *source, uint3
return 0;
case Z_OK: {
// patch header, setup crc and length (stolen from mod_trace_output)
uint8_t *p = target + 8; *p++ = 2; *p = OS_CODE; // xflags, os_code
uint8_t *p = target + 8; *p++ = 2; *p = GZIP_OS_UNKNOWN; // xflags, os_code
crc = crc32(crc, source, source_size);
memcpy(target + 4 + dest_len, &crc, 4);
memcpy(target + 8 + dest_len, &source_size, 4);
Expand Down
11 changes: 9 additions & 2 deletions Source/FreeImageToolkit/JPEGTransform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,15 @@ extern "C" {
#undef FAR
#include <setjmp.h>

#include "jinclude.h"
#include <cstddef>
#include <cstdio>
#include "jpeglib.h"
#include "jerror.h"

#if FREEIMAGE_WITH_LIBJPEG_TRANSFORMS
#include "transupp.h"
#endif // FREEIMAGE_WITH_LIBJPEG_TRANSFORMS

}

#endif // FREEIMAGE_WITH_LIBJPEG
Expand Down Expand Up @@ -154,6 +159,7 @@ getCropString(char* crop, size_t cropSize, int* left, int* top, int* right, int*
return TRUE;
}

#if FREEIMAGE_WITH_LIBJPEG_TRANSFORMS
static FIBOOL
JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, FIBOOL perfect) {
const FIBOOL onlyReturnCropRect = (!dst_io || !dst_handle);
Expand Down Expand Up @@ -368,13 +374,14 @@ JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO*
return TRUE;
}

#else // FREEIMAGE_WITH_LIBJPEG
#else // FREEIMAGE_WITH_LIBJPEG_TRANSFORMS

static FIBOOL
JPEGTransformFromHandle(FreeImageIO*, fi_handle, FreeImageIO*, fi_handle, FREE_IMAGE_JPEG_OPERATION, int*, int*, int*, int*, FIBOOL) {
return FALSE;
}

#endif // FREEIMAGE_WITH_LIBJPEG_TRANSFORMS
#endif // FREEIMAGE_WITH_LIBJPEG

// ----------------------------------------------------------
Expand Down
117 changes: 2 additions & 115 deletions Source/Plugins/PluginJPEG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ extern "C" {
#undef FAR
#include <setjmp.h>

#include "jinclude.h"
#include <cstddef>
#include <cstdio>
#include "jpeglib.h"
#include "jerror.h"
#include "jversion.h"
#include "jmorecfg.h"
}

Expand Down Expand Up @@ -483,119 +483,6 @@ marker_is_icc(jpeg_saved_marker_ptr marker) {
return FALSE;
}

#ifndef JPEG_HAS_READ_ICC_PROFILE
/**
See if there was an ICC profile in the JPEG file being read;
if so, reassemble and return the profile data.

TRUE is returned if an ICC profile was found, FALSE if not.
If TRUE is returned, *icc_data_ptr is set to point to the
returned data, and *icc_data_len is set to its length.

IMPORTANT: the data at **icc_data_ptr has been allocated with malloc()
and must be freed by the caller with free() when the caller no longer
needs it. (Alternatively, we could write this routine to use the
IJG library's memory allocator, so that the data would be freed implicitly
at jpeg_finish_decompress() time. But it seems likely that many apps
will prefer to have the data stick around after decompression finishes.)

NOTE: if the file contains invalid ICC APP2 markers, we just silently
return FALSE. You might want to issue an error message instead.
*/
static FIBOOL
jpeg_read_icc_profile(j_decompress_ptr cinfo, JOCTET **icc_data_ptr, unsigned *icc_data_len) {
jpeg_saved_marker_ptr marker;
int num_markers = 0;
int seq_no;
unsigned total_length;

const int MAX_SEQ_NO = 255; // sufficient since marker numbers are bytes
uint8_t marker_present[MAX_SEQ_NO+1]; // 1 if marker found
unsigned data_length[MAX_SEQ_NO+1]; // size of profile data in marker
unsigned data_offset[MAX_SEQ_NO+1]; // offset for data in marker

*icc_data_ptr = nullptr; // avoid confusion if FALSE return
*icc_data_len = 0;

/**
this first pass over the saved markers discovers whether there are
any ICC markers and verifies the consistency of the marker numbering.
*/

memset(marker_present, 0, (MAX_SEQ_NO + 1));

for (marker = cinfo->marker_list; marker; marker = marker->next) {
if (marker_is_icc(marker)) {
if (num_markers == 0) {
// number of markers
num_markers = GETJOCTET(marker->data[13]);
}
else if (num_markers != GETJOCTET(marker->data[13])) {
return FALSE; // inconsistent num_markers fields
}
// sequence number
seq_no = GETJOCTET(marker->data[12]);
if (seq_no <= 0 || seq_no > num_markers) {
return FALSE; // bogus sequence number
}
if (marker_present[seq_no]) {
return FALSE; // duplicate sequence numbers
}
marker_present[seq_no] = 1;
data_length[seq_no] = marker->data_length - ICC_HEADER_SIZE;
}
}

if (num_markers == 0)
return FALSE;

/**
check for missing markers, count total space needed,
compute offset of each marker's part of the data.
*/

total_length = 0;
for (seq_no = 1; seq_no <= num_markers; seq_no++) {
if (marker_present[seq_no] == 0) {
return FALSE; // missing sequence number
}
data_offset[seq_no] = total_length;
total_length += data_length[seq_no];
}

if (total_length <= 0) {
return FALSE; // found only empty markers ?
}

// allocate space for assembled data
std::unique_ptr<JOCTET, decltype(&free)> icc_data(static_cast<JOCTET*>(malloc(total_length * sizeof(JOCTET))), &free);
if (!icc_data) {
return FALSE; // out of memory
}

// and fill it in
for (marker = cinfo->marker_list; marker; marker = marker->next) {
if (marker_is_icc(marker)) {
JOCTET FAR *src_ptr;
JOCTET *dst_ptr;
unsigned length;
seq_no = GETJOCTET(marker->data[12]);
dst_ptr = icc_data.get() + data_offset[seq_no];
src_ptr = marker->data + ICC_HEADER_SIZE;
length = data_length[seq_no];
while (length--) {
*dst_ptr++ = *src_ptr++;
}
}
}

*icc_data_ptr = icc_data.release();
*icc_data_len = total_length;

return TRUE;
}
#endif

/**
Read JPEG_APPD marker (IPTC or Adobe Photoshop profile)
*/
Expand Down
38 changes: 34 additions & 4 deletions Source/Plugins/PluginWebP.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,26 @@
#include "webp/decode.h"
#include "webp/encode.h"
#include "webp/mux.h"
#include "dec/vp8i_dec.h"

#include <cstdio>

struct WebPVersion {
uint32_t major;
uint32_t minor;
uint32_t patch;
};

static WebPVersion GetWebPVersion() {
static char version[32];

const uint32_t v = WebPGetDecoderVersion();

return {
(v >> 16) & 0xff,
(v >> 8) & 0xff,
v & 0xff
};
}

// ==========================================================
// Plugin Interface
Expand Down Expand Up @@ -681,11 +700,22 @@ InitWEBP(Plugin *plugin, int format_id) {


const FIDEPENDENCY* GetWebpDependencyInfo() {
static char fullVersion[32];

const auto version = GetWebPVersion();

std::snprintf(fullVersion, sizeof(fullVersion),
"LibWebP v%d.%d.%d",
version.major,
version.minor,
version.patch);

static const FIDEPENDENCY info = {
.name = "LibWebP",
.fullVersion = "LibWebP v" FI_QUOTE(DEC_MAJ_VERSION) "." FI_QUOTE(DEC_MIN_VERSION) "." FI_QUOTE(DEC_REV_VERSION),
.majorVersion = DEC_MAJ_VERSION,
.minorVersion = DEC_MIN_VERSION
.fullVersion = fullVersion,
.majorVersion = version.major,
.minorVersion = version.minor
};

return &info;
}
9 changes: 7 additions & 2 deletions cmake/dependency.heif.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,20 @@
#
# Output target: LibHEIF

set(HEIF_VERSION "1.20.2")

if (USE_SYSTEM_LIBHEIF OR USE_SYSTEM_LIBS)
find_package(libheif REQUIRED CONFIG)
add_library(LibHEIF ALIAS heif)
return()
endif()

include(${EXTERNALPROJECT_INCLUDE_DIR}/external_project_common.cmake)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.de265.cmake)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.kvazaar.cmake)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.dav1d.cmake)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.svtav1.cmake)

set(HEIF_VERSION "1.20.2")

ExternalProject_Add(HEIF
PREFIX ${EXTERNALPROJECT_BINARY_ROOT}/heif
URL "https://github.com/strukturag/libheif/releases/download/v${HEIF_VERSION}/libheif-${HEIF_VERSION}.tar.gz"
Expand Down
7 changes: 6 additions & 1 deletion cmake/dependency.jpeg.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
#
# Output target: LibJPEG

if (USE_SYSTEM_LIBJPEG OR USE_SYSTEM_LIBS)
find_package(JPEG REQUIRED)
add_library(LibJPEG ALIAS JPEG::JPEG)
return()
endif()

include(${EXTERNALPROJECT_INCLUDE_DIR}/external_project_common.cmake)


Expand Down Expand Up @@ -71,7 +77,6 @@ elseif(JPEG_REPOSITORY STREQUAL "JPEG-turbo")
else()
target_link_libraries(LibJPEG INTERFACE ${INSTALL_DIR}/lib/libturbojpeg${CMAKE_STATIC_LIBRARY_SUFFIX})
endif()
target_compile_options(LibJPEG INTERFACE "-DJPEG_HAS_READ_ICC_PROFILE=1")
target_include_directories(LibJPEG INTERFACE ${INSTALL_DIR}/include)
set_property(TARGET TURBOJPEG PROPERTY FOLDER "Dependencies")

Expand Down
5 changes: 5 additions & 0 deletions cmake/dependency.openexr.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
# Output target: LibOpenEXR
#

if (USE_SYSTEM_LIBOPENEXR OR USE_SYSTEM_LIBS)
find_package(OpenEXR REQUIRED CONFIG)
add_library(LibOpenEXR ALIAS OpenEXR::OpenEXR)
return()
endif()

include(${EXTERNALPROJECT_INCLUDE_DIR}/external_project_common.cmake)
include(${EXTERNALPROJECT_INCLUDE_DIR}/dependency.openjph.cmake)
Expand Down
5 changes: 5 additions & 0 deletions cmake/dependency.png.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
#
# Output target: LibPNG

if (USE_SYSTEM_LIBPNG OR USE_SYSTEM_LIBS)
find_package(PNG)
add_library(LibPNG ALIAS PNG::PNG)
return()
endif()

include(${EXTERNALPROJECT_INCLUDE_DIR}/external_project_common.cmake)

Expand Down
6 changes: 6 additions & 0 deletions cmake/dependency.raw.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@
#
# Output target: LibRAW

if (USE_SYSTEM_LIBRAW OR USE_SYSTEM_LIBS)
find_package(PkgConfig)
pkg_check_modules(LIBRAW REQUIRED IMPORTED_TARGET libraw)
add_library(LibRAW ALIAS PkgConfig::LIBRAW)
return()
endif()

include(${EXTERNALPROJECT_INCLUDE_DIR}/external_project_common.cmake)

Expand Down
Loading