feat(01-bmpmafia): threemult
This commit is contained in:
@ -1,11 +1,24 @@
|
|||||||
BUILD_DIR = build
|
BUILD_DIR = build
|
||||||
CXX = g++
|
CXX = g++
|
||||||
|
|
||||||
|
all: nerdybmp deepfryer threemult threemultfr
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf $(BUILD_DIR)
|
||||||
|
rm -rf samples/output/*
|
||||||
|
|
||||||
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
|
deepfryer: src/deepfryer/main.cpp
|
||||||
@mkdir -p $(BUILD_DIR)
|
@mkdir -p $(BUILD_DIR)
|
||||||
$(CXX) -o build/deepfryer src/deepfryer/main.cpp
|
$(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
|
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/bmp.hpp"
|
||||||
#include "../../include/rainbow.hpp"
|
#include "../../include/rainbow.hpp"
|
||||||
|
#include <csignal>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -42,7 +43,8 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if (fileHeader.type != 0x4D42) {
|
if (fileHeader.type != 0x4D42) {
|
||||||
std::cerr << "💀 we are not cooking: this is NOT a BMP file...\n";
|
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;
|
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