{"id":22281262,"url":"https://github.com/devolutions/gfwx-rs","last_synced_at":"2025-07-28T20:30:34.437Z","repository":{"id":55897432,"uuid":"156907530","full_name":"Devolutions/gfwx-rs","owner":"Devolutions","description":"GFWX: Good, Fast Wavelet Codec (Rust)","archived":false,"fork":false,"pushed_at":"2022-12-08T21:23:06.000Z","size":6137,"stargazers_count":13,"open_issues_count":0,"forks_count":3,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-07-20T06:54:26.112Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Devolutions.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null}},"created_at":"2018-11-09T19:18:41.000Z","updated_at":"2025-03-28T11:33:09.000Z","dependencies_parsed_at":"2023-01-25T07:46:42.498Z","dependency_job_id":null,"html_url":"https://github.com/Devolutions/gfwx-rs","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/Devolutions/gfwx-rs","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fgfwx-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fgfwx-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fgfwx-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fgfwx-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Devolutions","download_url":"https://codeload.github.com/Devolutions/gfwx-rs/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Devolutions%2Fgfwx-rs/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267580457,"owners_count":24110844,"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","status":"online","status_checked_at":"2025-07-28T02:00:09.689Z","response_time":68,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":[],"created_at":"2024-12-03T16:16:32.850Z","updated_at":"2025-07-28T20:30:33.856Z","avatar_url":"https://github.com/Devolutions.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# gfwx-rs\n\n[![crates.io](https://img.shields.io/crates/v/gfwx.svg)](https://crates.io/crates/gfwx)\n[![docs](https://docs.rs/gfwx/badge.svg)](https://docs.rs/gfwx)\n[![build](https://travis-ci.com/vaffeine/gfwx-rs.svg?branch=master)](https://travis-ci.com/vaffeine/gfwx-rs)\n[![codecov](https://codecov.io/gh/vaffeine/gfwx-rs/branch/master/graph/badge.svg)](https://codecov.io/gh/vaffeine/gfwx-rs/branch/master)\n\nImplementation of [GFWX](http://www.gfwx.org/) image compression algorithm developed by Graham Fyffe.\nLibrary uses [rayon](https://github.com/rayon-rs/rayon) for parallelization as a default feature.\n\n## Getting Started\n\n### Prerequisites\n\nTo use the library you need to have Rust installed on your machine. The library works on stable Rust branch and doesn't require nightly.\n\n### Using\n\ngfwx-rs is available on crates.io. The recommended way to use it is to add a line into your Cargo.toml such as:\n```toml\n[dependencies]\ngfwx = \"0.2\"\n```\n\nor, if you don't want to use rayon:\n```toml\n[dependencies]\ngfwx = { version = \"0.2\", default-features = false }\n```\n\nBasic usage for compression:\n\n```rust\nextern crate gfwx;\n\nfn main() {\n    let image = ...;\n\n    let builder = gfwx::HeaderBuilder {\n        width: image.width(),\n        height: image.height(),\n        layers: 1,\n        channels: image.channels(),\n        quality: gfwx::QUALITY_MAX,\n        chroma_scale: 8,\n        block_size: gfwx::BLOCK_DEFAULT,\n        filter: gfwx::Filter::Linear,\n        encoder: gfwx::Encoder::Turbo,\n        intent: gfwx::Intent::RGBA,\n        metadata_size: 0,\n    };\n    let header = builder.build().unwrap();\n\n    let buffer = vec![0; 2 * image.len()]; // 2 times original size should always be enough\n    header.encode(\u0026mut buffer)?;\n    let gfwx_size = gfwx::compress_simple(\n        image.as_slice(),\n        \u0026header,\n        \u0026gfwx::ColorTransformProgram::new(), // no color transform\n        \u0026mut buffer,\n    ).unwrap();\n    buffer.truncate(gfwx_size);\n}\n```\n\nBasic usage for decompression:\n\n```rust\nextern crate gfwx;\n\nfn main() {\n    let mut compressed = ...;\n\n    let header = gfwx::Header::decode(\u0026mut compressed).unwrap();\n\n    let mut decompressed = vec![0; header.get_estimated_decompress_buffer_size()];\n    let next_point_of_interest = gfwx::decompress_simple(\n        \u0026mut compressed,\n        \u0026header,\n        0, // no downsamping\n        false, // do not test, full decompress\n        \u0026mut decompressed,\n    ).unwrap();\n\n    ...\n}\n```\n\n## Running the tests\n\n### Unit tests\n\nTo run unit tests:\n```bash\ncargo test\n```\n\nThere are also tests for the case when build should fail. You can run them with\n```bash\ncargo test --features test_build_fails\n```\n\n### Functional tests\nTo run functional tests, that use actual images, you can use `ci/func_tests.sh`:\n```bash\nci/func_tests.sh ci/test_images/\n```\n\nThis command will build reference application, build examples and run functional tests\nusing prepared images in `ci/test_images/` folder in the `/tmp/gfwx` directory\n(so working directory stays clean).\n\n### Benchmarks\n\nThere are also [criterion](https://github.com/japaric/criterion.rs) benchmarks which you can run with\n```bash\ncargo bench\n```\n\n### Examples\n\nExamples folder contains 3 applications:\n1. `compress` - compresses an input image to gfwx\n2. `decompress` - decompresses a gfwx file\n3. `compare` - compares two images excluding metadata. Useful for comparing the input image and the decompressed one, because they may have the same \"pixels\" but different metadata, which means these files will have different checksum\n\n## Features\n\nLibrary supports all features of original implementation except:\n- It only supports u8 data, when original implementation supports 8-bit and 16-bit data both signed and unsigned\n- Bayer mode is not supported\n\nHowever, original implementation supports only channels in interleaved format (for example, [R1, G1, B1, R2, B2, G2, ...]) and always transform channels to planar format.\nThis is not suitable for color spaces which already use planar channel format (for example, YUV420).\n\nFor this type of data, our library provides low-level `compress_aux_data` and `decompress_aux_data` functions.\nThis functions do not encode header, execute and encode ColorTransformProgram and accept 16-bit image data in planar channels format with boost already applied.\n\nThese functions are a little bit more complex to use, but provide more flexibility in case you need only image data compression and decompression.\nYou can manually encode the header with `Header::encode()`, encode `ColorTransformProgram` with `ColorTransformProgram::encode()`\nand execute it and apply boost with `ColorTransformProgram::transform()` (for planar channels) and `ColorTransformProgram::transform_and_to_planar()` (for interleaved channels).\nAlso, instead of using `ColorTransformProgram` you can use `interleaved_to_planar()` and `planar_to_interleaved()` that also can skip some channels during transformation (for example, skip Alpha channel in RGBA).\n\nYou can find a complete example on how to use these functions in `examples/test_app.rs` or by looking into `compress_simple` and `decompress_simple` implementation in `src/lib.rs`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevolutions%2Fgfwx-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevolutions%2Fgfwx-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevolutions%2Fgfwx-rs/lists"}