X-Git-Url: http://git.shiar.net/sheet.git/blobdiff_plain/1676865de8be5f051b97cc3d4b4fcc959732d3ef..8f768b6ed17048f182cde20a621758cdbd3b72bb:/codec.inc.pl diff --git a/codec.inc.pl b/codec.inc.pl index 925c2fe..92e17d5 100644 --- a/codec.inc.pl +++ b/codec.inc.pl @@ -5,6 +5,10 @@ codec => { name => 'JPEG', available => 1992, }, + gif => { + name => 'GIF', + available => 1987, + }, png => { name => 'PNG', available => 1996, @@ -29,15 +33,21 @@ codec => { name => 'JPEG XL', available => 2021, }, + pnm => { + name => 'PNM', + available => 1988, + }, }, feature => { default => { - children => [qw( quality_photo quality_art speed limits features royalties )], + children => [qw( quality_photo quality_art speed limits features royalties overhead support )], }, quality_photo => { name => 'compression (photo)', score => { jpeg => 3, + pnm => 'n', + gif => 1, png => 1, jp2k => 4, webp => 3, @@ -49,15 +59,17 @@ feature => { }, quality_photo_1 => { parent => 'quality_photo', - name => 'low fidelity', + name => 'thumbnails', score => { jpeg => 2, + pnm => 1, + gif => 1, png => 1, jp2k => 3, - webp => 3, + webp => 4, heic => 5, avif => 5, - jxl => 4, + jxl => 3, }, }, quality_photo_2 => { @@ -65,6 +77,8 @@ feature => { name => 'medium fidelity', score => { jpeg => 3, + pnm => 1, + gif => 1, png => 1, jp2k => 4, webp => 3, @@ -78,6 +92,8 @@ feature => { name => 'high fidelity', score => { jpeg => 3, + pnm => 1, + gif => 1, png => 2, jp2k => 4, webp => 2, @@ -91,6 +107,8 @@ feature => { name => 'lossless', score => { jpeg => 1, + pnm => 1, + gif => 1, png => 2, jp2k => 4, webp => 3, @@ -103,6 +121,8 @@ feature => { name => 'compression (other images)', score => { jpeg => 2, + pnm => 'n', + gif => 1, png => 3, jp2k => 2, webp => 4, @@ -116,6 +136,8 @@ feature => { name => 'lossy non-photographic', score => { jpeg => 2, + pnm => 1, + gif => 2, png => 3, jp2k => 2, webp => 4, @@ -128,6 +150,8 @@ feature => { name => 'lossless non-photographic', score => { jpeg => 1, + pnm => 1, + gif => 1, png => 4, jp2k => 2, webp => 5, @@ -140,6 +164,8 @@ feature => { name => 'mixed photo/nonphoto', score => { jpeg => 2, + pnm => 1, + gif => 1, png => 2, jp2k => 2, webp => 3, @@ -151,6 +177,8 @@ feature => { speed => { score => { jpeg => 5, + pnm => 5, + gif => 4, png => 4, jp2k => 3, webp => 4, @@ -165,6 +193,8 @@ feature => { name => 'single-core encode', score => { jpeg => 5, + pnm => 0, + gif => 3, # palette conversion png => 3, jp2k => 4, webp => 4, @@ -178,6 +208,8 @@ feature => { name => 'single-core decode', score => { jpeg => 5, + pnm => 0, + gif => 5, png => 5, jp2k => 4, webp => 5, @@ -191,6 +223,8 @@ feature => { name => 'pararellizable', score => { jpeg => 2, + pnm => 0, + gif => 2, png => 2, jp2k => 4, webp => 2, @@ -202,6 +236,8 @@ feature => { limits => { score => { jpeg => 3, + pnm => 3, + gif => 2, png => 4, jp2k => 5, webp => 2, @@ -215,57 +251,45 @@ feature => { parent => 'limits', name => 'maximum image dimensions', score => { - jpeg => 3, - png => 4, - jp2k => 5, - webp => 1, - heic => 2, - avif => 3, - jxl => 4, - }, - data => { - jpeg => '65k²', # 2**16 - png => '2G²', # 2**31 - jp2k => '4G²', # 2**32 - webp => '16k²', # 2**14 - heic => '8k×4k+', # 8193x4320 - avif => '65k²+', # 2**16, 8193x4320 with profile - jxl => '1G²', # 2**30 + jpeg => [3, '65k²'], # 2**16 + pnm => [5, '∞'], + gif => [3, '65k²'], # 2**16 + png => [4, '2G²'], # 2**31 + jp2k => [4, '4G²'], # 2**32 + webp => [1, '16k²'], # 2**14 + heic => [2,'8k×4k+', 'tilable, only 512×512 on Apple'], # 8193x4320 + avif => [3, '65k²+', 'tilable, 7680×4320 with Advanced profile'], # 2**16 + jxl => [4, '1G²'], # 2**30 }, }, max_bitdepth => { parent => 'limits', name => 'precision (max. bit depth)', score => { - jpeg => 2, - png => 4, - jp2k => 5, - webp => 2, - heic => 3, - avif => 3, - jxl => 5, - }, - data => { - jpeg => 8, - png => 16, - jp2k => 38, - webp => 8, - heic => 10, - avif => 10, - jxl => 32, + jpeg => [2, 8], + pnm => [2, 8, 'unofficial PFM extension for 32-bit'], + gif => [1, 8, '256 colour palette per frame'], + png => [4, 16], + jp2k => [5, 38], + webp => [2, 8], + heic => [3, 10], #TODO 16? + avif => [3, 12, '8, 10, 12 bit'], + jxl => [5, 32, '24-bit integer or 32-bit float'], }, }, color_444 => { parent => 'limits', - name => 'can do (lossy) 4:4:4', + name => 'chroma subsampling', score => { - jpeg => 'y', - png => 'y', + jpeg => ['y', undef, '4:2:0, 4:2:2, 4:4:4'], + pnm => [4, '✘'], + gif => [4, '✘'], + png => [4, '✘'], jp2k => 'y', - webp => 'n', - heic => 'n', - avif => 'y', - jxl => 'y', + webp => [1, '4:2:0'], + heic => [1, '4:2:0'], + avif => ['y', undef, '4:2:0, 4:2:2, 4:4:4'], + jxl => ['y', undef, 'for JPEG compatibility'], }, }, hdr => { @@ -273,6 +297,8 @@ feature => { name => 'wide gamut/HDR', score => { jpeg => 'n', + pnm => 'n', + gif => 'n', png => 'y', jp2k => 'y', webp => 'n', @@ -285,27 +311,22 @@ feature => { parent => 'limits', name => 'maximum number of channels', score => { - jpeg => 2, - png => 2, - jp2k => 5, - webp => 2, - heic => 3, - avif => 3, - jxl => 4, - }, - data => { - jpeg => 4, # cmyk - png => 4, # cmyk - jp2k => 2**15, - webp => 4, - heic => 5, - avif => 5, - jxl => 4099, + jpeg => [3, 4, 'RGB or CMYK'], + pnm => [3, 3, 'RGB'], + gif => [3, 3, 'RGB palette'], + png => [3, 4, 'RGBA'], + jp2k => [5, 2**15], + webp => [3, 4, 'RGBA'], + heic => [3, 3, 'RGB, separate alpha and depth'], + avif => [3, 3, 'RGB, separate alpha and depth'], + jxl => [4, 4099, 'native XYB'], }, }, features => { score => { jpeg => 2, + pnm => [2, undef, 'great for simplicity and ASCII storage'], + gif => 2, png => 3, jp2k => 4, webp => 2, @@ -319,25 +340,24 @@ feature => { parent => 'features', name => 'supports animation', score => { - jpeg => 2, - png => 4, - jp2k => 2, + jpeg => [2, 'MJPEG'], + pnm => 'n', + gif => 'y', + png => [4, 'APNG', 'later backwards-compatible extension'], + jp2k => [2, 'MJP2'], webp => 'y', heic => 'y', avif => 'y', jxl => 'y', }, - data => { - jpeg => 'MJPEG', - png => 'APNG', - jp2k => 'MJP2', - }, }, progressive => { parent => 'features', name => 'progressive decoding', score => { jpeg => 4, + pnm => 'n', + gif => 2, png => 2, jp2k => 5, webp => 'n', @@ -351,6 +371,8 @@ feature => { name => 'alpha transparency', score => { jpeg => 'n', + pnm => ['n', undef, 'PAM extension'], + gif => [3, '1 bit'], png => 'y', jp2k => 'y', webp => 'y', @@ -364,6 +386,8 @@ feature => { name => 'depth map', score => { jpeg => 'n', + pnm => 'n', + gif => 'n', png => 'n', jp2k => 'n', webp => 'n', @@ -374,9 +398,11 @@ feature => { }, overlays => { parent => 'features', - name => 'overlays', + name => 'overlays (layers)', score => { jpeg => 'n', + pnm => 'n', + gif => 'y', png => 'n', jp2k => 'n', webp => 'n', @@ -390,6 +416,8 @@ feature => { name => 'authoring workflow suitability', score => { jpeg => 2, + pnm => 2, + gif => 2, png => 3, jp2k => 3, webp => 2, @@ -403,22 +431,23 @@ feature => { name => 'generation loss resilience', score => { jpeg => 4, - png => 'n/a', + pnm => 0, + png => 0, + gif => 0, jp2k => 3, webp => 2, heic => 3, avif => 3, jxl => 4, }, - data => { - png => 'n/a', - }, }, compat_jpeg => { parent => 'features', name => 'lossless JPEG recompression', score => { jpeg => 0, + pnm => 'n', + gif => 'n', png => 'n', jp2k => 'n', webp => 'n', @@ -426,23 +455,50 @@ feature => { avif => 'n', jxl => 'y', }, - data => { - jpeg => 'n/a', - }, }, royalties => { name => 'royalty-free', score => { jpeg => 5, + pnm => 5, + gif => [5, undef, 'patented before 2003'], png => 5, - gif => 5, # patents expired - jp2k => 3, # specs not freely available - webp => 4, # submarine risk - heic => 'n', # patents enforced - avif => 4, - jxl => 4, + jp2k => [3, undef, 'ISO specification not freely available'], + webp => [4, undef, 'free format, low remaining risk of patent trolls'], + heic => ['n', undef, 'heavily patented'], + avif => [4, undef, 'free format, risk of patent trolls'], + jxl => [4, undef, 'free format, risk of patent trolls'], }, children => [], }, + support => { + score => { + jpeg => 5, + pnm => [2, undef], + gif => 5, + png => 5, + jp2k => [2, undef, 'Apple only'], + webp => [4, undef, 'modern browsers'], + heic => [1, undef, 'stored by latest cameras, no browser support'], + avif => [3, undef, 'all modern browsers except Safari and Edge'], + jxl => [2, undef, 'upcoming in most browsers'], + }, + }, + overhead => { + name => 'container overhead (file size)', + score => { + png => [3, 67, 'upto 70 bytes for specific RGBA'], + jpeg => [2, 160, '159 bytes minimum for gray, 288 for specific colours'], + gif => [4, 35, '43 bytes for transparent'], + webp => [4, 34, 'black or transparent lossless; 44-92 bytes lossy'], + bpg => [4, 31, 'lossy 29-62 bytes, lossless 37-160'], + flif => [5, 14, 'black or transparent; 20 bytes for specific RGBA'], + pnm => [5, 8, 'monochrome text PBM; 12 bytes PPM; 69 bytes PAM'], + jxl => [5, 12, '512×256 black pixels'], + avif => [1, 282, 'container overhead; 457 bytes with alpha'], + jp2k => [2, 123, 'experimental results, likely not optimal'], + heic => [1, 386], + }, + }, }, }