Skip to content

Commit

Permalink
Merge branch 'develop-v1.18.0' into timestamp-properties
Browse files Browse the repository at this point in the history
  • Loading branch information
farindk committed Jan 25, 2024
2 parents 5ceb92f + d08df5d commit 9185352
Show file tree
Hide file tree
Showing 154 changed files with 8,813 additions and 1,185 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/cifuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
fuzz-seconds: 600
dry-run: false
- name: Upload Crash
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
if: failure() && steps.build.outcome == 'success'
with:
name: artifacts
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v4
- uses: actions/setup-go@v5
with:
go-version: "1.10"

Expand Down
113 changes: 111 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.16.3) # Oldest Ubuntu LTS (20.04 currently)

project(libheif LANGUAGES C CXX VERSION 1.17.5)
project(libheif LANGUAGES C CXX VERSION 1.17.6)

# compatibility_version is never allowed to be decreased for any specific SONAME.
# Libtool in the libheif-1.15.1 release had set it to 17.0.0, so we have to use this for the v1.x.y versions.
Expand Down Expand Up @@ -142,6 +142,14 @@ plugin_option(AOM_DECODER "AOM AV1 decoder" ON OFF)
plugin_option(AOM_ENCODER "AOM AV1 encoder" ON OFF)
if (WITH_AOM_ENCODER OR WITH_AOM_DECODER)
find_package(AOM)

# When decoding/encoding is disabled, overwrite the *_FOUND variables, because they are used to ultimately decide what to build.
if (NOT WITH_AOM_DECODER)
set(AOM_DECODER_FOUND FALSE)
endif()
if (NOT WITH_AOM_ENCODER)
set(AOM_ENCODER_FOUND FALSE)
endif()
endif()

# svt
Expand Down Expand Up @@ -181,14 +189,22 @@ if (WITH_FFMPEG_DECODER)
find_package(FFMPEG COMPONENTS avcodec)
endif ()

# openjph

plugin_option(OPENJPH_ENCODER "OpenJPH HT-J2K encoder" OFF ON)
# plugin_option(OPENJPH_DECODER "OpenJPH HT-J2K decoder" OFF ON)
if (WITH_OPENJPH_ENCODER OR WITH_OPENJPH_DECODER)
find_package(OPENJPH)
endif()

# uncompressed

option(WITH_UNCOMPRESSED_CODEC " Support internal ISO/IEC 23001-17 uncompressed codec (experimental) " OFF)


# --- show codec compilation summary

message("=== Summary of compiled codecs ===")
message("\n=== Summary of compiled codecs ===")
plugin_compilation_info(LIBDE265 LIBDE265 "libde265 HEVC decoder")
plugin_compilation_info(FFMPEG_DECODER FFMPEG_avcodec "FFMPEG HEVC decoder (HW acc)")
plugin_compilation_info(X265 X265 "x265 HEVC encoder")
Expand All @@ -202,7 +218,78 @@ plugin_compilation_info(JPEG_DECODER JPEG "JPEG decoder")
plugin_compilation_info(JPEG_ENCODER JPEG "JPEG encoder")
plugin_compilation_info(OpenJPEG_DECODER OpenJPEG "OpenJPEG J2K decoder")
plugin_compilation_info(OpenJPEG_ENCODER OpenJPEG "OpenJPEG J2K encoder")
# plugin_compilation_info(OPENJPH_DECODER OPENJPH "OpenJPH HT-J2K decoder")
plugin_compilation_info(OPENJPH_ENCODER OPENJPH "OpenJPH HT-J2K encoder")

# --- show summary which formats are supported

macro(format_compilation_info formatName decoding_supported encoding_supported)
if (${decoding_supported})
set(decoding "YES")
else()
set(decoding "NO ")
endif()

if (${encoding_supported})
set(encoding "YES")
else()
set(encoding "NO ")
endif()

