google / wuffs

Wrangling Untrusted File Formats Safely
Other
4.16k stars 131 forks source link

The test file gifplayer-muybridge.gif is not standard conformant and rust-gif update #37

Closed HeroicKatora closed 3 years ago

HeroicKatora commented 3 years ago

I'm just curious how this particular gif was created. It seems that in frame 62 (and possibly more after it) the LZW compressed data is not terminated by an end code. However, the specifcation says:

  1. An End of Information code is defined that explicitly indicates the end of the image data stream. LZW processing terminates when this code is encountered. It must be the last code output by the encoder for an image.

Where image refers to one block terminated by a block terminator.

This was noticed when upgrading the Rust gif library to a more principled decoder. (The old decoder was incredibly lenient in the structure of data permitted, even outputting additional data after the end code). By the way, this yields new performance numbers which compare quite favorably. As measured:

```text Benchmarkrust_gif_decode_1k_bw 20000 3125 ns/op 327.585 MB/s Benchmarkrust_gif_decode_1k_color 10000 9139 ns/op 110.285 MB/s Benchmarkrust_gif_decode_10k_bgra 1000 121340 ns/op 332.287 MB/s Benchmarkrust_gif_decode_10k_indexed 1000 97152 ns/op 103.754 MB/s Benchmarkrust_gif_decode_20k 500 152167 ns/op 126.176 MB/s Benchmarkrust_gif_decode_100k_artificial 150 516036 ns/op 267.236 MB/s Benchmarkrust_gif_decode_100k_realistic 100 1136677 ns/op 121.322 MB/s Benchmarkrust_gif_decode_1000k 10 8158620 ns/op 122.659 MB/s Benchmarkrust_gif_decode_anim_screencap 10 8946771 ns/op 519.986 MB/s Benchmarkrust_gif_decode_1k_bw 20000 3140 ns/op 326.044 MB/s Benchmarkrust_gif_decode_1k_color 10000 9129 ns/op 110.410 MB/s Benchmarkrust_gif_decode_10k_bgra 1000 122251 ns/op 329.811 MB/s Benchmarkrust_gif_decode_10k_indexed 1000 97687 ns/op 103.186 MB/s Benchmarkrust_gif_decode_20k 500 157508 ns/op 121.897 MB/s Benchmarkrust_gif_decode_100k_artificial 150 530540 ns/op 259.931 MB/s Benchmarkrust_gif_decode_100k_realistic 100 1146479 ns/op 120.284 MB/s Benchmarkrust_gif_decode_1000k 10 8132214 ns/op 123.058 MB/s Benchmarkrust_gif_decode_anim_screencap 10 8920712 ns/op 521.505 MB/s Benchmarkrust_gif_decode_1k_bw 20000 3147 ns/op 325.321 MB/s Benchmarkrust_gif_decode_1k_color 10000 9086 ns/op 110.935 MB/s Benchmarkrust_gif_decode_10k_bgra 1000 121492 ns/op 331.873 MB/s Benchmarkrust_gif_decode_10k_indexed 1000 100702 ns/op 100.096 MB/s Benchmarkrust_gif_decode_20k 500 156993 ns/op 122.297 MB/s Benchmarkrust_gif_decode_100k_artificial 150 530643 ns/op 259.880 MB/s Benchmarkrust_gif_decode_100k_realistic 100 1170923 ns/op 117.773 MB/s Benchmarkrust_gif_decode_1000k 10 8373270 ns/op 119.515 MB/s Benchmarkrust_gif_decode_anim_screencap 10 8980037 ns/op 518.059 MB/s Benchmarkrust_gif_decode_1k_bw 20000 3138 ns/op 326.319 MB/s Benchmarkrust_gif_decode_1k_color 10000 9135 ns/op 110.334 MB/s Benchmarkrust_gif_decode_10k_bgra 1000 121609 ns/op 331.551 MB/s Benchmarkrust_gif_decode_10k_indexed 1000 96996 ns/op 103.921 MB/s Benchmarkrust_gif_decode_20k 500 150769 ns/op 127.346 MB/s Benchmarkrust_gif_decode_100k_artificial 150 511933 ns/op 269.378 MB/s Benchmarkrust_gif_decode_100k_realistic 100 1145734 ns/op 120.363 MB/s Benchmarkrust_gif_decode_1000k 10 8124121 ns/op 123.180 MB/s Benchmarkrust_gif_decode_anim_screencap 10 9107758 ns/op 510.795 MB/s Benchmarkrust_gif_decode_1k_bw 20000 3216 ns/op 318.332 MB/s Benchmarkrust_gif_decode_1k_color 10000 9245 ns/op 109.020 MB/s Benchmarkrust_gif_decode_10k_bgra 1000 122231 ns/op 329.865 MB/s Benchmarkrust_gif_decode_10k_indexed 1000 98080 ns/op 102.773 MB/s Benchmarkrust_gif_decode_20k 500 152815 ns/op 125.641 MB/s Benchmarkrust_gif_decode_100k_artificial 150 522883 ns/op 263.737 MB/s Benchmarkrust_gif_decode_100k_realistic 100 1156334 ns/op 119.259 MB/s Benchmarkrust_gif_decode_1000k 10 8178582 ns/op 122.360 MB/s Benchmarkrust_gif_decode_anim_screencap 10 9022169 ns/op 515.640 MB/s ```

