feat(01-bmpmafia): threemult
This commit is contained in:
@ -1,11 +1,24 @@
|
||||
BUILD_DIR = build
|
||||
CXX = g++
|
||||
|
||||
all: nerdybmp deepfryer threemult threemultfr
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
rm -rf samples/output/*
|
||||
|
||||
nerdybmp: src/nerdybmp/main.cpp
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
$(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
|
||||
|
||||
threemultfr: src/threemult/main.cpp
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
$(CXX) -o build/threemultfr src/threemult/main.cpp
|
||||
|
||||
threemult: src/threemult/bad.cpp
|
||||
@mkdir -p $(BUILD_DIR)
|
||||
$(CXX) -o build/threemult src/threemult/bad.cpp
|
||||
|
||||
@ -36,3 +36,22 @@ make deepfryer
|
||||
build/deepfryer some/path/to/input.bmp some/path/to/output.bmp 128
|
||||
```
|
||||
|
||||
## threemult
|
||||
|
||||
converts 8bit bmp to 24bit
|
||||
|
||||
### build
|
||||
|
||||
```sh
|
||||
# wrong edition
|
||||
make threemult
|
||||
|
||||
# fine edition
|
||||
make threemultfr
|
||||
```
|
||||
|
||||
### usage
|
||||
|
||||
```sh
|
||||
build/threemult(fr) some/path/to/input.bmp some/path/to/output.bmp
|
||||
```
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "../../include/bmp.hpp"
|
||||
#include "../../include/rainbow.hpp"
|
||||
#include <csignal>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -42,7 +43,8 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (fileHeader.type != 0x4D42) {
|
||||
std::cerr << "💀 we are not cooking: this is NOT a BMP file...\n";
|
||||
return 1;
|
||||
std::cerr << "⚡ so now you get what you really deserve.\n";
|
||||
std::raise(SIGSEGV);
|
||||
}
|
||||
|
||||
bmp::InfoHeader infoHeader;
|
||||
|
||||
70
01-bmpmafia/src/threemult/bad.cpp
Normal file
70
01-bmpmafia/src/threemult/bad.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
#include "../../include/bmp.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
std::cout << "🎰 threemult\n";
|
||||
|
||||
if (argc < 3) {
|
||||
std::cerr << "🚬 " << argc - 1 << " args? we must have more!!\n";
|
||||
std::cerr << "usage:\n";
|
||||
std::cerr << "threemult <input_bmp_file> <output_bmp_file>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::ifstream inputFile(argv[1], std::ios::binary);
|
||||
if (!inputFile) {
|
||||
std::cerr << "💀 we are not cooking: the file is cooked or even not a "
|
||||
"file...\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
bmp::FileHeader fileHeader;
|
||||
inputFile.read(reinterpret_cast<char *>(&fileHeader), sizeof(fileHeader));
|
||||
if (inputFile.gcount() < sizeof(fileHeader)) {
|
||||
std::cerr << "💀 we are not cooking: the file header is cursed..";
|
||||
return 1;
|
||||
}
|
||||
|
||||
bmp::InfoHeader infoHeader;
|
||||
inputFile.read(reinterpret_cast<char *>(&infoHeader), sizeof(infoHeader));
|
||||
if (inputFile.gcount() < sizeof(infoHeader)) {
|
||||
std::cerr << "💀 we are not cooking: the infoheader is cursed..";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fileHeader.type != 0x4D42) {
|
||||
std::cerr << "💀 we are not cooking: this is NOT a BMP file...\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (infoHeader.bitCount != 8) {
|
||||
std::cerr << "💀 we are not cooking: uhm i cannot convert"
|
||||
<< infoHeader.bitCount << "bit to 24bit im soooo sorry..\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::ofstream outputFile(argv[2], std::ios::binary);
|
||||
if (!outputFile) {
|
||||
std::cerr << "💀 we are not cooking: unable to output to sthn...\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "🧢 writing headers...\n";
|
||||
|
||||
infoHeader.bitCount = 24;
|
||||
infoHeader.colorsImportant = 0;
|
||||
|
||||
fileHeader.offBits = sizeof(fileHeader) + sizeof(infoHeader);
|
||||
|
||||
outputFile.write(reinterpret_cast<char *>(&fileHeader), sizeof(fileHeader));
|
||||
outputFile.write(reinterpret_cast<char *>(&infoHeader), sizeof(infoHeader));
|
||||
|
||||
outputFile << inputFile.rdbuf();
|
||||
|
||||
std::cout << "✅ ur pic is ready... check it out...\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
109
01-bmpmafia/src/threemult/main.cpp
Executable file
109
01-bmpmafia/src/threemult/main.cpp
Executable file
@ -0,0 +1,109 @@
|
||||
#include "../../include/bmp.hpp"
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
std::cout << "🎰 threemult\n";
|
||||
|
||||
if (argc < 3) {
|
||||
std::cerr << "🚬 " << argc - 1 << " args? we must have more!!\n";
|
||||
std::cerr << "usage:\n";
|
||||
std::cerr << "threemult <input_bmp_file> <output_bmp_file>\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::ifstream inputFile(argv[1], std::ios::binary);
|
||||
if (!inputFile) {
|
||||
std::cerr << "💀 we are not cooking: the file is cooked or even not a "
|
||||
"file...\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
bmp::FileHeader fileHeader;
|
||||
inputFile.read(reinterpret_cast<char *>(&fileHeader), sizeof(fileHeader));
|
||||
if (inputFile.gcount() < sizeof(fileHeader)) {
|
||||
std::cerr << "💀 we are not cooking: the file header is cursed..";
|
||||
return 1;
|
||||
}
|
||||
|
||||
bmp::InfoHeader infoHeader;
|
||||
inputFile.read(reinterpret_cast<char *>(&infoHeader), sizeof(infoHeader));
|
||||
if (inputFile.gcount() < sizeof(infoHeader)) {
|
||||
std::cerr << "💀 we are not cooking: the infoheader is cursed..";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (fileHeader.type != 0x4D42) {
|
||||
std::cerr << "💀 we are not cooking: this is NOT a BMP file...\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (infoHeader.bitCount != 8) {
|
||||
std::cerr << "💀 we are not cooking: uhm i cannot convert"
|
||||
<< infoHeader.bitCount << "bit to 24bit im soooo sorry..\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::ofstream outputFile(argv[2], std::ios::binary);
|
||||
if (!outputFile) {
|
||||
std::cerr << "💀 we are not cooking: unable to output to sthn...\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
// here's the side order
|
||||
// some header stuff nvm
|
||||
std::cout << "🧢 writing headers...\n";
|
||||
|
||||
infoHeader.bitCount = 24;
|
||||
infoHeader.colorsImportant = 0;
|
||||
|
||||
fileHeader.offBits = sizeof(fileHeader) + sizeof(infoHeader);
|
||||
|
||||
outputFile.write(reinterpret_cast<char *>(&fileHeader), sizeof(fileHeader));
|
||||
outputFile.write(reinterpret_cast<char *>(&infoHeader), sizeof(infoHeader));
|
||||
|
||||
// 8bit bmps got 256 colors
|
||||
// every color got 4bytes - rgba
|
||||
std::vector<uint8_t> palette(256 * 4);
|
||||
inputFile.read(reinterpret_cast<char *>(palette.data()), palette.size());
|
||||
|
||||
// calculating lines realign
|
||||
int width = std::abs(infoHeader.width);
|
||||
int height = std::abs(infoHeader.height);
|
||||
int row_padded_input = (width + 3) & ~3;
|
||||
int row_padded_output = (width * 3 + 3) & ~3;
|
||||
int padding_input = row_padded_input - width;
|
||||
int padding_output = row_padded_output - width * 3;
|
||||
|
||||
std::cout << "🖼️ ok so now we're doin the pixels part\n";
|
||||
for (int i = 0; i < height; ++i) {
|
||||
std::vector<uint8_t> row(width);
|
||||
inputFile.read(reinterpret_cast<char *>(row.data()), width);
|
||||
inputFile.ignore(padding_input);
|
||||
|
||||
// and here's the main course
|
||||
std::vector<uint8_t> new_row;
|
||||
for (size_t j = 0; j < row.size(); ++j) {
|
||||
uint8_t index = row[j]; // getting the color index
|
||||
|
||||
// setting values for each channel
|
||||
uint8_t r = palette[index * 4 + 2];
|
||||
uint8_t g = palette[index * 4 + 1];
|
||||
uint8_t b = palette[index * 4 + 0];
|
||||
|
||||
new_row.push_back(b);
|
||||
new_row.push_back(g);
|
||||
new_row.push_back(r);
|
||||
}
|
||||
|
||||
outputFile.write(reinterpret_cast<char *>(new_row.data()), new_row.size());
|
||||
outputFile.write("\x00\x00\x00", padding_output);
|
||||
}
|
||||
|
||||
std::cout << "✅ i guess we're done for now\n";
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user