{"id":15551712,"url":"https://github.com/toruniina/pnm","last_synced_at":"2025-04-15T16:56:37.577Z","repository":{"id":48354639,"uuid":"137644009","full_name":"ToruNiina/pnm","owner":"ToruNiina","description":"pbm, pgm, ppm image IO for modern C++ (single header only library)","archived":false,"fork":false,"pushed_at":"2024-05-21T12:29:13.000Z","size":728,"stargazers_count":23,"open_issues_count":0,"forks_count":10,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-28T22:41:51.370Z","etag":null,"topics":["c-plus-plus","image","pbm","pgm","pnm","ppm"],"latest_commit_sha":null,"homepage":"https://app.gitbook.com/@niina-toru/s/pnm/","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/ToruNiina.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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,"publiccode":null,"codemeta":null}},"created_at":"2018-06-17T09:42:15.000Z","updated_at":"2025-03-16T11:06:06.000Z","dependencies_parsed_at":"2024-05-21T13:44:19.257Z","dependency_job_id":"c2cb1231-56b9-4d55-9f80-19c59c6cb2c1","html_url":"https://github.com/ToruNiina/pnm","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/ToruNiina%2Fpnm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ToruNiina%2Fpnm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ToruNiina%2Fpnm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ToruNiina%2Fpnm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ToruNiina","download_url":"https://codeload.github.com/ToruNiina/pnm/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249116137,"owners_count":21215140,"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":["c-plus-plus","image","pbm","pgm","pnm","ppm"],"created_at":"2024-10-02T14:06:36.006Z","updated_at":"2025-04-15T16:56:37.546Z","avatar_url":"https://github.com/ToruNiina.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pnm++\n\n[![Build Status](https://travis-ci.com/ToruNiina/pnm.svg?branch=master)](https://travis-ci.com/ToruNiina/pnm)\n[![version](https://img.shields.io/github/release/ToruNiina/pnm.svg?style=flat)](https://github.com/ToruNiina/pnm/releases)\n[![license](https://img.shields.io/github/license/ToruNiina/pnm.svg?style=flat)](https://github.com/ToruNiina/pnm/blob/master/LICENSE)\n\nheader-only, standalone pnm image reader/writer for modern C++ (after C++11).\n\nIt has no dependencies except for C++ Standard Library.\n\nthe interfaces are inspired by png++.\n\n## installation\n\ncopy `pnm.hpp` to your favorite location. then use it.\n\n## example\n\n```cpp\n#include \u003cpnm++/pnm.hpp\u003e\n#include \u003ciostream\u003e\n\nint main()\n{\n    using namespace pnm::literals;\n    pnm::image\u003cpnm::rgb_pixel\u003e ppm = pnm::read(\"sample.ppm\");\n\n    std::cout \u003c\u003c \"width  = \" \u003c\u003c ppm.width()  \u003c\u003c std::endl;\n    std::cout \u003c\u003c \"height = \" \u003c\u003c ppm.height() \u003c\u003c std::endl;\n\n    for(std::size_t y=0; y\u003cppm.y_size(); ++y)\n    {\n        for(std::size_t x=0; x\u003cppm.x_size(); ++x)\n        {\n            ppm[y][x] = 0xFF00FF_rgb;\n        }\n    }\n    pnm::write(\"out.ppm\", ppm, pnm::format::binary);\n\n    return 0;\n}\n```\n\n## build samples and test codes\n\nTo use this library, you don't need to build anything.\nThe following commands will build the sample scripts.\n\n```sh\n$ mkdir build\n$ cd build\n$ cmake ..\n$ make\n```\n\n## reference\n\n### pixels\n\n`pixel` classes are aliases of `basic_pixel`.\nFor the convenience, `basic_pixel\u003cT, 3\u003e` is specialized to have members named\n`red`, `green`, and `blue`.\n\n#### synopsis\n\n```cpp\ntemplate\u003ctypename T, std::size_t N\u003e\nstruct basic_pixel;\n\ntemplate\u003ctypename T\u003e\nstruct basic_pixel\u003cT, 1\u003e\n{\n  public:\n    using value_type = T;\n    static constexpr std::size_t colors = 1;\n\n    basic_pixel()  = default;\n    ~basic_pixel() = default;\n    basic_pixel(const basic_pixel\u0026) = default;\n    basic_pixel(basic_pixel\u0026\u0026)      = default;\n    basic_pixel\u0026 operator=(const basic_pixel\u0026) = default;\n    basic_pixel\u0026 operator=(basic_pixel\u0026\u0026)      = default;\n\n// noexcept if T is nothrow constructible\n    basic_pixel(const value_type\u0026 v);\n    basic_pixel(value_type\u0026\u0026 v);\n\n    value_type value;\n};\n\ntemplate\u003ctypename T\u003e\nstruct basic_pixel\u003cT, 3\u003e\n{\n  public:\n    using value_type = T;\n    static constexpr std::size_t colors = 3;\n\n    basic_pixel()  = default;\n    ~basic_pixel() = default;\n    basic_pixel(const basic_pixel\u0026) = default;\n    basic_pixel(basic_pixel\u0026\u0026)      = default;\n    basic_pixel\u0026 operator=(const basic_pixel\u0026) = default;\n    basic_pixel\u0026 operator=(basic_pixel\u0026\u0026)      = default;\n\n// noexcept if T is nothrow constructible\n    basic_pixel(const value_type\u0026 R, const value_type\u0026 G, const value_type\u0026 B);\n    basic_pixel(value_type\u0026\u0026      R, value_type\u0026\u0026      G, value_type\u0026\u0026      B);\n    basic_pixel(const std::array\u003cvalue_type, 3\u003e\u0026 values);\n\n    value_type red;\n    value_type green;\n    value_type blue;\n};\n\nusing  bit_pixel = basic_pixel\u003cbool,         1\u003e;\nusing gray_pixel = basic_pixel\u003cstd::uint8_t, 1\u003e;\nusing  rgb_pixel = basic_pixel\u003cstd::uint8_t, 3\u003e;\n\nnamespace literals\n{\ninline namespace pixel_literals\n{\nbit_pixel  operator\"\" _bit (unsigned long long x);\ngray_pixel operator\"\" _gray(unsigned long long x);\nrgb_pixel  operator\"\" _rgb (unsigned long long x);\n}\n}\n\ntemplate\u003ctypename T\u003e struct is_pixel;\ntemplate\u003ctypename From, typename To\u003e struct is_narrowing_conversion;\n\ntemplate\u003ctypename ToPixel, typename FromPixel\u003e\nToPixel convert_to(FromPixel\u0026\u0026 pixel);\n```\n\n### image\n\n`image` provides a proxy class that enables line-by-line access to underlying\nsequence container(`std::vector`). It contains `pnm::pixel`s as a contiguous\narray for cache locality and provides `img[y][x]` access at the same time.\n\nIt also supports constructor from\n`width, height, std::vector\u003c/* convertible-to-pixel */\u003e` or\n`std::vector\u003cstd::vector\u003c/* convertible-to-pixel */\u003e\u003e`.\n\nThe proxy class allows you to access the pixel in the form like `img[y][x]` or\n`img.at(y).at(x)`. It also allows you to loop line-by-line and pixel-by-pixel.\n\n```cpp\npnm::image\u003cpnm::rgb_pixel\u003e img;\nfor(const auto line : img.lines())\n{\n    for(const auto pixel : line)\n    {\n        std::cout \u003c\u003c '(' \u003c\u003c pixel.red \u003c\u003c ' ' \u003c\u003c pixel.green \u003c\u003c ' '\n                  \u003c\u003c pixel.blue \u003c\u003c ')';\n    }\n}\n```\n\nAnd you can also substitute `line_proxy` to other `line_proxy`.\n\n```cpp\npnm::image\u003cpnm::rgb_pixel\u003e img1(100, 100);\npnm::image\u003cpnm::rgb_pixel\u003e img2(100, 100);\n\n// reverse img1\nfor(std::size_t i=0; i\u003c100; ++i)\n{\n    img2[i] = img1[99 - i];\n}\n```\n\n#### synopsis\n\n```cpp\ntemplate\u003ctypename Pixel, typename Alloc = std::allocator\u003cPixel\u003e\u003e\nclass image\n{\n  public:\n    using pixel_type                = Pixel;\n    using allocator_type            = Alloc;\n    using container_type            = std::vector\u003cpixel_type, allocator_type\u003e;\n    using size_type                 = typename container_type::size_type;\n    using difference_type           = typename container_type::difference_type;\n    using value_type                = typename container_type::value_type;\n    using pointer                   = typename container_type::pointer;\n    using const_pointer             = typename container_type::const_pointer;\n    using reference                 = typename container_type::reference;\n    using const_reference           = typename container_type::const_reference;\n    using iterator                  = typename container_type::iterator;\n    using const_iterator            = typename container_type::const_iterator;\n    using reverse_iterator          = typename container_type::reverse_iterator;\n    using const_reverse_iterator    = typename container_type::const_reverse_iterator;\n    using line_proxy                = /* internal proxy class */\n    using const_line_proxy          = /* internal proxy class */\n    using line_proxy_iterator       = /* internal proxy class */\n    using const_line_proxy_iterator = /* internal proxy class */\n    using line_range                = /* internal proxy class */\n    using const_line_range          = /* internal proxy class */\n\n    image()  = default;\n    ~image() = default;\n    image(const image\u0026) = default;\n    image(image\u0026\u0026)      = default;\n    image\u0026 operator=(const image\u0026) = default;\n    image\u0026 operator=(image\u0026\u0026)      = default;\n\n    image(const std::size_t width, const std::size_t height);\n    image(const std::size_t width, const std::size_t height, const pixel_type\u0026 pix);\n\n    template\u003ctypename T\u003e\n    image(const std::size_t width, const std::size_t height, const std::vector\u003cT\u003e\u0026 values)\n    template\u003ctypename T\u003e\n    image(const std::vector\u003cstd::vector\u003cT\u003e\u003e\u0026 values)\n\n    line_proxy       operator[](const std::size_t i)       noexcept;\n    const_line_proxy operator[](const std::size_t i) const noexcept;\n\n    line_proxy       at(const std::size_t i);\n    const_line_proxy at(const std::size_t i) const;\n\n    reference       operator()(const std::size_t ix, const std::size_t iy)       noexcept;\n    const_reference operator()(const std::size_t ix, const std::size_t iy) const noexcept;\n\n    reference       at(const std::size_t ix, const std::size_t iy);\n    const_reference at(const std::size_t ix, const std::size_t iy) const;\n\n    reference       raw_access(const std::size_t i)       noexcept;\n    const_reference raw_access(const std::size_t i) const noexcept;\n    reference       raw_at(const std::size_t i);\n    const_reference raw_at(const std::size_t i) const;\n\n    std::size_t width()  const noexcept;\n    std::size_t height() const noexcept;\n    std::size_t x_size() const noexcept;\n    std::size_t y_size() const noexcept;\n    std::size_t size()   const noexcept;\n\n    iterator       begin()        noexcept;\n    iterator       end()          noexcept;\n    const_iterator begin()  const noexcept;\n    const_iterator end()    const noexcept;\n    const_iterator cbegin() const noexcept;\n    const_iterator cend()   const noexcept;\n\n    reverse_iterator       rbegin()        noexcept;\n    reverse_iterator       rend()          noexcept;\n    const_reverse_iterator rbegin()  const noexcept;\n    const_reverse_iterator rend()    const noexcept;\n    const_reverse_iterator crbegin() const noexcept;\n    const_reverse_iterator crend()   const noexcept;\n\n    line_proxy_iterator       line_begin()        noexcept;\n    line_proxy_iterator       line_end()          noexcept;\n    const_line_proxy_iterator line_begin()  const noexcept;\n    const_line_proxy_iterator line_end()    const noexcept;\n    const_line_proxy_iterator line_cbegin() const noexcept;\n    const_line_proxy_iterator line_cend()   const noexcept;\n\n    line_range       lines()       noexcept;\n    const_line_range lines() const noexcept;\n};\n\nusing pbm_image = image\u003c bit_pixel\u003e;\nusing pgm_image = image\u003cgray_pixel\u003e;\nusing ppm_image = image\u003c rgb_pixel\u003e;\n```\n\n### io\n\n`read()` and `read_(pbm|pgm|ppm)` functions read a file header and\nautomatically detects the file format. `read()` function receives `pixel_type`\nthat you want to get(By default, it is `rgb_pixel`). But please note that when\nyou pass a `pixel_type` that is different from actual one contained in the file,\n`read()` converts the `pixel_type` if it is not `narrowing-conversion` (for\nexample, conversion from `bit_pixel` to `rgb_pixel` is allowed. On the other\nhand, the opposite conversion is not allowed).\n\n`write` function writes the image file into a specific file. You can select a\nformat to write out by passing an enum value `pnm::format::ascii` or\n`pnm::format::binary`.\n\n#### synopsis\n\n```cpp\nenum class format: bool {ascii, binary};\n\ntemplate\u003ctypename Pixel = rgb_pixel, typename Alloc = std::allocator\u003cPixel\u003e\u003e\nimage\u003cPixel, Alloc\u003e read(const std::string\u0026 fname);\ntemplate\u003ctypename Pixel, typename Alloc\u003e\nvoid write(const std::string\u0026 fname, const image\u003cPixel, Alloc\u003e\u0026 img, const format fmt);\n\ntemplate\u003ctypename Alloc = std::allocator\u003cbit_pixel\u003e\u003e\nimage\u003cbit_pixel, Alloc\u003e  read_pbm(const std::string\u0026 fname);\ntemplate\u003ctypename Alloc = std::allocator\u003cgray_pixel\u003e\u003e\nimage\u003cgray_pixel, Alloc\u003e read_pgm(const std::string\u0026 fname);\ntemplate\u003ctypename Alloc = std::allocator\u003crgb_pixel\u003e\u003e\nimage\u003crgb_pixel, Alloc\u003e  read_ppm(const std::string\u0026 fname);\n\n\ntemplate\u003ctypename Alloc = std::allocator\u003cbit_pixel\u003e\u003e\nimage\u003cbit_pixel, Alloc\u003e read_pbm_ascii(const std::string\u0026 fname);\ntemplate\u003ctypename Alloc = std::allocator\u003cbit_pixel\u003e\u003e\nimage\u003cbit_pixel, Alloc\u003e read_pbm_binary(const std::string\u0026 fname);\n\ntemplate\u003ctypename Alloc = std::allocator\u003cgray_pixel\u003e\u003e\nimage\u003cgray_pixel, Alloc\u003e read_pgm_ascii(const std::string\u0026 fname);\ntemplate\u003ctypename Alloc = std::allocator\u003cgray_pixel\u003e\u003e\nimage\u003cgray_pixel, Alloc\u003e read_pgm_binary(const std::string\u0026 fname);\n\ntemplate\u003ctypename Alloc = std::allocator\u003crgb_pixel\u003e\u003e\nimage\u003crgb_pixel, Alloc\u003e read_ppm_ascii(const std::string\u0026 fname);\ntemplate\u003ctypename Alloc = std::allocator\u003crgb_pixel\u003e\u003e\nimage\u003crgb_pixel, Alloc\u003e read_ppm_binary(const std::string\u0026 fname);\n\n\ntemplate\u003ctypename Alloc\u003e\nvoid write_pbm(const std::string\u0026 fname, const image\u003cbit_pixel, Alloc\u003e\u0026 img, const format fmt);\ntemplate\u003ctypename Alloc\u003e\nvoid write_pgm(const std::string\u0026 fname, const image\u003cgray_pixel, Alloc\u003e\u0026 img, const format fmt);\ntemplate\u003ctypename Alloc\u003e\nvoid write_ppm(const std::string\u0026 fname, const image\u003crgb_pixel, Alloc\u003e\u0026 img, const format fmt);\n\ntemplate\u003ctypename Alloc\u003e\nvoid write_pbm_ascii (const std::string\u0026 fname, const image\u003cbit_pixel, Alloc\u003e\u0026 img);\ntemplate\u003ctypename Alloc\u003e\nvoid write_pbm_binary(const std::string\u0026 fname, const image\u003cbit_pixel, Alloc\u003e\u0026 img);\n\ntemplate\u003ctypename Alloc\u003e\nvoid write_pgm_ascii (const std::string\u0026 fname, const image\u003cgray_pixel, Alloc\u003e\u0026 img);\ntemplate\u003ctypename Alloc\u003e\nvoid write_pgm_binary(const std::string\u0026 fname, const image\u003cgray_pixel, Alloc\u003e\u0026 img);\n\ntemplate\u003ctypename Alloc\u003e\nvoid write_ppm_ascii (const std::string\u0026 fname, const image\u003crgb_pixel, Alloc\u003e\u0026 img);\ntemplate\u003ctypename Alloc\u003e\nvoid write_ppm_binary(const std::string\u0026 fname, const image\u003crgb_pixel, Alloc\u003e\u0026 img);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoruniina%2Fpnm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftoruniina%2Fpnm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftoruniina%2Fpnm/lists"}