codec: gif format (best effort comparison)
[sheet.git] / codec.inc.pl
1 use utf8;
2 +{
3 codec => {
4         jpeg => {
5                 name => '<abbr title="Joint Photographic Experts Group">JPEG</abbr>',
6                 available => 1992,
7         },
8         gif => {
9                 name => '<abbr title="Graphics Interchange Format">GIF</abbr>',
10                 available => 1987,
11         },
12         png => {
13                 name => '<abbr title="Portable Network Graphics">PNG</abbr>',
14                 available => 1996,
15         },
16         jp2k => {
17                 name => 'JPEG 2000',
18                 available => 2000,
19         },
20         webp => {
21                 name => 'WebP',
22                 available => 2010,
23         },
24         heic => {
25                 name => '<abbr title="High Efficiency Image Container (HEVC in HEIF)">HEIC</abbr>',
26                 available => 2015,
27         },
28         avif => {
29                 name => '<abbr title="AV1 Image File Format">AVIF</abbr>',
30                 available => 2019,
31         },
32         jxl => {
33                 name => 'JPEG XL',
34                 available => 2021,
35         },
36 },
37 feature => {
38         default => {
39                 children => [qw( quality_photo quality_art speed limits features royalties )],
40         },
41         quality_photo => {
42                 name => 'compression (photo)',
43                 score => {
44                         jpeg => 3,
45                         gif  => 1,
46                         png  => 1,
47                         jp2k => 4,
48                         webp => 3,
49                         heic => 5,
50                         avif => 5,
51                         jxl  => 5,
52                 },
53                 children => [qw( quality_photo_1 quality_photo_2 quality_photo_3 quality_photo_ll )],
54         },
55         quality_photo_1 => {
56                 parent => 'quality_photo',
57                 name => 'thumbnails',
58                 score => {
59                         jpeg => 2,
60                         gif  => 1,
61                         png  => 1,
62                         jp2k => 3,
63                         webp => 4,
64                         heic => 5,
65                         avif => 5,
66                         jxl  => 3,
67                 },
68         },
69         quality_photo_2 => {
70                 parent => 'quality_photo',
71                 name => 'medium fidelity',
72                 score => {
73                         jpeg => 3,
74                         gif  => 1,
75                         png  => 1,
76                         jp2k => 4,
77                         webp => 3,
78                         heic => 4,
79                         avif => 5,
80                         jxl  => 5,
81                 },
82         },
83         quality_photo_3 => {
84                 parent => 'quality_photo',
85                 name => 'high fidelity',
86                 score => {
87                         jpeg => 3,
88                         gif  => 1,
89                         png  => 2,
90                         jp2k => 4,
91                         webp => 2,
92                         heic => 3,
93                         avif => 4,
94                         jxl  => 5,
95                 },
96         },
97         quality_photo_ll => {
98                 parent => 'quality_photo',
99                 name => 'lossless',
100                 score => {
101                         jpeg => 1,
102                         gif  => 1,
103                         png  => 2,
104                         jp2k => 4,
105                         webp => 3,
106                         heic => 3,
107                         avif => 3,
108                         jxl  => 5,
109                 },
110         },
111         quality_art => {
112                 name => 'compression (other images)',
113                 score => {
114                         jpeg => 2,
115                         gif  => 1,
116                         png  => 3,
117                         jp2k => 2,
118                         webp => 4,
119                         heic => 3,
120                         avif => 4.5,
121                         jxl  => 5,
122                 },
123                 children => [qw( quality_art_2 quality_art_ll quality_art_mixed )],
124         },
125         quality_art_2 => {
126                 name => 'lossy non-photographic',
127                 score => {
128                         jpeg => 2,
129                         gif  => 2,
130                         png  => 3,
131                         jp2k => 2,
132                         webp => 4,
133                         heic => 3,
134                         avif => 5,
135                         jxl  => 5,
136                 },
137         },
138         quality_art_ll => {
139                 name => 'lossless non-photographic',
140                 score => {
141                         jpeg => 1,
142                         gif  => 1,
143                         png  => 4,
144                         jp2k => 2,
145                         webp => 5,
146                         heic => 2,
147                         avif => 3,
148                         jxl  => 5,
149                 },
150         },
151         quality_art_mixed => {
152                 name => 'mixed photo/nonphoto',
153                 score => {
154                         jpeg => 2,
155                         gif  => 1,
156                         png  => 2,
157                         jp2k => 2,
158                         webp => 3,
159                         heic => 3,
160                         avif => 5,
161                         jxl  => 5,
162                 },
163         },
164         speed => {
165                 score => {
166                         jpeg => 5,
167                         gif  => 4,
168                         png  => 4,
169                         jp2k => 3,
170                         webp => 4,
171                         heic => 3,
172                         avif => 3,
173                         jxl  => 5,
174                 },
175                 children => [qw( speed_encode speed_decode speed_parallel )],
176         },
177         speed_encode => {
178                 parent => 'speed',
179                 name => 'single-core encode',
180                 score => {
181                         jpeg => 5,
182                         gif  => 3, # palette conversion
183                         png  => 3,
184                         jp2k => 4,
185                         webp => 4,
186                         heic => 3,
187                         avif => 2,
188                         jxl  => 5,
189                 },
190         },
191         speed_decode => {
192                 parent => 'speed',
193                 name => 'single-core decode',
194                 score => {
195                         jpeg => 5,
196                         gif  => 5,
197                         png  => 5,
198                         jp2k => 4,
199                         webp => 5,
200                         heic => 3,
201                         avif => 3,
202                         jxl  => 5,
203                 },
204         },
205         speed_parallel => {
206                 parent => 'speed',
207                 name => 'pararellizable',
208                 score => {
209                         jpeg => 2,
210                         gif  => 2,
211                         png  => 2,
212                         jp2k => 4,
213                         webp => 2,
214                         heic => 4,
215                         avif => 4,
216                         jxl  => 5,
217                 },
218         },
219         limits => {
220                 score => {
221                         jpeg => 3,
222                         gif  => 2,
223                         png  => 4,
224                         jp2k => 5,
225                         webp => 2,
226                         heic => 4,
227                         avif => 4.5,
228                         jxl  => 5,
229                 },
230                 children => [qw( max_dimensions max_bitdepth color_444 hdr max_channels  )],
231         },
232         max_dimensions => {
233                 parent => 'limits',
234                 name => 'maximum image dimensions',
235                 score => {
236                         jpeg => 3,
237                         gif  => 3,
238                         png  => 4,
239                         jp2k => 5,
240                         webp => 1,
241                         heic => 2,
242                         avif => 3,
243                         jxl  => 4,
244                 },
245                 data => {
246                         jpeg => '65k²',  # 2**16
247                         gif  => '65k²',  # 2**16
248                         png  => '2G²',   # 2**31
249                         jp2k => '4G²',   # 2**32
250                         webp => '16k²',  # 2**14
251                         heic => '8k×4k+', # 8193x4320
252                         avif => '65k²+',  # 2**16, 8193x4320 with profile
253                         jxl  => '1G²',   # 2**30
254                 },
255         },
256         max_bitdepth => {
257                 parent => 'limits',
258                 name => 'precision (max. bit depth)',
259                 score => {
260                         jpeg => 2,
261                         gif  => 2,
262                         png  => 4,
263                         jp2k => 5,
264                         webp => 2,
265                         heic => 3,
266                         avif => 3,
267                         jxl  => 5,
268                 },
269                 data => {
270                         jpeg => 8,
271                         gif  => 8,
272                         png  => 16,
273                         jp2k => 38,
274                         webp => 8,
275                         heic => 10,
276                         avif => 10,
277                         jxl  => 32,
278                 },
279         },
280         color_444 => {
281                 parent => 'limits',
282                 name => 'can do (lossy) 4:4:4',
283                 score => {
284                         jpeg => 'y',
285                         gif  => 'y',
286                         png  => 'y',
287                         jp2k => 'y',
288                         webp => 'n',
289                         heic => 'n',
290                         avif => 'y',
291                         jxl  => 'y',
292                 },
293         },
294         hdr => {
295                 parent => 'limits',
296                 name => 'wide gamut/HDR',
297                 score => {
298                         jpeg => 'n',
299                         gif  => 'n',
300                         png  => 'y',
301                         jp2k => 'y',
302                         webp => 'n',
303                         heic => 'y',
304                         avif => 'y',
305                         jxl  => 'y',
306                 },
307         },
308         max_channels => {
309                 parent => 'limits',
310                 name => 'maximum number of channels',
311                 score => {
312                         jpeg => 2,
313                         gif  => 1,
314                         png  => 2,
315                         jp2k => 5,
316                         webp => 2,
317                         heic => 3,
318                         avif => 3,
319                         jxl  => 4,
320                 },
321                 data => {
322                         jpeg => 4, # cmyk
323                         gif  => 3,
324                         png  => 4, # cmyk
325                         jp2k => 2**15,
326                         webp => 4,
327                         heic => 5,
328                         avif => 5,
329                         jxl  => 4099,
330                 },
331         },
332         features => {
333                 score => {
334                         jpeg => 2,
335                         gif  => 2,
336                         png  => 3,
337                         jp2k => 4,
338                         webp => 2,
339                         heic => 4,
340                         avif => 4,
341                         jxl  => 5,
342                 },
343                 children => [qw( animation progressive alpha depthmap overlays authoring reencode compat_jpeg )],
344         },
345         animation => {
346                 parent => 'features',
347                 name => 'supports animation',
348                 score => {
349                         jpeg => 2,
350                         gif  => 'y',
351                         png  => 4,
352                         jp2k => 2,
353                         webp => 'y',
354                         heic => 'y',
355                         avif => 'y',
356                         jxl  => 'y',
357                 },
358                 data => {
359                         jpeg => 'MJPEG',
360                         png  => 'APNG',
361                         jp2k => 'MJP2',
362                 },
363         },
364         progressive => {
365                 parent => 'features',
366                 name => 'progressive decoding',
367                 score => {
368                         jpeg => 4,
369                         gif  => 2,
370                         png  => 2,
371                         jp2k => 5,
372                         webp => 'n',
373                         heic => 'n',
374                         avif => 'n',
375                         jxl  => 5,
376                 },
377         },
378         alpha => {
379                 parent => 'features',
380                 name => 'alpha transparency',
381                 score => {
382                         jpeg => 'n',
383                         gif  => 3,
384                         png  => 'y',
385                         jp2k => 'y',
386                         webp => 'y',
387                         heic => 'y',
388                         avif => 'y',
389                         jxl  => 'y',
390                 },
391                 data => {
392                         gif => '1 bit',
393                 },
394         },
395         depthmap => {
396                 parent => 'features',
397                 name => 'depth map',
398                 score => {
399                         jpeg => 'n',
400                         gif  => 'n',
401                         png  => 'n',
402                         jp2k => 'n',
403                         webp => 'n',
404                         heic => 'y',
405                         avif => 'y',
406                         jxl  => 'y',
407                 },
408         },
409         overlays => {
410                 parent => 'features',
411                 name => 'overlays (layers)',
412                 score => {
413                         jpeg => 'n',
414                         gif  => 'y',
415                         png  => 'n',
416                         jp2k => 'n',
417                         webp => 'n',
418                         heic => 'y',
419                         avif => 'y',
420                         jxl  => 'y',
421                 },
422         },
423         authoring => {
424                 parent => 'features',
425                 name => 'authoring workflow suitability',
426                 score => {
427                         jpeg => 2,
428                         gif  => 2,
429                         png  => 3,
430                         jp2k => 3,
431                         webp => 2,
432                         heic => 2,
433                         avif => 2,
434                         jxl  => 5,
435                 },
436         },
437         reencode => {
438                 parent => 'features',
439                 name => 'generation loss resilience',
440                 score => {
441                         jpeg => 4,
442                         png  => 0,
443                         gif  => 0,
444                         jp2k => 3,
445                         webp => 2,
446                         heic => 3,
447                         avif => 3,
448                         jxl  => 4,
449                 },
450                 data => {
451                         gif  => 'n/a',
452                         png  => 'n/a',
453                 },
454         },
455         compat_jpeg => {
456                 parent => 'features',
457                 name => 'lossless JPEG recompression',
458                 score => {
459                         jpeg => 0,
460                         gif  => 'n',
461                         png  => 'n',
462                         jp2k => 'n',
463                         webp => 'n',
464                         heic => 'n',
465                         avif => 'n',
466                         jxl  => 'y',
467                 },
468                 data => {
469                         jpeg => 'n/a',
470                 },
471         },
472         royalties => {
473                 name => 'royalty-free',
474                 score => {
475                         jpeg => 5,
476                         gif  => 5, # patents expired
477                         png  => 5,
478                         jp2k => 3, # specs not freely available
479                         webp => 4, # submarine risk
480                         heic => 'n', # patents enforced
481                         avif => 4,
482                         jxl  => 4,
483                 },
484                 children => [],
485         },
486 },
487 }