{"id":15049306,"url":"https://github.com/kikuchan/pngle","last_synced_at":"2025-10-25T18:48:57.289Z","repository":{"id":42977961,"uuid":"203041100","full_name":"kikuchan/pngle","owner":"kikuchan","description":"Pngle - PNG Loader for Embedding","archived":false,"fork":false,"pushed_at":"2024-04-20T05:58:37.000Z","size":158,"stargazers_count":116,"open_issues_count":3,"forks_count":21,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-02-02T17:42:44.395Z","etag":null,"topics":["arduino","c","c99","esp32","esp8266","m5stack","mbed","png","png-decoder","stm32"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"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/kikuchan.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,"dei":null}},"created_at":"2019-08-18T18:21:24.000Z","updated_at":"2025-01-30T17:48:14.000Z","dependencies_parsed_at":"2024-04-19T04:21:24.464Z","dependency_job_id":"80d09c1b-3928-457c-9c08-c63000a34dbc","html_url":"https://github.com/kikuchan/pngle","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuchan%2Fpngle","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuchan%2Fpngle/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuchan%2Fpngle/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kikuchan%2Fpngle/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kikuchan","download_url":"https://codeload.github.com/kikuchan/pngle/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239114224,"owners_count":19583985,"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":["arduino","c","c99","esp32","esp8266","m5stack","mbed","png","png-decoder","stm32"],"created_at":"2024-09-24T21:19:40.085Z","updated_at":"2025-10-25T18:48:57.284Z","avatar_url":"https://github.com/kikuchan.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"Pngle\n=====\n\nThis is a stream based portable **PNG** **L**oader for **E**mbedding, **Pngle**.\n\n## Background\n\nBasically PNG is a memory consuming format from an embedded system perspective, especially on decoding, it mandatory require 32KiB working memory for a sliding window of Deflate, and a scanline buffer (its size depend on image width \u0026 format) to reconstruct the image, at least.\nUnfortunately, due to the memory requirements, we could say traditional Arduino boards, that uses ATmega328 or ATmega32U4 for example, lack of ability to decode standard PNG images.\n\nToday, we have variety of SoC boards for embedded systems or Arduino that have enough memory to decode PNG images, but we need to be concerned about memory consumption sometimes.\nWhile there are many other PNG decoders, some of them always require the full size of frame-buffer, some of them don't but do require using complicated APIs instead, and some of them are hard to use in Arduino because of deep dependency.\nThis is why I reinvent the wheel for my own.\n\n## Features \u0026 Restrictions\n\n- **All standard types of PNG files are supported**\n\t- Interlaced files are also supported\n\t- Tested with PngSuite\n- Easy to use\n\t- **Simple API**\n\t\t- Feed PNG binary data with `pngle_feed` API (in the same way as `write` syscall)\n\t- A super simple single callback interface is used to draw an image\n\t\t- You need to render pixel-by-pixel (it's neither line-by-line nor frame-by-frame)\n\t\t- Pixel values are always normalized to 8bits/ch x 4ch for convenience (even if they are indexed, grayscaled, ... or 16bits/ch)\n\t\t- Drawing x and y values are passed via the interface, so...\n\t\t\t- You can roughly resize an image on-the-fly by adjusting drawing x and y values\n\t\t\t- You can draw an interlaced image as soon as possible (x and y values occur in Adam7 sequence)\n- Easy to embed\n\t- **Reasonably small memory footprint** on runtime\n\t\t- Theoretical minimum scanline buffer (depends on width \u0026 format) + decompression working memory for Deflate (~43KiB) + α\n\t- **No frame-buffer required**\n\t\t- It simply renders pixel-by-pixel instead, mentioned above\n\t\t\t- If you prefer off-screen canvas, you can allocate the canvas by yourself and draw pixels to it\n\t- **Less dependency**\n\t\t- It only requires `miniz` (don't worry, battery included!)\n\t- **Portable**\n\t\t- Written in C99 with `stdint.h` (but not for `miniz` yet...)\n\t- MIT License\n- **Transparency support**\n\t- A value of transparency is always available as 4th channel of pixel\n\t\t- tRNS chunk is also supported\n\t- If you need full featured alpha-blending, you can implement it easily (as long as you could know its background source color value, and how to blend them)\n- **Gamma correction support** (gAMA chunk only)\n\t- You can activate the feature by calling `pngle_set_display_gamma` API with display gamma value (Typically 2.2)\n\t- It require additional memory (depends on image depth, 64KiB at most), math library (libm), and floating point arithmetic to generate gamma lookup table\n\t- You can remove the feature by defining `PNGLE_NO_GAMMA_CORRECTION` in case of emergency\n\n## Usage \u0026 How it works\n\n1. Allocate Pngle object by calling `pngle_new()`\n2. Setup draw callback by calling `pngle_set_draw_callback()`\n3. Feed PNG binary data by calling `pngle_feed()` until exhausted\n4. During the feeding, callback function `on_draw()` (for example) is called repeatedly\n5. In the `on_draw()` function, put the pixel on a screen (or wherever you want)\n6. Finally, you'll get an image\n\n## API\n\nSee [src/pngle.h](src/pngle.h)\n\n## Examples\n\n### Generic C\n```c\nvoid on_draw(pngle_t *pngle, uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint8_t rgba[4])\n{\n    uint8_t r = rgba[0]; // 0 - 255\n    uint8_t g = rgba[1]; // 0 - 255\n    uint8_t b = rgba[2]; // 0 - 255\n    uint8_t a = rgba[3]; // 0: fully transparent, 255: fully opaque\n\n    if (a) printf(\"put pixel at (%d, %d) with color #%02x%02x%02x\\n\", x, y, r, g, b);\n}\n\nint main(int argc, char *argv[])\n{\n    pngle_t *pngle = pngle_new();\n\n    pngle_set_draw_callback(pngle, on_draw);\n\n    // Feed data to pngle\n    char buf[1024];\n    int remain = 0;\n    int len;\n    while ((len = read(STDIN_FILENO, buf + remain, sizeof(buf) - remain)) \u003e 0) {\n        int fed = pngle_feed(pngle, buf, remain + len);\n        if (fed \u003c 0) errx(1, \"%s\", pngle_error(pngle));\n\n        remain = remain + len - fed;\n        if (remain \u003e 0) memmove(buf, buf + fed, remain);\n    }\n\n    pngle_destroy(pngle);\n\n    return 0;\n}\n```\n\nSee [examples/pngle-png2ppm/pngle-png2ppm.c](examples/pngle-png2ppm/pngle-png2ppm.c) for more practical example.\n\n\n### Arduino (for M5Stack)\n\nSee [examples/m5stack-png/m5stack-png.ino](examples/m5stack-png/m5stack-png.ino)\n\n\n## Author\n\nkikuchan / @kikuchan98\n\n\n## License\n\nMIT License\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkikuchan%2Fpngle","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkikuchan%2Fpngle","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkikuchan%2Fpngle/lists"}