diff options
author | Elliott Hughes <enh@google.com> | 2023-12-17 15:55:20 -0800 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2023-12-20 15:00:03 -0600 |
commit | 40e73a3873297040f3d57ffa7e1bebcf43f7a267 (patch) | |
tree | a562b49a35b8a0a688db1c7b306c3169e247beba | |
parent | 25cae192c6156512776de49b5d5569825a6931c5 (diff) | |
download | toybox-40e73a3873297040f3d57ffa7e1bebcf43f7a267.tar.gz |
file: parse JPEG files enough to pull out their size in pixels.
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.)
-rw-r--r-- | toys/posix/file.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/toys/posix/file.c b/toys/posix/file.c index 8bc2b383..30d22495 100644 --- a/toys/posix/file.c +++ b/toys/posix/file.c @@ -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. |