TinyGPU
Loading...
Searching...
No Matches
BMPExporter.h
Go to the documentation of this file.
1#pragma once
2
3#include <stddef.h>
4#include <stdint.h>
5
6#include "ISurface.h"
7#include "Print.h"
8
9namespace tinygpu {
10
11/**
12 * @brief Writes TinyGPU surfaces as uncompressed 24-bit BMP data.
13 *
14 * The exporter serializes any ISurface-compatible surface to a standard BMP
15 * stream using bottom-up BGR pixel rows padded to 4-byte boundaries.
16 */
17template <typename RGB_T = RGB565>
19public:
20 BMPExporter(const ISurface<RGB_T>& surface) : surface_(surface) {}
21
22 /// Writes the target surface as BMP data to the provided Print output.
23 bool save(Print& out) const {
24 const size_t width = surface_.width();
25 const size_t height = surface_.height();
26 if (width == 0 || height == 0) {
27 return false;
28 }
29
30 const uint32_t rowStride = bmpRowStride(width);
31 const uint32_t imageSize = rowStride * static_cast<uint32_t>(height);
32 const uint32_t pixelOffset = 54;
33 const uint32_t fileSize = pixelOffset + imageSize;
34
35 if (!writeFileHeader(out, fileSize, pixelOffset) ||
36 !writeInfoHeader(out, width, height, imageSize)) {
37 return false;
38 }
39
40 const uint8_t padding[3] = {0, 0, 0};
41 const size_t paddingSize = rowStride - (width * 3U);
42
43 for (size_t row = height; row > 0; --row) {
44 const size_t y = row - 1;
45 for (size_t x = 0; x < width; ++x) {
46 const RGB_T color = surface_.getPixel(x, y);
47 const uint8_t pixel[3] = {color.getBlue(), color.getGreen(),
48 color.getRed()};
49 if (!writeBytes(out, pixel, sizeof(pixel))) {
50 return false;
51 }
52 }
53
54 if (paddingSize != 0 && !writeBytes(out, padding, paddingSize)) {
55 return false;
56 }
57 }
58
59 return true;
60 }
61
62 protected:
63 const ISurface<RGB_T>& surface_;
64
65 static uint32_t bmpRowStride(size_t width) {
66 return static_cast<uint32_t>(((width * 3U) + 3U) & ~0x3U);
67 }
68
69 static bool writeFileHeader(Print& out, uint32_t fileSize,
70 uint32_t pixelOffset) {
71 return writeU16(out, 0x4D42) && writeU32(out, fileSize) &&
72 writeU16(out, 0) && writeU16(out, 0) && writeU32(out, pixelOffset);
73 }
74
75 static bool writeInfoHeader(Print& out, size_t width, size_t height,
76 uint32_t imageSize) {
77 return writeU32(out, 40) && writeU32(out, static_cast<uint32_t>(width)) &&
78 writeU32(out, static_cast<uint32_t>(height)) && writeU16(out, 1) &&
79 writeU16(out, 24) && writeU32(out, 0) && writeU32(out, imageSize) &&
80 writeU32(out, 2835) && writeU32(out, 2835) && writeU32(out, 0) &&
81 writeU32(out, 0);
82 }
83
84 static bool writeU16(Print& out, uint16_t value) {
85 const uint8_t bytes[2] = {static_cast<uint8_t>(value & 0xFFU),
86 static_cast<uint8_t>((value >> 8) & 0xFFU)};
87 return writeBytes(out, bytes, sizeof(bytes));
88 }
89
90 static bool writeU32(Print& out, uint32_t value) {
91 const uint8_t bytes[4] = {static_cast<uint8_t>(value & 0xFFU),
92 static_cast<uint8_t>((value >> 8) & 0xFFU),
93 static_cast<uint8_t>((value >> 16) & 0xFFU),
94 static_cast<uint8_t>((value >> 24) & 0xFFU)};
95 return writeBytes(out, bytes, sizeof(bytes));
96 }
97
98 static bool writeBytes(Print& out, const uint8_t* data, size_t length) {
99 return length == 0 || out.write(data, length) == length;
100 }
101};
102
103} // namespace tinygpu
Writes TinyGPU surfaces as uncompressed 24-bit BMP data.
Definition: BMPExporter.h:18
static bool writeU16(Print &out, uint16_t value)
Definition: BMPExporter.h:84
static bool writeBytes(Print &out, const uint8_t *data, size_t length)
Definition: BMPExporter.h:98
bool save(Print &out) const
Writes the target surface as BMP data to the provided Print output.
Definition: BMPExporter.h:23
const ISurface< RGB_T > & surface_
Definition: BMPExporter.h:63
static bool writeFileHeader(Print &out, uint32_t fileSize, uint32_t pixelOffset)
Definition: BMPExporter.h:69
BMPExporter(const ISurface< RGB_T > &surface)
Definition: BMPExporter.h:20
static bool writeInfoHeader(Print &out, size_t width, size_t height, uint32_t imageSize)
Definition: BMPExporter.h:75
static bool writeU32(Print &out, uint32_t value)
Definition: BMPExporter.h:90
static uint32_t bmpRowStride(size_t width)
Definition: BMPExporter.h:65
RGB color stored in 16-bit RGB565 format.
Definition: RGB565.h:13
Definition: AVIWriter.h:9