NDDEM
TinyPngOut.hpp
Go to the documentation of this file.
1 /*
2  * Tiny PNG Output (C++)
3  *
4  * Copyright (c) 2018 Project Nayuki
5  * https://www.nayuki.io/page/tiny-png-output
6  *
7  * This program is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program (see COPYING.txt and COPYING.LESSER.txt).
19  * If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #pragma once
23 
24 #include <cstddef>
25 #include <cstdint>
26 #include <ostream>
27 
28 
29 /*
30  * Takes image pixel data in raw RGB8.8.8 format and writes a PNG file to a byte output stream.
31  */
32 class TinyPngOut final {
33 
34  /*---- Fields ----*/
35 
36  // Immutable configuration
37  private: std::uint32_t width; // Measured in pixels
38  private: std::uint32_t height; // Measured in pixels
39  private: std::uint32_t lineSize; // Measured in bytes, equal to (width * 3 + 1)
40 
41  // Running state
42  private: std::ostream &output;
43  private: std::uint32_t positionX; // Next byte index in current line
44  private: std::uint32_t positionY; // Line index of next byte
45  private: std::uint32_t uncompRemain; // Number of uncompressed bytes remaining
46  private: std::uint16_t deflateFilled; // Bytes filled in the current block (0 <= n < DEFLATE_MAX_BLOCK_SIZE)
47  private: std::uint32_t crc; // Primarily for IDAT chunk
48  private: std::uint32_t adler; // For DEFLATE data within IDAT
49 
50 
51 
52  /*---- Public constructor and method ----*/
53 
54  /*
55  * Creates a PNG writer with the given width and height (both non-zero) and byte output stream.
56  * TinyPngOut will leave the output stream still open once it finishes writing the PNG file data.
57  * Throws an exception if the dimensions exceed certain limits (e.g. w * h > 700 million).
58  */
59  public: explicit TinyPngOut(std::uint32_t w, std::uint32_t h, std::ostream &out);
60 
61 
62  /*
63  * Writes 'count' pixels from the given array to the output stream. This reads count*3
64  * bytes from the array. Pixels are presented from top to bottom, left to right, and with
65  * subpixels in RGB order. This object keeps track of how many pixels were written and
66  * various position variables. It is an error to write more pixels in total than width*height.
67  * Once exactly width*height pixels have been written with this TinyPngOut object,
68  * there are no more valid operations on the object and it should be discarded.
69  */
70  public: void write(const std::uint8_t pixels[], size_t count);
71 
72 
73 
74  /*---- Private checksum methods ----*/
75 
76  // Reads the 'crc' field and updates its value based on the given array of new data.
77  private: void crc32(const std::uint8_t data[], size_t len);
78 
79 
80  // Reads the 'adler' field and updates its value based on the given array of new data.
81  private: void adler32(const std::uint8_t data[], size_t len);
82 
83 
84 
85  /*---- Private utility members ----*/
86 
87  private: template <std::size_t N>
88  void write(const std::uint8_t (&data)[N]) {
89  output.write(reinterpret_cast<const char*>(data), sizeof(data));
90  }
91 
92 
93  private: static void putBigUint32(std::uint32_t val, std::uint8_t array[4]);
94 
95 
96  private: static constexpr std::uint16_t DEFLATE_MAX_BLOCK_SIZE = 65535;
97 
98 };
99 
Definition: TinyPngOut.hpp:32
std::uint32_t height
Definition: TinyPngOut.hpp:38
void write(const std::uint8_t(&data)[N])
Definition: TinyPngOut.hpp:88
std::uint32_t lineSize
Definition: TinyPngOut.hpp:39
void crc32(const std::uint8_t data[], size_t len)
Definition: TinyPngOut.cpp:182
std::uint32_t positionX
Definition: TinyPngOut.hpp:43
std::uint16_t deflateFilled
Definition: TinyPngOut.hpp:46
std::uint32_t adler
Definition: TinyPngOut.hpp:48
std::uint32_t width
Definition: TinyPngOut.hpp:37
std::uint32_t uncompRemain
Definition: TinyPngOut.hpp:45
void write(const std::uint8_t pixels[], size_t count)
Definition: TinyPngOut.cpp:99
std::uint32_t crc
Definition: TinyPngOut.hpp:47
void adler32(const std::uint8_t data[], size_t len)
Definition: TinyPngOut.cpp:194
TinyPngOut(std::uint32_t w, std::uint32_t h, std::ostream &out)
Definition: TinyPngOut.cpp:35
std::uint32_t positionY
Definition: TinyPngOut.hpp:44
static constexpr std::uint16_t DEFLATE_MAX_BLOCK_SIZE
Definition: TinyPngOut.hpp:96
std::ostream & output
Definition: TinyPngOut.hpp:42
static void putBigUint32(std::uint32_t val, std::uint8_t array[4])
Definition: TinyPngOut.cpp:205
int N
unsigned short uint16_t
Definition: stdint.h:125
unsigned int uint32_t
Definition: stdint.h:126
unsigned char uint8_t
Definition: stdint.h:124