4 ms·
With some dirty hacks, I got it down to 83 bytes: https://cdn.discordapp.com/attachments/286612533757083648/966916647875137576/foo.png https://cdn.discordapp.c
by Retr0id 5y ago
With some dirty hacks, I got it down to 83 bytes:
https://cdn.discordapp.com/attachments/286612533757083648/966916647875137576/foo.png https://cdn.discordapp.com/attachments/286612533757083648/96...
00 89 50 4e 47 0d 0a 1a 0a 00 00 00 0d 49 48 44 52 |.PNG........IHDR|
10 00 00 01 00 00 00 01 00 01 03 00 00 00 66 bc 3a |.............f�:|
20 25 00 00 00 03 50 4c 54 45 b5 d0 d0 63 04 16 ea |%....PLTE���c..�|
30 00 00 00 1b 49 44 41 54 68 81 ec c1 01 0d 00 00 |....IDATh.��....|
40 00 c2 a0 f7 4f 6d 0f 07 14 00 00 00 00 00 00 00 |. �Om..........|
50 c0 b9 01 |��.|
Although technically invalid, it still renders fine in Firefox, Chrome, and Safari.
Edit: 87 -> 83 bytes
Edit2: Maybe in a couple of years time, we can use JPEG-XL instead (only 22 bytes, without any hacks!):
data:image/jxl;base64,/wp/QCQIBgEALABLOEmIDIPCakgSBg==
- thrdbndndn 5y agoSo what are the tricks
- Retr0id 5y agoThe first trick is simply "cut the end of the file off". This saves the adler32 checksum on the end of the zlib stream, the crc32 on the end of the IDAT chunk, and the entire IEND chunk. This works because modern browsers have support for progressively rendering images that are still being downloaded - as a result, truncation is also handled gracefully. However, this alone results in rendering errors - the last few rows of pixels end up missing, like this: https://cdn.discordapp.com/attachments/286612533757083648/966914183214014594/foo.png https://cdn.discordapp.com/attachments/286612533757083648/96... I don't know the precise reason for this, but I believe the parsing state machine ends up stalling too soon, so I threw some extra zeroes into the IDAT data to "flush" the state machine - but not enough to increase the file size.
- vmception 5y ago> Although technically invalid, it still renders fine in Firefox, Chrome, and Safari. When I learned HTML the syntax was sooo particular. Now (our pretty much since then) anything goes and I love it Natural evolution of protocols
- Andrew_nenakhov 5y agoNo. It goes only because there are very few browser engines, who mostly can align their behaviour with each other. Protocols with miltiple implementations are way more strict, because you can't feasibly test your quirky approach on every implementation, and the chance they will all be as forgiving is slim.
- sophiebits 5y agoHTML parsing is well-specced these days.
- boondaburrah 5y agoparsing was never so much the problem as what was rendered afterwards being different.
- berkes 5y agoThe parsing is easy. And done in many, many libraries outside of the browsers. (And no, parsing with regex is still not possible, zalgo) The problem is not parsing of HTML, its the DOM events, CSS application, javascript apis and above all the combination thereof which must be rendered all exactly the same, what makes it hard.
- deleted 5y ago[deleted]
- doomlaser 5y agoHadn't heard of JPEG XL until you mentioned it. The format looks really cool! Support for lossless and lossy compression, animation, and tons of other new features https://en.wikipedia.org/wiki/JPEG_XL https://en.wikipedia.org/wiki/JPEG_XL Preliminary support in Firefox and Chromium nightly/testing builds already. I share your hope that we can start to use it in the next couple years. Looking at you, Safari ;)
- naoqj 5y agoI thought that it had existed for decades, but I had confused it for jp2. https://en.wikipedia.org/wiki/JPEG_2000 https://en.wikipedia.org/wiki/JPEG_2000
- capitainenemo 5y agoStill sad about the demise of JNG all these years later. There was even a "light" version of the spec to address the complexity issues, and someone in bug #18574 had even made a reference library which took up less space than the default Mozilla libpng, and maintained their own browser branch. It was maintained for a few years but abandoned when it was clear Mozilla was all in on APNG. But, yeah, we had all those things in something that was actually in major browsers, 22 years ago. https://bugzilla.mozilla.org/show_bug.cgi?id=18574 https://bugzilla.mozilla.org/show_bug.cgi?id=18574 http://mngzilla.sourceforge.net/ http://mngzilla.sourceforge.net/
- blurred 5y agoThere is this JPEG XL art gallery with very nice images 20-100 bytes e.g.: https://jpegxl.info/art/2021-04_jon.html https://jpegxl.info/art/2021-04_jon.html To see them, enable flag in chrome: chrome://flags/#enable-jxl
- yread 5y agoStill super bloated compared to the tiniest GIF: 47 49 46 38 39 61 01 00 01 00 00 ff 00 2c 00 00 00 00 01 00 01 00 00 02 00 3b http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ever http://probablyprogramming.com/2009/03/15/the-tiniest-gif-ev...
- daxterspeed 5y agoIf we permit the fairly recent QOI format[0] we can produce a 1x1 transparent pixel in just 23 bytes (14 byte header, 1 byte for QOI_OP_INDEX, 8 byte end marker): 71 6f 69 66 00 00 00 01 00 00 00 01 04 00 | 14 byte header 00 | QOI_OP_INDEX 00 00 00 00 00 00 00 01 | end marker Similarly the 103 byte png in the article would be [EDIT] This is incorrect, see below 71 6f 69 66 00 00 01 00 00 00 01 00 04 00 | 14 byte header fe b7 d0 d0 | QOI_OP_RGB, RGB color, fd fd fd fd c6 | QOI_OP_RUN for 62+62+62+62+7 00 00 00 00 00 00 00 01 | end marker [0]: https://qoiformat.org/qoi-specification.pdf https://qoiformat.org/qoi-specification.pdf [EDIT] I realized that we actually run into one of QOI's drawbacks if we were to encode the 103 byte png in the article, as we actually need to repeat the pixel 65535 times, so we'd have floor(65535/62)=1057 QOI_OP_RUN bytes followed by another QOI_OP_RUN to repeat the last pixel. Here it's pretty clear that the QOI spec missed out on special handling of repeated QOI_OP_RUN operators, as long repetitions could have been handled in far fewer bytes.
- Someone 5y agoThat’s bloated ;-) P1 1 1 1 is a 9 byte 1 × 1 pixel black image in portable bitmap format (https://en.wikipedia.org/wiki/Netpbm#File_formats https://en.wikipedia.org/wiki/Netpbm#File_formats). Consumers of such files likely will know how to scale them to 256 × 256 pixels. The trailing newline may not even be necessary. If so, it would become 8 bytes. Gray 1 X 1 pixel images in binary portable graymap format have the same size. To get a non-gray RGB color, you’ll need two more bytes in binary portable pixmap format.
- dchest 5y agoJXL without container has a very short header, which is nice. WebP is 38 bytes, and is already supported by browsers. 00000000 52 49 46 46 24 00 00 00 57 45 42 50 56 50 38 4c |RIFF$...WEBPVP8L| 00000010 18 00 00 00 2f ff c0 3f 00 07 50 e8 d6 16 ba ff |..../???..P??.??| 00000020 01 00 45 fa ff 9f 22 fa 9f fa df 7f |..E??."?.??.| data:image/webp;base64,UklGRiQAAABXRUJQVlA4TBgAAAAv/8A/AAdQ6NYWuv8BAEX6/58i+p/6338= Maybe can be made smaller, I just used cwebp -z 9.