string(LENGTH "${formatName}" len)
math(EXPR fill "12 - ${len}")
string(SUBSTRING " " 0 ${fill} filler)
message("${formatName}${filler} ${decoding} ${encoding}")
unset(msg)
endmacro()


if (LIBDE265_FOUND OR FFMPEG_avcodec_FOUND)
set(SUPPORTS_HEIC_DECODING TRUE)
endif()
if (X265_FOUND OR KVAZAAR_FOUND)
set(SUPPORTS_HEIC_ENCODING TRUE)
endif()
if (AOM_DECODER_FOUND OR DAV1D_FOUND)
set(SUPPORTS_AVIF_DECODING TRUE)
endif()
if (AOM_ENCODER_FOUND OR RAV1E_FOUND OR SvtEnc_FOUND)
set(SUPPORTS_AVIF_ENCODING TRUE)
endif ()
if (JPEG_FOUND AND WITH_JPEG_DECODER)
set(SUPPORTS_JPEG_DECODING TRUE)
endif()
if (JPEG_FOUND AND WITH_JPEG_ENCODER)
set(SUPPORTS_JPEG_ENCODING TRUE)
endif()
if (OpenJPEG_FOUND AND WITH_OpenJPEG_DECODER)
set(SUPPORTS_J2K_DECODING TRUE)
set(SUPPORTS_J2K_HT_DECODING TRUE)
endif()
if (OpenJPEG_FOUND AND WITH_OpenJPEG_ENCODER)
set(SUPPORTS_J2K_ENCODING TRUE)
endif()
if (OPENJPH_FOUND AND WITH_OPENJPH_ENCODER)
set(SUPPORTS_J2K_HT_ENCODING TRUE)
endif()
if (OPENJPH_FOUND AND WITH_OPENJPH_DECODER)
set(SUPPORTS_J2K_HT_ENCODING TRUE)
endif()

if (WITH_UNCOMPRESSED_CODEC)
set(SUPPORTS_UNCOMPRESSED_DECODING TRUE)
set(SUPPORTS_UNCOMPRESSED_ENCODING TRUE)
endif()

message("\n=== Supported formats ===")
message("format decoding encoding")
format_compilation_info("HEIC" SUPPORTS_HEIC_DECODING SUPPORTS_HEIC_ENCODING)
format_compilation_info("AVIF" SUPPORTS_AVIF_DECODING SUPPORTS_AVIF_ENCODING)
format_compilation_info("JPEG" SUPPORTS_JPEG_DECODING SUPPORTS_JPEG_ENCODING)
format_compilation_info("JPEG2000" SUPPORTS_J2K_DECODING SUPPORTS_J2K_ENCODING)
format_compilation_info("JPEG2000-HT" SUPPORTS_J2K_HT_DECODING SUPPORTS_J2K_HT_ENCODING)
format_compilation_info("Uncompressed" SUPPORTS_UNCOMPRESSED_DECODING SUPPORTS_UNCOMPRESSED_ENCODING)
message("")

# --- Libsharpyuv color space transforms

Expand Down Expand Up @@ -263,6 +350,10 @@ endif()
if (LIBSHARPYUV_FOUND)
list(APPEND REQUIRES_PRIVATE "libsharpyuv")
endif()
if (WITH_DEFLATE_HEADER_COMPRESSION)
list(APPEND REQUIRES_PRIVATE "zlib")
endif()

list(JOIN REQUIRES_PRIVATE " " REQUIRES_PRIVATE)

include(CheckCXXSymbolExists)
Expand Down Expand Up @@ -324,6 +415,24 @@ endif (DOXYGEN_FOUND)

# --- Testing

option(ENABLE_COVERAGE "" OFF)
if(ENABLE_COVERAGE)
# set compiler flags
set(CMAKE_CXX_FLAGS "-O0 -coverage")

# find required tools
find_program(LCOV lcov REQUIRED)
find_program(GENHTML genhtml REQUIRED)

