Skip to content

Commit

Permalink
file: parse JPEG files enough to pull out their size in pixels.
Browse files Browse the repository at this point in the history
This doesn't handle refilling toybuf in the case where there's so
much EXIF data before the header we're looking for that we hit the
end of toybuf first. (In part because I couldn't decide whether to
do that or switch to a scheme where we only ever lseek() around,
reading big-endian shorts.)
  • Loading branch information
enh-google authored and landley committed Dec 20, 2023
1 parent 25cae19 commit 40e73a3
Showing 1 changed file with 17 additions and 3 deletions.
20 changes: 17 additions & 3 deletions toys/posix/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -244,10 +244,24 @@ static void do_regular_file(int fd, char *name)
xprintf("GIF image data, version %3.3s, %d x %d\n",
s-3, (int)peek_le(s, 2), (int)peek_le(s+2, 2));

// TODO: parsing JPEG for width/height is harder than GIF or PNG.
else if (len>32 && !smemcmp(s, "\xff\xd8", 2)) xputs("JPEG image data");
// https://en.wikipedia.org/wiki/JPEG#Syntax_and_structure
else if (len>32 && !smemcmp(s, "\xff\xd8", 2)) {
char *types[] = {"baseline", "extended sequential", "progressive"};
int marker;

printf("JPEG image data");
while (s < toybuf+len-8) { // TODO: refill for files with lots of EXIF data?
marker = peek_be(s, 2);
if (marker >= 0xffd0 && marker <= 0xffd9) s += 2; // No data.
else if (marker >= 0xffc0 && marker <= 0xffc2) {
xprintf(", %s, %dx%d", types[marker-0xffc0], (int) peek_be(s+7, 2),
(int) peek_be(s+5, 2));
break;
} else s += peek_be(s + 2, 2) + 2;
}
xputc('\n');

else if (len>8 && strstart(&s, "\xca\xfe\xba\xbe")) {
} else if (len>8 && strstart(&s, "\xca\xfe\xba\xbe")) {
unsigned count = peek_be(s, 4), i, arch;

// 0xcafebabe can be a Java class file or a Mach-O universal binary.
Expand Down

0 comments on commit 40e73a3

Please sign in to comment.