Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mini rebase 2024 10 15 #1338

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,8 @@ option(WITH_HEADER_COMPRESSION OFF)
option(ENABLE_MULTITHREADING_SUPPORT "Switch off for platforms without multithreading support" ON)
option(ENABLE_PARALLEL_TILE_DECODING "Will launch multiple decoders to decode tiles in parallel (requires ENABLE_MULTITHREADING_SUPPORT)" ON)

option(WITH_EXPERIMENTAL_MINI_FORMAT "Enable experimental (draft) low-overhead box format (likely reduced interoperability)." OFF)

if (WITH_REDUCED_VISIBILITY)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
else ()
Expand Down
1 change: 1 addition & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"WITH_AOM_ENCODER_PLUGIN" : "OFF",
"WITH_DAV1D" : "ON",
"WITH_DAV1D_PLUGIN" : "OFF",
"WITH_EXPERIMENTAL_MINI_FORMAT" : "ON",
"WITH_LIBDE265" : "ON",
"WITH_LIBDE265_PLUGIN" : "OFF",
"WITH_RAV1E" : "ON",
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,7 @@ to update the gdk-pixbuf loader database.
* [darktable](https://www.darktable.org)
* [digiKam 7.0.0](https://www.digikam.org/)
* [libvips](https://github.com/libvips/libvips)
* [kImageFormats](https://api.kde.org/frameworks/kimageformats/html/index.html)
* [libGD](https://libgd.github.io/)
* [Kodi HEIF image decoder plugin](https://kodi.wiki/view/Add-on:HEIF_image_decoder)
* [bimg](https://github.com/h2non/bimg)
Expand Down
2 changes: 2 additions & 0 deletions go/heif/heif.go
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@ const (

SuberrorNoIcbrBox = C.heif_suberror_No_icbr_box

SuberrorNoMiniBox = C.heif_suberror_No_mini_box

// --- Unsupported_feature ---

// Image was coded with an unsupported compression method.
Expand Down
7 changes: 7 additions & 0 deletions libheif/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,13 @@ if (WITH_UNCOMPRESSED_CODEC)
codecs/uncompressed/decoder_tile_component_interleave.cc)
endif ()

if (WITH_EXPERIMENTAL_MINI_FORMAT)
target_compile_definitions(heif PUBLIC WITH_EXPERIMENTAL_MINI_FORMAT=1)
target_sources(heif PRIVATE
mini.h
mini.cc)
endif ()

write_basic_package_version_file(${PROJECT_NAME}-config-version.cmake COMPATIBILITY ExactVersion)

install(TARGETS heif EXPORT ${PROJECT_NAME}-config
Expand Down
26 changes: 26 additions & 0 deletions libheif/api/libheif/heif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ heif_error heif_has_compatible_filetype(const uint8_t* data, int len)
heif_brand2_miaf,
heif_brand2_mif1,
heif_brand2_mif2
#if WITH_EXPERIMENTAL_MINI_FORMAT
, heif_brand2_mif3
#endif
};

auto it = supported_brands.find(main_brand);
Expand Down Expand Up @@ -302,6 +305,13 @@ heif_brand2 heif_fourcc_to_brand(const char* fourcc_string)
return fourcc(fourcc_string);
}

heif_brand2 heif_read_minor_version_brand(const uint8_t* data, int len)
{
if (len < 16) {
return heif_unknown_brand;
}
return heif_fourcc_to_brand((char*) (data + 12));
}

void heif_brand_to_fourcc(heif_brand2 brand, char* out_fourcc)
{
Expand Down Expand Up @@ -462,6 +472,22 @@ const char* heif_get_file_mime_type(const uint8_t* data, int len)
else if (mainBrand == heif_avis) {
return "image/avif-sequence";
}
#if WITH_EXPERIMENTAL_MINI_FORMAT
else if (mainBrand == heif_brand2_mif3) {
heif_brand2 minorBrand = heif_read_minor_version_brand(data, len);
if (minorBrand == heif_brand2_avif) {
return "image/avif";
}
if (minorBrand == heif_brand2_heic ||
minorBrand == heif_brand2_heix ||
minorBrand == heif_brand2_heim ||
minorBrand == heif_brand2_heis) {
return "image/heic";
}
// There could be other options in here, like VVC or J2K
return "image/heif";
}
#endif
else if (mainBrand == heif_j2ki) {
return "image/hej2k";
}
Expand Down
21 changes: 21 additions & 0 deletions libheif/api/libheif/heif.h
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,9 @@ enum heif_suberror_code

heif_suberror_No_avcC_box = 143,

// we got a mini box, but could not read it properly
heif_suberror_No_mini_box = 149,

// Decompressing generic compression or header compression data failed (e.g. bitstream corruption)
heif_suberror_Decompression_invalid_data = 150,

Expand Down Expand Up @@ -770,6 +773,13 @@ typedef uint32_t heif_brand2;
*/
#define heif_brand2_mif2 heif_fourcc('m','i','f','2')

/**
* HEIF image structural brand (`mif3`).
*
* This indicates the low-overhead (ftyp+mini) structure.
*/
#define heif_brand2_mif3 heif_fourcc('m','i','f','3')

/**
* HEIF image sequence structural brand (`msf1`).
*
Expand Down Expand Up @@ -871,6 +881,10 @@ typedef uint32_t heif_brand2;
LIBHEIF_API
heif_brand2 heif_read_main_brand(const uint8_t* data, int len);

// input data should be at least 16 bytes
LIBHEIF_API
heif_brand2 heif_read_minor_version_brand(const uint8_t* data, int len);

// 'brand_fourcc' must be 4 character long, but need not be 0-terminated
LIBHEIF_API
heif_brand2 heif_fourcc_to_brand(const char* brand_fourcc);
Expand Down Expand Up @@ -1959,6 +1973,13 @@ struct heif_decoded_mastering_display_colour_volume
double min_display_mastering_luminance;
};

struct heif_ambient_viewing_environment
{
uint32_t ambient_illumination;
uint16_t ambient_light_x;
uint16_t ambient_light_y;
};

LIBHEIF_API
int heif_image_has_mastering_display_colour_volume(const struct heif_image*);

Expand Down
1 change: 1 addition & 0 deletions libheif/api/libheif/heif_emscripten.h
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,7 @@ EMSCRIPTEN_BINDINGS(libheif) {
.value("heif_suberror_Missing_grid_images", heif_suberror_Missing_grid_images)
.value("heif_suberror_No_av1C_box", heif_suberror_No_av1C_box)
.value("heif_suberror_No_avcC_box", heif_suberror_No_avcC_box)
.value("heif_suberror_No_mini_box", heif_suberror_No_mini_box)
.value("heif_suberror_Invalid_clean_aperture", heif_suberror_Invalid_clean_aperture)
.value("heif_suberror_Invalid_overlay_data", heif_suberror_Invalid_overlay_data)
.value("heif_suberror_Overlay_image_outside_of_canvas", heif_suberror_Overlay_image_outside_of_canvas)
Expand Down
19 changes: 19 additions & 0 deletions libheif/bitstream.cc
Original file line number Diff line number Diff line change
Expand Up @@ -477,13 +477,32 @@ uint8_t BitReader::get_bits8(int n)
return static_cast<uint8_t>(get_bits(n));
}

uint16_t BitReader::get_bits16(int n)
{
assert(n>0 && n <= 16);
return static_cast<uint16_t>(get_bits(n));
}

uint32_t BitReader::get_bits32(int n)
{
assert(n>0 && n <= 32);
return static_cast<uint32_t>(get_bits(n));
}

bool BitReader::get_flag()
{
return (get_bits(1) == 0x01);
}

std::vector<uint8_t> BitReader::read_bytes(uint32_t n)
{
// TODO: this implementation isn't very efficient
std::vector<uint8_t> bytes;
for (uint32_t i = 0; i < n; i++) {
bytes.push_back(get_bits8(8));
}
return bytes;
}

int BitReader::get_bits_fast(int n)
{
Expand Down
22 changes: 22 additions & 0 deletions libheif/bitstream.h
Original file line number Diff line number Diff line change
Expand Up @@ -381,8 +381,19 @@ class BitReader

uint8_t get_bits8(int n);

uint16_t get_bits16(int n);

uint32_t get_bits32(int n);

/**
* Get a one-bit flag value.
*
* @returns true if the next bit value is 1, otherwise false
*/
bool get_flag();

std::vector<uint8_t> read_bytes(uint32_t n);

int get_bits_fast(int n);

int peek_bits(int n);
Expand All @@ -409,10 +420,21 @@ class BitReader
return ((int64_t) bytes_remaining) * 8 + nextbits_cnt;
}

void set_start_offset(uint64_t offset)
{
start_offset = offset;
}

uint64_t get_file_offset() const
{
return start_offset + (data_length - bytes_remaining - (nextbits_cnt / 8));
}

private:
const uint8_t* data;
int data_length;
int bytes_remaining;
uint64_t start_offset = 0;

uint64_t nextbits; // left-aligned bits
int nextbits_cnt;
Expand Down
Loading