# add coverage target
add_custom_target(coverage
# gather data
COMMAND ${LCOV} --directory . --capture --output-file coverage.info
# generate report
COMMAND ${GENHTML} --demangle-cpp -o coverage coverage.info
WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
endif()

option(BUILD_TESTING "" ON)
include(CTest)
if(BUILD_TESTING)
Expand Down
1 change: 1 addition & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
"WITH_KVAZAAR" : "ON",
"WITH_OpenJPEG_DECODER" : "ON",
"WITH_OpenJPEG_ENCODER" : "ON",
"WITH_OPENJPH_ENCODER" : "ON",
"WITH_FFMPEG_DECODER" : "ON",
"WITH_REDUCED_VISIBILITY" : "OFF",
"WITH_DEFLATE_HEADER_COMPRESSION" : "ON",
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ Supported codecs:
## API

The library has a C API for easy integration and wide language support.
Note that the API is still work in progress and may still change.

The decoder automatically supports both HEIF and AVIF through the same API. No changes are required to existing code to support AVIF.
The encoder can be switched between HEIF and AVIF simply by setting `heif_compression_HEVC` or `heif_compression_AV1`
Expand Down Expand Up @@ -155,7 +154,7 @@ For each codec, there are two configuration variables:
* `WITH_{codec}_PLUGIN`: when enabled, the codec is compiled as a separate plugin.

In order to use dynamic plugins, also make sure that `ENABLE_PLUGIN_LOADING` is enabled.
The placeholder `{codec}` can have these values: `LIBDE265`, `X265`, `AOM_DECODER`, `AOM_ENCODER`, `SvtEnc`, `DAV1D`, `FFMPEG_DECODER`, `JPEG_DECODER`, `JPEG_ENCODER`, `KVAZAAR`, `OpenJPEG_DECODER`, `OpenJPEG_ENCODER`.
The placeholder `{codec}` can have these values: `LIBDE265`, `X265`, `AOM_DECODER`, `AOM_ENCODER`, `SvtEnc`, `DAV1D`, `FFMPEG_DECODER`, `JPEG_DECODER`, `JPEG_ENCODER`, `KVAZAAR`, `OpenJPEG_DECODER`, `OpenJPEG_ENCODER`, `OPENJPH_ENCODER`

Further options are:

Expand Down
24 changes: 24 additions & 0 deletions cmake/modules/FindOPENJPH.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
include(LibFindMacros)
libfind_pkg_check_modules(OPENJPH_PKGCONF openjph)

find_path(OPENJPH_INCLUDE_DIR
NAMES openjph/ojph_version.h
HINTS ${OPENJPH_PKGCONF_INCLUDE_DIRS} ${OPENJPH_PKGCONF_INCLUDEDIR}
PATH_SUFFIXES OPENJPH
)

find_library(OPENJPH_LIBRARY
NAMES libopenjph openjph
HINTS ${OPENJPH_PKGCONF_LIBRARY_DIRS} ${OPENJPH_PKGCONF_LIBDIR}
)

set(OPENJPH_PROCESS_LIBS OPENJPH_LIBRARY)
set(OPENJPH_PROCESS_INCLUDES OPENJPH_INCLUDE_DIR)
libfind_process(OPENJPH)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OPENJPH
REQUIRED_VARS
OPENJPH_INCLUDE_DIR
OPENJPH_LIBRARY
)
22 changes: 21 additions & 1 deletion examples/encoder_jpeg.cc
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <string.h>

#include <vector>
#include <limits>

