codec: rate browser support in my biased opinion
[sheet.git] / codec.inc.pl
index 925c2fe54f5b0e6b286b263e095b67ca9a49ea4f..992c48869c83f7ae4d301daf090251835a345eef 100644 (file)
@@ -5,6 +5,10 @@ codec => {
                name => '<abbr title="Joint Photographic Experts Group">JPEG</abbr>',
                available => 1992,
        },
+       gif => {
+               name => '<abbr title="Graphics Interchange Format">GIF</abbr>',
+               available => 1987,
+       },
        png => {
                name => '<abbr title="Portable Network Graphics">PNG</abbr>',
                available => 1996,
@@ -32,12 +36,13 @@ codec => {
 },
 feature => {
        default => {
-               children => [qw( quality_photo quality_art speed limits features royalties )],
+               children => [qw( quality_photo quality_art speed limits features royalties support )],
        },
        quality_photo => {
                name => 'compression (photo)',
                score => {
                        jpeg => 3,
+                       gif  => 1,
                        png  => 1,
                        jp2k => 4,
                        webp => 3,
@@ -49,15 +54,16 @@ feature => {
        },
        quality_photo_1 => {
                parent => 'quality_photo',
-               name => 'low fidelity',
+               name => 'thumbnails',
                score => {
                        jpeg => 2,
+                       gif  => 1,
                        png  => 1,
                        jp2k => 3,
-                       webp => 3,
+                       webp => 4,
                        heic => 5,
                        avif => 5,
-                       jxl  => 4,
+                       jxl  => 3,
                },
        },
        quality_photo_2 => {
@@ -65,6 +71,7 @@ feature => {
                name => 'medium fidelity',
                score => {
                        jpeg => 3,
+                       gif  => 1,
                        png  => 1,
                        jp2k => 4,
                        webp => 3,
@@ -78,6 +85,7 @@ feature => {
                name => 'high fidelity',
                score => {
                        jpeg => 3,
+                       gif  => 1,
                        png  => 2,
                        jp2k => 4,
                        webp => 2,
@@ -91,6 +99,7 @@ feature => {
                name => 'lossless',
                score => {
                        jpeg => 1,
+                       gif  => 1,
                        png  => 2,
                        jp2k => 4,
                        webp => 3,
@@ -103,6 +112,7 @@ feature => {
                name => 'compression (other images)',
                score => {
                        jpeg => 2,
+                       gif  => 1,
                        png  => 3,
                        jp2k => 2,
                        webp => 4,
@@ -116,6 +126,7 @@ feature => {
                name => 'lossy non-photographic',
                score => {
                        jpeg => 2,
+                       gif  => 2,
                        png  => 3,
                        jp2k => 2,
                        webp => 4,
@@ -128,6 +139,7 @@ feature => {
                name => 'lossless non-photographic',
                score => {
                        jpeg => 1,
+                       gif  => 1,
                        png  => 4,
                        jp2k => 2,
                        webp => 5,
@@ -140,6 +152,7 @@ feature => {
                name => 'mixed photo/nonphoto',
                score => {
                        jpeg => 2,
+                       gif  => 1,
                        png  => 2,
                        jp2k => 2,
                        webp => 3,
@@ -151,6 +164,7 @@ feature => {
        speed => {
                score => {
                        jpeg => 5,
+                       gif  => 4,
                        png  => 4,
                        jp2k => 3,
                        webp => 4,
@@ -165,6 +179,7 @@ feature => {
                name => 'single-core encode',
                score => {
                        jpeg => 5,
+                       gif  => 3, # palette conversion
                        png  => 3,
                        jp2k => 4,
                        webp => 4,
@@ -178,6 +193,7 @@ feature => {
                name => 'single-core decode',
                score => {
                        jpeg => 5,
+                       gif  => 5,
                        png  => 5,
                        jp2k => 4,
                        webp => 5,
@@ -191,6 +207,7 @@ feature => {
                name => 'pararellizable',
                score => {
                        jpeg => 2,
+                       gif  => 2,
                        png  => 2,
                        jp2k => 4,
                        webp => 2,
@@ -202,6 +219,7 @@ feature => {
        limits => {
                score => {
                        jpeg => 3,
+                       gif  => 2,
                        png  => 4,
                        jp2k => 5,
                        webp => 2,
@@ -215,57 +233,42 @@ 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
+                       gif  => [3, '65k²'],   # 2**16
+                       png  => [4,  '2G²'],   # 2**31
+                       jp2k => [5,  '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],
+                       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'],
+                       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 +276,7 @@ feature => {
                name => 'wide gamut/HDR',
                score => {
                        jpeg => 'n',
+                       gif  => 'n',
                        png  => 'y',
                        jp2k => 'y',
                        webp => 'n',
@@ -285,27 +289,20 @@ 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'],
+                       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,
+                       gif  => 2,
                        png  => 3,
                        jp2k => 4,
                        webp => 2,
@@ -319,25 +316,22 @@ feature => {
                parent => 'features',
                name => 'supports animation',
                score => {
-                       jpeg => 2,
-                       png  => 4,
-                       jp2k => 2,
+                       jpeg => [2, 'MJPEG'],
+                       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,
+                       gif  => 2,
                        png  => 2,
                        jp2k => 5,
                        webp => 'n',
@@ -351,6 +345,7 @@ feature => {
                name => 'alpha transparency',
                score => {
                        jpeg => 'n',
+                       gif  => [3, '1 bit'],
                        png  => 'y',
                        jp2k => 'y',
                        webp => 'y',
@@ -364,6 +359,7 @@ feature => {
                name => 'depth map',
                score => {
                        jpeg => 'n',
+                       gif  => 'n',
                        png  => 'n',
                        jp2k => 'n',
                        webp => 'n',
@@ -374,9 +370,10 @@ feature => {
        },
        overlays => {
                parent => 'features',
-               name => 'overlays',
+               name => 'overlays (layers)',
                score => {
                        jpeg => 'n',
+                       gif  => 'y',
                        png  => 'n',
                        jp2k => 'n',
                        webp => 'n',
@@ -390,6 +387,7 @@ feature => {
                name => 'authoring workflow suitability',
                score => {
                        jpeg => 2,
+                       gif  => 2,
                        png  => 3,
                        jp2k => 3,
                        webp => 2,
@@ -403,22 +401,21 @@ feature => {
                name => 'generation loss resilience',
                score => {
                        jpeg => 4,
-                       png  => 'n/a',
+                       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,
+                       gif  => 'n',
                        png  => 'n',
                        jp2k => 'n',
                        webp => 'n',
@@ -426,23 +423,32 @@ feature => {
                        avif => 'n',
                        jxl  => 'y',
                },
-               data => {
-                       jpeg => 'n/a',
-               },
        },
        royalties => {
                name => 'royalty-free',
                score => {
                        jpeg => 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,
+                       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'],
+               },
+       },
 },
 }