feat(01-bmpmafia): deepfryer

This commit is contained in:
2025-02-06 11:20:31 +03:00
parent aac3bb56c8
commit e110d9afe2
6 changed files with 174 additions and 1 deletions

View File

@ -4,3 +4,8 @@ CXX = g++
nerdybmp: src/nerdybmp/main.cpp nerdybmp: src/nerdybmp/main.cpp
@mkdir -p $(BUILD_DIR) @mkdir -p $(BUILD_DIR)
$(CXX) -o build/nerdybmp src/nerdybmp/main.cpp $(CXX) -o build/nerdybmp src/nerdybmp/main.cpp
deepfryer: src/deepfryer/main.cpp
@mkdir -p $(BUILD_DIR)
$(CXX) -o build/deepfryer src/deepfryer/main.cpp

View File

@ -17,3 +17,22 @@ make nerdybmp
```sh ```sh
build/nerdybmp some/path/to/file.bmp build/nerdybmp some/path/to/file.bmp
``` ```
## 🍳 `deepfryer`
![catstare](assets/catstare.jpg)
image binarification program
### build
```sh
make deepfryer
```
### usage
```sh
build/deepfryer some/path/to/input.bmp some/path/to/output.bmp 128
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -25,7 +25,15 @@ namespace bmp {
uint32_t colorsUsed; uint32_t colorsUsed;
uint32_t colorsImportant; uint32_t colorsImportant;
}; };
struct BMPColorHeader {
uint32_t red;
uint32_t green;
uint32_t blue;
uint32_t alpha;
uint32_t colorSpaceType;
uint32_t unused[16];
};
} }
#pragma pack(pop) #pragma pack(pop)
#endif #endif

View File

@ -0,0 +1,24 @@
#ifndef RAINBOW_HPP
#define RAINBOW_HPP
#include <ostream>
namespace rainbow {
void print(std::ostream & out, std::string s) {
std::string colors[7] = {
"\033[38;2;210;15;57m",
"\033[38;2;254;100;11m",
"\033[38;2;223;142;29m",
"\033[38;2;64;160;43m",
"\033[38;2;4;165;229m",
"\033[38;2;30;102;245m",
"\033[38;2;136;57;239m"
};
for (int i = 0; i < s.length(); i++)
{
out << colors[i % 7] << s[i] << "\033[0m";
}
}
}
#endif

View File

@ -0,0 +1,117 @@
#include "../../include/bmp.hpp"
#include "../../include/rainbow.hpp"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
int main(int argc, char *argv[]) {
std::cout << "🍳 ";
rainbow::print(std::cout, "deepfryer");
std::cout << "\n";
if (argc < 4) {
std::cerr << "🚬 " << argc << " args? we must have more!!\n";
std::cerr << "usage:\n";
std::cerr << "nerdybmp <input_bmp_file> <output_bmp_file> <threshold>\n";
return 1;
}
int threshold = 127;
try {
threshold = std::stoi(argv[3]);
} catch (std::invalid_argument const &ex) {
std::cerr << "💀 thats not the threshold.. even not a number.... ok bye\n";
return 1;
}
if (threshold > 256 || threshold < 0) {
std::cerr << "💀 thats not a valid threshold.. ok bye\n";
return 1;
}
std::ifstream inputFile(argv[1], std::ios_base::binary);
if (!inputFile) {
std::cerr << "💀 unable to read the file.. ok bye\n";
return 1;
}
bmp::FileHeader fileHeader;
inputFile.read((char *)&fileHeader, sizeof(fileHeader));
if (fileHeader.type != 0x4D42) {
std::cerr << "💀 we are not cooking: this is NOT a BMP file...\n";
return 1;
}
bmp::InfoHeader infoHeader;
inputFile.read((char *)&infoHeader, sizeof(infoHeader));
std::cout << "📂 opened " << argv[1] << '\n';
std::ofstream outputFile(argv[2], std::ios_base::binary);
if (!outputFile) {
std::cerr << "💀 unable to create the output file.. ok bye\n";
return 1;
}
std::cout << "🧨 heating up the ";
rainbow::print(std::cout, "fryer");
std::cout << " up to " << threshold << "°...\n";
inputFile.seekg(infoHeader.size + sizeof(bmp::FileHeader), std::ios::beg);
int rowSize = (infoHeader.width * infoHeader.bitCount / 8 + 3) & ~3;
int paddingSize = rowSize - (infoHeader.width * infoHeader.bitCount / 8);
std::vector<uint8_t> row(rowSize);
bmp::FileHeader outFileHeader;
outFileHeader.type = 0x4D42;
outFileHeader.size = sizeof(bmp::FileHeader) + sizeof(bmp::InfoHeader) +
rowSize * infoHeader.height;
outFileHeader.reserved1 = 0;
outFileHeader.reserved2 = 0;
outFileHeader.offBits = sizeof(bmp::FileHeader) + sizeof(bmp::InfoHeader);
outputFile.write((char *)&fileHeader, sizeof(fileHeader));
outputFile.write((char *)&infoHeader, sizeof(infoHeader));
std::cout << "🍾 THE ";
rainbow::print(std::cout, "DEEPFRYER");
std::cout << " IS READY FOR COOKING 🔥\n";
for (int y = 0; y < infoHeader.height; ++y) {
inputFile.read((char *)row.data(), rowSize);
for (int x = 0; x < infoHeader.width; ++x) {
uint8_t blue = row[x * 3];
uint8_t green = row[x * 3 + 1];
uint8_t red = row[x * 3 + 2];
uint8_t gray =
static_cast<uint8_t>(0.299 * red + 0.587 * green + 0.114 * blue);
uint8_t binaryColor = (gray < threshold) ? 0 : 255;
row[x * 3] = binaryColor;
row[x * 3 + 1] = binaryColor;
row[x * 3 + 2] = binaryColor;
}
outputFile.write((char *)row.data(), rowSize);
}
std::cout << "🍗 your pic is ready, turning off the ";
rainbow::print(std::cout, "fryer");
std::cout << "...\n";
std::vector<uint8_t> padding(paddingSize, 0);
outputFile.write((char *)padding.data(), paddingSize);
std::cout << "✅ take your " << argv[2] << " .. bone apple teeth\n";
inputFile.close();
outputFile.close();
return 0;
}