Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
2 / 2
CRAP
100.00% covered (success)
100.00%
1 / 1
ImageParser
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
2 / 2
26
100.00% covered (success)
100.00%
1 / 1
 parse
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
13
 parseString
100.00% covered (success)
100.00%
8 / 8
100.00% covered (success)
100.00%
1 / 1
13
1<?php
2
3declare(strict_types=1);
4
5namespace Phpdftk\ImageMetadata;
6
7use Phpdftk\Filesystem\LocalFilesystem;
8
9/**
10 * Detect image format from magic bytes and delegate to the format-specific parser.
11 *
12 * Extracts only header metadata (dimensions, color space, bit depth) —
13 * never decodes pixel data. This keeps image embedding fast since PDF
14 * can reference the compressed image bytes directly.
15 */
16final class ImageParser
17{
18    public static function parse(string $path): ImageInfo
19    {
20        $data = LocalFilesystem::readPrefix($path, 32, "image file");  // read just enough for signature
21        return match (true) {
22            str_starts_with($data, "\xFF\xD8\xFF") => JpegParser::parseFile($path),
23            str_starts_with($data, "\x89PNG\r\n\x1A\n") => PngParser::parseFile($path),
24            str_starts_with($data, 'GIF87a') || str_starts_with($data, 'GIF89a') => GifParser::parseFile($path),
25            str_starts_with($data, 'II') || str_starts_with($data, 'MM') => TiffParser::parseFile($path),
26            str_starts_with($data, 'RIFF') && substr($data, 8, 4) === 'WEBP' => WebpParser::parseFile($path),
27            str_starts_with($data, "\x00\x00\x00\x0C\x6A\x50\x20\x20") || str_starts_with($data, "\xFF\x4F\xFF\x51") => Jpeg2000Parser::parseFile($path),
28            str_starts_with($data, "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A") => Jbig2Parser::parseFile($path),
29            default => throw new \RuntimeException('Unsupported image format'),
30        };
31    }
32
33    public static function parseString(string $data): ImageInfo
34    {
35        return match (true) {
36            str_starts_with($data, "\xFF\xD8\xFF") => JpegParser::parse($data),
37            str_starts_with($data, "\x89PNG\r\n\x1A\n") => PngParser::parse($data),
38            str_starts_with($data, 'GIF87a') || str_starts_with($data, 'GIF89a') => GifParser::parse($data),
39            str_starts_with($data, 'II') || str_starts_with($data, 'MM') => TiffParser::parse($data),
40            str_starts_with($data, 'RIFF') && substr($data, 8, 4) === 'WEBP' => WebpParser::parse($data),
41            str_starts_with($data, "\x00\x00\x00\x0C\x6A\x50\x20\x20") || str_starts_with($data, "\xFF\x4F\xFF\x51") => Jpeg2000Parser::parse($data),
42            str_starts_with($data, "\x97\x4A\x42\x32\x0D\x0A\x1A\x0A") => Jbig2Parser::parse($data),
43            default => throw new \RuntimeException('Unsupported image format'),
44        };
45    }
46}