{"id":13831536,"url":"https://github.com/cloudinary/fuif","last_synced_at":"2025-12-25T01:48:25.433Z","repository":{"id":37581475,"uuid":"164445985","full_name":"cloudinary/fuif","owner":"cloudinary","description":"Free Universal Image Format","archived":false,"fork":false,"pushed_at":"2023-04-06T23:03:54.000Z","size":104,"stargazers_count":163,"open_issues_count":0,"forks_count":10,"subscribers_count":36,"default_branch":"master","last_synced_at":"2024-08-05T10:17:25.475Z","etag":null,"topics":["decoder","encoder","image-compression"],"latest_commit_sha":null,"homepage":null,"language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudinary.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2019-01-07T14:39:46.000Z","updated_at":"2024-07-08T07:45:22.000Z","dependencies_parsed_at":"2024-01-15T15:24:40.511Z","dependency_job_id":null,"html_url":"https://github.com/cloudinary/fuif","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudinary%2Ffuif","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudinary%2Ffuif/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudinary%2Ffuif/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudinary%2Ffuif/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudinary","download_url":"https://codeload.github.com/cloudinary/fuif/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225565822,"owners_count":17489272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decoder","encoder","image-compression"],"created_at":"2024-08-04T10:01:30.527Z","updated_at":"2025-12-25T01:48:25.362Z","avatar_url":"https://github.com/cloudinary.png","language":"C++","funding_links":[],"categories":["C++"],"sub_categories":[],"readme":"\n---\n**FUIF development has stopped since FUIF is subsumed in [JPEG XL](https://jpeg.org/jpegxl/), which is based on a combination of [Pik](https://github.com/google/pik) and FUIF.\nA royalty-free and open source reference implementation of JPEG XL is available on [GitHub](https://github.com/libjxl/libjxl). For more information, see [JPEG XL community page](https://jpegxl.info) or visit the [JPEG XL Discord server](https://discord.gg/DqkQgDRTFu).**\n\n---\n\n# FUIF: Free Universal Image Format\n\n**WARNING: This is a research prototype. The bitstream is not finalized. Images encoded\nwith the current version of FUIF may not (and probably will not) decode with future versions\nof FUIF. Use at your own risk!**\n\nFUIF is a new image format, combining ideas from JPEG, lossless WebP, and FLIF.\nIt is a 'universal' image format in several senses:\n\n1. it works well for any kind of image (photographic and non-photographic)\n2. it can do both lossless and lossy (with the same underlying algorithm)\n3. it is Responsive By Design: one file can be used, instead of needing\n   separate images for the low-quality image placeholder, thumbnail, preview, dpr 1, dpr 2, etc\n4. it is backwards compatible with JPEG, in the sense that existing JPEG images can be\n   transcoded to FUIF losslessly (no generation loss) and effectively (smaller files)\n5. it can achieve various trade-offs between encode/decode complexity and compression density\n\n\nIn more detail:\n\n## 1. Any kind of image\n\nFUIF supports several methods for image preprocessing and entropy coding, so it can use\nthe methods that work best for a particular image (or a particular part of an image).\n\nFor non-photographic images with few colors, a palette (color index) can be used.\nThere is no limit on the palette size.\n\nFor images with repetition (e.g. images that include text, where the same letter shapes\nappear in multiple locations), an optional transformation can be used to replace repetition\nwith references (somewhat similar to JBIG2).\n\nFor photographic images, the DCT transformation can be used.\n\nFor raw sensor data, the format supports an arbitrary number of channels, that do not need\nto have the same dimensions, and that do not need to have the same value ranges either.\nThe actual ranges can be used effectively (not just 8-bit or 16-bit like in PNG, but also\nthings like 14-bit with a black level and white level range of 1023..15600).\n\nFUIF supports bit depths up to 28-bit per channel, unsigned or signed.\nOnly integer values are supported (no floating point), but in principle, floating point\nnumbers can be represented as integers plus a suitable transfer function.\n\n\n## 2. Lossless and lossy\n\nFUIF uses reversible transforms (YCoCg, reversible Haar-like squeezing);\noptional quantization is the only source of loss.\n\nUnlike FLIF, FUIF was designed with lossy compression in mind.\nUnlike JPEG, FUIF can obtain fully lossless compression.\nUnlike WebP and JPEG 2000, FUIF uses the same algorithm for both lossy and lossless.\n\nFUIF attempts to offer state-of-the-art compression for both lossy and lossless compression.\n\n\n## 3. Responsive By Design\n\n\nThe FUIF bitstream is designed in such a way that truncating a file results in a\nlower resolution downscaled image. It is similar to progressive JPEG or JPEG 2000\nin this respect. Image formats (like WebP, HEIC/BPG, AVIF) that are derived from a video codec\n(VP8, HEVC, AV1) intra-frame encoding, do not support progressive decoding, since\nin a video codec it does not make much sense to decode a single frame progressively.\n\nFUIF was designed specifically with web delivery in mind. Instead of having to produce,\nstore and deliver many variants of an image, scaled to various dimensions, the idea is\nto use a single file and truncate it depending on the dimensions it gets rendered on.\nThis approach has several advantages:\n\n* Less storage needed (no redundancy)\n* Better for CDNs (cache hit is more likely)\n* Less bandwidth needed (e.g. if you are currently sending a LQIP, then a thumbnail, then when it gets clicked a larger image)\n* Smart browsers could make choices themselves, e.g. load lower resolution when on a slow or expensive connection; when the local browser cache\n  gets too full, instead of deleting whole files, it could trim off bytes at the end, keeping a preview in cache\n\nThe header of a FUIF file contains a mandatory list of truncation offsets, which makes\nit easy to know how many bytes should be requested or served. The following offsets are\nincluded in the header:\n\n* LQIP: the first very low-quality preview of an image (typically at 100-200 bytes)\n* scale 1/16\n* scale 1/8\n* scale 1/4\n* scale 1/2\n\nThese power-of-two downscales are exact, in the sense that if you truncate the file at the given offset,\nthe resulting image is the same as decoding the whole full-resolution image and then downscaling it.\nThis cannot really be done in an efficient way with progressive JPEG.\n\nFUIF has a minimalistic, compact header layout, so the first bits of actual image data appear as\nearly as possible. This makes it possible to get a LQIP within a small byte budget, while it is still\nthe beginning of the actual full image, so you also get the actual image dimensions, truncation offsets\netc.\n\n\n## 4. Backwards compatible with JPEG\n\nThere are a LOT of existing JPEG images out there, as well as devices that produce new JPEG images.\nIf the only way to transcode a JPEG image to a new image format, is to decode the JPEG to pixels and\nencode that to the new format, then there is a problem. Either you get significant generation loss,\nor you get new files that are actually larger than the original.\n\nFUIF supports the 8x8 DCT transform (which is inherently lossy due to rounding errors) and the\nYCbCr color transform (which is also inherently lossy for the same reason). This means it can\nlosslessly represent the actual information in a JPEG image, while still adding most of the benefits\nof FUIF:\n\n* LQIP and scale 1/16 (progressive JPEG starts at scale 1/8)\n* Minimal header overhead\n* Better compression\n\nComparing FUIF to [Dropbox's Lepton](https://github.com/dropbox/lepton), which also does lossless JPEG recompression:\n\n* Lepton can obtain slightly better compression density\n* Lepton is faster\n* Lepton is bit-exact (not just image-exact)\n* FUIF can be decoded progressively (Lepton is anti-progressive since it encodes the AC before the DC)\n* FUIF can do more than just what JPEG can, for example you can add an alpha channel to an existing JPEG\n\n\n## 5. Trade-offs between complexity and compression density\n\nThe entropy coding of FUIF is based on MANIAC (just like FLIF).\nDifferent trade-offs between computational complexity and compression density can be obtained.\nUsing predefined or restricted MANIAC trees (or even no trees at all), encoding can be made\nfaster; if encode time is not an issue, then there are many ways to optimize the encoding.\n\nIn principle, subsets of the formats (\"profiles\") could be defined\n(e.g. by using fixed or restricted transformations and MANIAC trees)\nfor which both encoding and decoding can be specialized (or done in hardware),\nmaking it significantly faster.\nThese subsets are not currently defined nor implemented.\n\nFUIF is also well-suited for adaptive compression (i.e. having different qualities in\ndifferent regions of the image). The MANIAC tree can represent an arbitrary segmentation\nof the image; there is no notion of (having to align with) macroblocks. This makes it easy\nto effectively use different context models for different regions of the image.\n\n\n## FUIF Design Principles\n\nThe following goals or principles have guided the design of FUIF:\n\n* FUIF is an __image format, not a container__. FUIF stores pixels and the metadata needed to\nrender the image, but that's it. Anything else, like Exif metadata, comments,\nrotation, crop coordinates, layers, tiling, image sequences, and so on is a task\nfor the container format (e.g. HEIF), not for the image format.\nFUIF does support simple 'filmstrip' animation, so it can be used to recompress GIF and APNG,\nbut it is not a video codec.\n_Rationale: this is a matter of separation of concerns, as well as avoiding duplication of functionality.\nFor simple animations, FUIF might be suitable, but in general we think that most animations\nshould be encoded as a short (looping) video\n(taking advantage of inter-frame prediction, which is out of the scope of an image format)._\n\n* FUIF is optimized for __delivery__, not storage. It is progressive / \"responsive by design\". One single file\ncan be used instead of having to downscale a high-resolution original to various target resolutions.\nThe bitstream does not require seeking and a meaningful placeholder/preview can be shown from the first few\nhundred bytes. Perhaps it is possible to achieve better compression density and/or faster encoding by not\noptimizing for delivery (e.g. by predicting DC from AC like Lepton does).\nIf the use case is (essentially) write-only archival then maybe it is worth it to sacrifice progressive decoding,\nand FUIF can in principle be used in such a way, but that's not the primary target.\n_Rationale: the variety of display devices (from smart watches to huge 8K screens) and network conditions\n(from 2G on the road in rural areas to very high speed at home) is a huge challenge.\nMaking many files for the same image is not the best approach, e.g. in terms of CDN cache hits.\nMoreover browsers get few opportunities to be smart and adjust the image resolution and quality\nautomatically based on the device and network conditions. Non-progressive image formats result\nin a bad user experience when bandwidth is an issue._\n\n* __'Honest' compression artifacts__.\nThere are various approaches to how to do lossy compression. Different techniques lead to different artifacts.\nSome artifacts are less \"annoying\" than other artifacts. For example, blurring, smearing and mild ringing are probably\nnot very annoying (or even desireable to some, because it might eliminate noise and increase perceived sharpness),\nwhile pixelation, blockiness and color banding are annoying and obvious compression artifacts.\nAlso, some artifacts are not very \"honest\", in the sense that the image looks deceptively better than\nit actually is. For example, JBIG2 in lossy mode or HEIC at low bitrates can produce images that look like they\nare high-quality (e.g. they have sharp details at the pixel level),\nbut they are actually very different from the uncompressed image.\nFor example, JPEG artifacts are \"honest\" and \"annoying\", while WebP and HEIC artifacts are \"not honest\" and \"not annoying\".\nFUIF aims for compression artifacts that are \"honest\" and \"not annoying\". At low bitrates, pixelation will become\nobvious at a 1:1 scale, but the overall image fidelity will still be as high as possible\n(e.g. comparing a downscaled lossy FUIF image to a downscaled original).\n_Rationale: this is a matter of preference, but we think that image fidelity is more important than hiding the fact\nthat lossy compression was used. An image format should not act as an artistic filter that modifies an image more than\nnecessary. At least that's our opinion._\n\n* FUIF is royalty __free__ and it has a reference implementation that is free and open source software.\n_Rationale: we don't want no patent mess, please._\n\n* FUIF is __legacy-friendly__ but not backwards compatible.\nUnlike JPEG XT, the FUIF bitstream is completely different from legacy JPEG, so it is not backwards compatible\n(cannot be read by existing JPEG decoders). But unlike most other recent image formats (e.g. WebP, HEIC, AVIF),\nexisting JPEG images can be converted losslessly and effectively to FUIF,\npotentially with added information like alpha or depth channels.\n_Rationale: backwards compatibility is obviously convenient, but it has serious downsides.\nIt implies that the compression density cannot be improved compared to legacy JPEG.\nIt also means that none of the new features (like e.g. alpha) are guaranteed to be rendered correctly,\nsince (at least initially) most decoders will ignore any extensions of the legacy JPEG bitstream.\nSo for these reasons, not being backwards compatible is a better choice.\nHowever it is nice to be able to transcode existing JPEG images to FUIF without generation loss and while saving bytes._\n\n\n## TL;DR feature summary\n\n* Lossless and lossy, works well for photographic and non-photographic\n* Arbitrary number of channels (grayscale, RGB, CMYK, RGBA, CMYKA, CMYKA+depth, etc)\n* Bit depth up to 28-bit, arbitrary actual ranges of pixel values\n* Progressive/Responsive by design: single-file responsive images\n* Minimal header overhead, so LQIP in say a 200-byte budget is possible\n* Backwards compatible with JPEG (can losslessly and efficiently represent legacy JPEG files)\n* Adjustable trade-off between encode/decode complexity and compression density\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudinary%2Ffuif","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudinary%2Ffuif","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudinary%2Ffuif/lists"}