I'll provide another update for ignoring the missing end code is published as currently the benchmark fails.

nigeltao commented 3 years ago

I'm just curious how this particular gif was created.

I'm not 100% confident that I remember the details, but I suspect that it was created by the byzanz tool.

this yields new performance numbers which compare quite favorably

Thanks, but since we all have different hardware, I can't really learn much from these raw numbers without knowing a comparison point (on the same hardware, obviously). For example, numbers for "the old rust" or "wuffs/gif" or "C/giflib". When comparing two different Benchmarketc runs, I use the benchstat program to derive summary statistics (e.g. standard deviations and p-values).

HeroicKatora commented 3 years ago

Thanks, but since we all have different hardware, I can't really learn much from these raw numbers without knowing a comparison point (on the same hardware, obviously). For example, numbers for "the old rust" or "wuffs/gif" or "C/giflib".

the numbers for gcc -O3 test/c/gif.c && ./a.out -bench:

``` Benchmarkwuffs_gif_decode_1k_bw/gcc10 200000 1567 ns/op 653.388 MB/s Benchmarkwuffs_gif_decode_1k_color_full_init/gcc10 100000 5489 ns/op 183.617 MB/s Benchmarkwuffs_gif_decode_1k_color_part_init/gcc10 100000 4161 ns/op 242.213 MB/s Benchmarkwuffs_gif_decode_10k_bgra/gcc10 10000 52387 ns/op 769.650 MB/s Benchmarkwuffs_gif_decode_10k_indexed/gcc10 10000 41503 ns/op 242.873 MB/s Benchmarkwuffs_gif_decode_20k/gcc10 5000 67273 ns/op 285.401 MB/s Benchmarkwuffs_gif_decode_100k_artificial/gcc10 1500 219455 ns/op 628.392 MB/s Benchmarkwuffs_gif_decode_100k_realistic/gcc10 1000 548069 ns/op 251.617 MB/s Benchmarkwuffs_gif_decode_1000k_full_init/gcc10 100 3924560 ns/op 254.992 MB/s Benchmarkwuffs_gif_decode_1000k_part_init/gcc10 100 3922270 ns/op 255.141 MB/s Benchmarkwuffs_gif_decode_anim_screencap/gcc10 100 3348490 ns/op 1389.342 MB/s Benchmarkwuffs_gif_decode_1k_bw/gcc10 200000 1575 ns/op 650.028 MB/s Benchmarkwuffs_gif_decode_1k_color_full_init/gcc10 100000 5475 ns/op 184.106 MB/s Benchmarkwuffs_gif_decode_1k_color_part_init/gcc10 100000 4183 ns/op 240.922 MB/s Benchmarkwuffs_gif_decode_10k_bgra/gcc10 10000 52488 ns/op 768.163 MB/s Benchmarkwuffs_gif_decode_10k_indexed/gcc10 10000 41521 ns/op 242.767 MB/s Benchmarkwuffs_gif_decode_20k/gcc10 5000 67409 ns/op 284.828 MB/s Benchmarkwuffs_gif_decode_100k_artificial/gcc10 1500 218344 ns/op 631.588 MB/s Benchmarkwuffs_gif_decode_100k_realistic/gcc10 1000 549226 ns/op 251.087 MB/s Benchmarkwuffs_gif_decode_1000k_full_init/gcc10 100 3917780 ns/op 255.434 MB/s Benchmarkwuffs_gif_decode_1000k_part_init/gcc10 100 3929240 ns/op 254.689 MB/s Benchmarkwuffs_gif_decode_anim_screencap/gcc10 100 3374310 ns/op 1378.710 MB/s Benchmarkwuffs_gif_decode_1k_bw/gcc10 200000 1561 ns/op 655.825 MB/s Benchmarkwuffs_gif_decode_1k_color_full_init/gcc10 100000 5495 ns/op 183.422 MB/s Benchmarkwuffs_gif_decode_1k_color_part_init/gcc10 100000 4154 ns/op 242.633 MB/s Benchmarkwuffs_gif_decode_10k_bgra/gcc10 10000 52682 ns/op 765.343 MB/s Benchmarkwuffs_gif_decode_10k_indexed/gcc10 10000 41623 ns/op 242.171 MB/s Benchmarkwuffs_gif_decode_20k/gcc10 5000 67333 ns/op 285.147 MB/s Benchmarkwuffs_gif_decode_100k_artificial/gcc10 1500 218626 ns/op 630.775 MB/s Benchmarkwuffs_gif_decode_100k_realistic/gcc10 1000 547527 ns/op 251.867 MB/s Benchmarkwuffs_gif_decode_1000k_full_init/gcc10 100 3935070 ns/op 254.311 MB/s Benchmarkwuffs_gif_decode_1000k_part_init/gcc10 100 3914220 ns/op 255.666 MB/s Benchmarkwuffs_gif_decode_anim_screencap/gcc10 100 3373890 ns/op 1378.882 MB/s Benchmarkwuffs_gif_decode_1k_bw/gcc10 200000 1569 ns/op 652.351 MB/s Benchmarkwuffs_gif_decode_1k_color_full_init/gcc10 100000 5478 ns/op 183.978 MB/s Benchmarkwuffs_gif_decode_1k_color_part_init/gcc10 100000 4161 ns/op 242.211 MB/s Benchmarkwuffs_gif_decode_10k_bgra/gcc10 10000 53005 ns/op 760.678 MB/s Benchmarkwuffs_gif_decode_10k_indexed/gcc10 10000 41800 ns/op 241.147 MB/s Benchmarkwuffs_gif_decode_20k/gcc10 5000 67582 ns/op 284.098 MB/s Benchmarkwuffs_gif_decode_100k_artificial/gcc10 1500 218334 ns/op 631.617 MB/s Benchmarkwuffs_gif_decode_100k_realistic/gcc10 1000 549995 ns/op 250.736 MB/s Benchmarkwuffs_gif_decode_1000k_full_init/gcc10 100 3917530 ns/op 255.450 MB/s Benchmarkwuffs_gif_decode_1000k_part_init/gcc10 100 3950690 ns/op 253.306 MB/s Benchmarkwuffs_gif_decode_anim_screencap/gcc10 100 3356460 ns/op 1386.043 MB/s Benchmarkwuffs_gif_decode_1k_bw/gcc10 200000 1562 ns/op 655.420 MB/s Benchmarkwuffs_gif_decode_1k_color_full_init/gcc10 100000 5486 ns/op 183.725 MB/s Benchmarkwuffs_gif_decode_1k_color_part_init/gcc10 100000 4160 ns/op 242.286 MB/s Benchmarkwuffs_gif_decode_10k_bgra/gcc10 10000 52965 ns/op 761.255 MB/s Benchmarkwuffs_gif_decode_10k_indexed/gcc10 10000 41722 ns/op 241.597 MB/s Benchmarkwuffs_gif_decode_20k/gcc10 5000 67457 ns/op 284.622 MB/s Benchmarkwuffs_gif_decode_100k_artificial/gcc10 1500 220192 ns/op 626.289 MB/s Benchmarkwuffs_gif_decode_100k_realistic/gcc10 1000 549098 ns/op 251.146 MB/s Benchmarkwuffs_gif_decode_1000k_full_init/gcc10 100 3960640 ns/op 252.670 MB/s Benchmarkwuffs_gif_decode_1000k_part_init/gcc10 100 3916360 ns/op 255.526 MB/s Benchmarkwuffs_gif_decode_anim_screencap/gcc10 100 3403920 ns/op 1366.717 MB/s ```

In other words, the performance difference is no longer ×7 but rather ~×2.3.

HeroicKatora commented 3 years ago

I'm not 100% confident that I remember the details, but I suspect that it was created by the byzanz tool.

Thanks, I'll have a look.

HeroicKatora commented 3 years ago

Heh, I should just have read your source code... Since you made the same observation but more accurately reported it.

https://github.com/google/wuffs/blob/master/std/gif/decode_gif.wuffs#L889-L906

Sorry for the noice :slightly_smiling_face: