Skip to content

Commit

Permalink
Make a bit more effort trying to find acTL apng header.
Browse files Browse the repository at this point in the history
Previously was too simplistic and essentially assumed it to be at
a particular location. Now, iterate through the headers until we
find it ... within the first kilobyte.
  • Loading branch information
hzeller committed Jul 20, 2024
1 parent ffa17ae commit 85b31d3
Showing 1 changed file with 14 additions and 6 deletions.
20 changes: 14 additions & 6 deletions src/image-source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

#include "image-source.h"

// Various implementations we try in the constructor
#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <math.h>
Expand Down Expand Up @@ -297,12 +297,20 @@ static bool HasAPNGHeader(const std::string &filename) {
// well, let's assume it is just after IHDR.
int fd = open(filename.c_str(), O_RDONLY);
if (fd < 0) return false;
char actl_sig[4] = {};
static constexpr int kPngHeaderLen = 8;
static constexpr int kPngIHDRLen = 8 + 13 + 4;
const ssize_t len = pread(fd, actl_sig, 4, kPngHeaderLen + kPngIHDRLen + 4);
// Iterate through headers until we find some acTL one.
static constexpr size_t kPngHeaderLen = 8;
size_t pos = kPngHeaderLen;
uint8_t buf[8];
bool found_actl_header = false;
while (!found_actl_header && pos < 1024) {
const ssize_t len = pread(fd, buf, 8, pos);
if (len < 0 || len != 8) break; // Best effort.
found_actl_header = (memcmp(buf + 4, "acTL", 4) == 0);
// Header contains data length; add sizeof() for len, CRC, and ChunkType
pos += ntohl(*(uint32_t*)buf) + 12;
}
close(fd);
return len == 4 && memcmp(actl_sig, "acTL", 4) == 0;
return found_actl_header;
}

bool ImageSource::LooksLikeAPNG(const std::string &filename) {
Expand Down

0 comments on commit 85b31d3

Please sign in to comment.