MCPcopy Create free account
hub / github.com/Arm-Examples/ML-examples / ReadBmp24

Function ReadBmp24

ethos-u-corstone-1000/app/src/common/InputUtils.cpp:104–172  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

102}
103
104Image ReadBmp24(const std::string& bmpPath)
105{
106 std::ifstream bmpStream(bmpPath, std::ios::binary | std::ios::ate);
107 if (!bmpStream.is_open()) {
108 throw std::runtime_error("failed to open BMP file: " + bmpPath);
109 }
110
111 const auto fileSize = bmpStream.tellg();
112 if (fileSize < 0) {
113 throw std::runtime_error("failed to determine BMP file size: " + bmpPath);
114 }
115
116 std::vector<uint8_t> bytes(static_cast<size_t>(fileSize));
117 bmpStream.seekg(0, std::ios_base::beg);
118 bmpStream.read(reinterpret_cast<char*>(bytes.data()),
119 static_cast<std::streamsize>(bytes.size()));
120
121 if (static_cast<size_t>(bmpStream.gcount()) != bytes.size()) {
122 throw std::runtime_error("BMP payload size mismatch in: " + bmpPath);
123 }
124
125 constexpr size_t kBmpFileHeaderBytes = 14;
126 constexpr size_t kMinDibHeaderBytes = 40;
127 constexpr uint16_t kBmpMagic = 0x4D42;
128 constexpr uint16_t kRgbBitsPerPixel = 24;
129 constexpr uint32_t kNoCompression = 0;
130 if (bytes.size() < kBmpFileHeaderBytes + kMinDibHeaderBytes ||
131 ReadLe16(bytes, 0) != kBmpMagic) {
132 throw std::runtime_error("invalid BMP header: " + bmpPath);
133 }
134
135 const uint32_t pixelOffset = ReadLe32(bytes, 10);
136 const uint32_t dibBytes = ReadLe32(bytes, 14);
137 const int32_t width = ReadLeS32(bytes, 18);
138 const int32_t height = ReadLeS32(bytes, 22);
139 const uint16_t planes = ReadLe16(bytes, 26);
140 const uint16_t bpp = ReadLe16(bytes, 28);
141 const uint32_t compression = ReadLe32(bytes, 30);
142
143 if (dibBytes < kMinDibHeaderBytes || width <= 0 || height == 0 || planes != 1U ||
144 bpp != kRgbBitsPerPixel || compression != kNoCompression) {
145 throw std::runtime_error("only uncompressed 24-bit BMP input is supported: " + bmpPath);
146 }
147
148 const int absHeight = height < 0 ? -height : height;
149 const size_t rowBytes =
150 ((static_cast<size_t>(width) * static_cast<size_t>(bpp) + 31U) / 32U) * 4U;
151 const size_t requiredBytes = static_cast<size_t>(pixelOffset) +
152 rowBytes * static_cast<size_t>(absHeight);
153 if (requiredBytes > bytes.size()) {
154 throw std::runtime_error("BMP pixel data is truncated: " + bmpPath);
155 }
156
157 std::vector<uint8_t> rgb(static_cast<size_t>(width) * static_cast<size_t>(absHeight) * 3U);
158 for (int row = 0; row < absHeight; ++row) {
159 const int srcRow = height > 0 ? absHeight - 1 - row : row;
160 const size_t src = static_cast<size_t>(pixelOffset) + rowBytes * static_cast<size_t>(srcRow);
161 const size_t dst = static_cast<size_t>(row) * static_cast<size_t>(width) * 3U;

Callers 1

ReadImageFunction · 0.85

Calls 3

ReadLe16Function · 0.85
ReadLe32Function · 0.85
ReadLeS32Function · 0.85

Tested by

no test coverage detected