Skip to content

Commit

Permalink
Merge branch 'bradh-compatible_brands_2024-04-02' into develop-v1.18.0
Browse files Browse the repository at this point in the history
  • Loading branch information
farindk committed Jun 11, 2024
2 parents 17add3f + 6f9a093 commit 2d2c1cc
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 15 deletions.
30 changes: 16 additions & 14 deletions examples/heif_convert.cc
Original file line number Diff line number Diff line change
Expand Up @@ -380,27 +380,29 @@ int main(int argc, char** argv)
// TODO: check, whether reading from named pipes works at all.

std::ifstream istr(input_filename.c_str(), std::ios_base::binary);
uint8_t magic[12];
istr.read((char*) magic, 12);

if (heif_check_jpeg_filetype(magic, 12)) {
fprintf(stderr, "Input file '%s' is a JPEG image\n", input_filename.c_str());
std::array<uint8_t,4> length{};
istr.read((char*) length.data(), length.size());
uint32_t box_size = (length[0] << 24) + (length[1] << 16) + (length[2] << 8) + (length[3]);
if ((box_size < 16) || (box_size > 512)) {
fprintf(stderr, "Input file does not appear to start with a valid box length.");
if ((box_size & 0xFFFFFFF0) == 0xFFD8FFE0) {
fprintf(stderr, " Possibly could be a JPEG file instead.\n");
} else {
fprintf(stderr, "\n");
}
return 1;
}

enum heif_filetype_result filetype_check = heif_check_filetype(magic, 12);
if (filetype_check == heif_filetype_no) {
fprintf(stderr, "Input file is not an HEIF/AVIF file\n");
return 1;
}
std::vector<uint8_t> ftyp_bytes(box_size);
std::copy(length.begin(), length.end(), ftyp_bytes.begin());
istr.read((char*) ftyp_bytes.data() + 4, ftyp_bytes.size() - 4);

if (filetype_check == heif_filetype_yes_unsupported) {
fprintf(stderr, "Input file is an unsupported HEIF/AVIF file type\n");
heif_error filetype_check = heif_has_compatible_filetype(ftyp_bytes.data(), (int)ftyp_bytes.size());
if (filetype_check.code != heif_error_Ok) {
fprintf(stderr, "Input file is not a supported format. %s\n", filetype_check.message);
return 1;
}



// --- read the HEIF file

struct heif_context* ctx = heif_context_alloc();
Expand Down
44 changes: 43 additions & 1 deletion libheif/heif.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,48 @@ heif_filetype_result heif_check_filetype(const uint8_t* data, int len)
}


heif_error heif_has_compatible_filetype(const uint8_t* data, int len)
{
// Get compatible brands first, because that does validity checks
heif_brand2* compatible_brands = nullptr;
int nBrands = 0;
struct heif_error err = heif_list_compatible_brands(data, len, &compatible_brands, &nBrands);
if (err.code) {
return err;
}

heif_brand2 main_brand = heif_read_main_brand(data, len);

std::set<heif_brand2> supported_brands{
heif_brand2_avif,
heif_brand2_heic,
heif_brand2_heix,
heif_brand2_j2ki,
heif_brand2_jpeg,
heif_brand2_miaf,
heif_brand2_mif1,
heif_brand2_mif2
};

auto it = supported_brands.find(main_brand);
if (it != supported_brands.end()) {
heif_free_list_of_compatible_brands(compatible_brands);
return heif_error_ok;
}

for (int i = 0; i < nBrands; i++) {
heif_brand2 compatible_brand = compatible_brands[i];
it = supported_brands.find(compatible_brand);
if (it != supported_brands.end()) {
heif_free_list_of_compatible_brands(compatible_brands);
return heif_error_ok;
}
}
heif_free_list_of_compatible_brands(compatible_brands);
return {heif_error_Invalid_input, heif_suberror_Unsupported_image_type, "No supported brands found."};;
}


int heif_check_jpeg_filetype(const uint8_t* data, int len)
{
if (len < 12 || data == nullptr) {
Expand Down Expand Up @@ -318,7 +360,7 @@ struct heif_error heif_list_compatible_brands(const uint8_t* data, int len, heif

auto ftyp = std::dynamic_pointer_cast<Box_ftyp>(box);
if (!ftyp) {
return {heif_error_Invalid_input, heif_suberror_No_ftyp_box, "input is no ftyp box"};
return {heif_error_Invalid_input, heif_suberror_No_ftyp_box, "input is not a ftyp box"};
}

auto brands = ftyp->list_brands();
Expand Down
12 changes: 12 additions & 0 deletions libheif/heif.h
Original file line number Diff line number Diff line change
Expand Up @@ -575,6 +575,18 @@ enum heif_filetype_result
LIBHEIF_API
enum heif_filetype_result heif_check_filetype(const uint8_t* data, int len);

/**
* Check the filetype box content for a supported file type.
*
* <p>The data is assumed to start from the start of the `ftyp` box.
*
* <p>This function checks the compatible brands.
*
* @returns heif_error_ok if a supported brand is found, or other error if not.
*/
LIBHEIF_API
struct heif_error heif_has_compatible_filetype(const uint8_t* data, int len);

LIBHEIF_API
int heif_check_jpeg_filetype(const uint8_t* data, int len);

Expand Down

0 comments on commit 2d2c1cc

Please sign in to comment.