#include "encoder_jpeg.h"
#include "libheif/exif.h"
Expand Down Expand Up @@ -176,13 +177,30 @@ bool JpegEncoder::Encode(const struct heif_image_handle* handle,
static const uint8_t kExifMarker = JPEG_APP0 + 1;

uint32_t skip = (exifdata[0]<<24) | (exifdata[1]<<16) | (exifdata[2]<<8) | exifdata[3];
if (skip > (exifsize - 4)) {
fprintf(stderr, "Invalid EXIF data (offset too large)\n");
free(exifdata);
jpeg_destroy_compress(&cinfo);
fclose(fp);
return false;
}
skip += 4;

uint8_t* ptr = exifdata + skip;
size_t size = exifsize - skip;

if (size > std::numeric_limits<uint32_t>::max()) {
fprintf(stderr, "EXIF larger than 4GB is not supported");
free(exifdata);
jpeg_destroy_compress(&cinfo);
fclose(fp);
return false;
}

auto size32 = static_cast<uint32_t>(size);

// libheif by default normalizes the image orientation, so that we have to set the EXIF Orientation to "Horizontal (normal)"
modify_exif_orientation_tag_if_it_exists(ptr, (int)size, 1);
modify_exif_orientation_tag_if_it_exists(ptr, size32, 1);

// We have to limit the size for the memcpy, otherwise GCC warns that we exceed the maximum size.
if (size>0x1000000) {
Expand Down Expand Up @@ -246,6 +264,8 @@ bool JpegEncoder::Encode(const struct heif_image_handle* handle,

if (heif_image_get_bits_per_pixel(image, heif_channel_Y) != 8) {
fprintf(stderr, "JPEG writer cannot handle image with >8 bpp.\n");
jpeg_destroy_compress(&cinfo);
fclose(fp);
return false;
}

Expand Down
15 changes: 8 additions & 7 deletions examples/encoder_png.cc
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,16 @@ bool PngEncoder::Encode(const struct heif_image_handle* handle,
if (exifdata) {
if (exifsize > 4) {
uint32_t skip = (exifdata[0]<<24) | (exifdata[1]<<16) | (exifdata[2]<<8) | exifdata[3];
skip += 4;
if (skip < (exifsize - 4)) {
skip += 4;
uint8_t* ptr = exifdata + skip;
size_t size = exifsize - skip;

uint8_t* ptr = exifdata + skip;
size_t size = exifsize - skip;
// libheif by default normalizes the image orientation, so that we have to set the EXIF Orientation to "Horizontal (normal)"
modify_exif_orientation_tag_if_it_exists(ptr, (int)size, 1);

// libheif by default normalizes the image orientation, so that we have to set the EXIF Orientation to "Horizontal (normal)"
modify_exif_orientation_tag_if_it_exists(ptr, (int)size, 1);

png_set_eXIf_1(png_ptr, info_ptr, (png_uint_32)size, ptr);
png_set_eXIf_1(png_ptr, info_ptr, (png_uint_32)size, ptr);
}
}

free(exifdata);
Expand Down
8 changes: 6 additions & 2 deletions examples/heif-info.1
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ heif-info \- show information on HEIC/HEIF file
.B heif-info
[\fB\-d\fR|\fB--dump-boxes\fR]
[\fB\-h\fR|\fB--help\fR]
[\fB\-v\fR|\fB--version\fR]
.IR filename
.SH DESCRIPTION
.B heif-info
Expand All @@ -14,8 +15,11 @@ Show information on HEIC/HEIF file.
.BR \-d ", " \-\-dump-boxes\fR
Show a low-level dump of all MP4 file boxes.
.TP
.BR \-help ", " \-\-help\fR
Show help.
.BR \-h ", " \-\-help\fR
Show help. A filename is not required or used.
.TP
.BR \-v ", " \-\-version\fR
Show version information for the tool, library version, and the plugin path. A filename is not required or used.
.SH EXIT STATUS
.PP
\fB0\fR
Expand Down
3 changes: 3 additions & 0 deletions examples/heif_convert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ void list_all_decoders()
std::cout << "JPEG 2000 decoders:\n";
list_decoders(heif_compression_JPEG2000);

std::cout << "HT-J2K decoders:\n";
list_decoders(heif_compression_HTJ2K);

#if WITH_UNCOMPRESSED_CODEC
std::cout << "uncompressed: yes\n";
#else
Expand Down
Loading

0 comments on commit 9185352

Please sign in to comment.