scop
a small 3D object loader
Loading...
Searching...
No Matches
Image.hpp
Go to the documentation of this file.
1/* ************************************************************************** */
2/* */
3/* ::: :::::::: */
4/* Image.hpp :+: :+: :+: */
5/* +:+ +:+ +:+ */
6/* By: rbourgea <rbourgea@student.42.fr> +#+ +:+ +#+ */
7/* +#+#+#+#+#+ +#+ */
8/* Created: 2024/01/14 19:51:52 by rbourgea #+# #+# */
9/* Updated: 2024/01/20 11:23:53 by rbourgea ### ########.fr */
10/* */
11/* ************************************************************************** */
12
13#ifndef IMAGE_HPP
14#define IMAGE_HPP
15
16#include <fstream>
17#include <stdexcept>
18#include <vector>
19#include <iostream>
20
21class Image {
22public:
23 static std::vector<unsigned char> loadImage(const char* filename, int& width, int& height, int& channels) {
24 std::ifstream file(filename, std::ios::ate | std::ios::binary);
25
26 if (!file.is_open()) {
27 std::cerr << "Error opening file: " << filename << std::endl;
28 std::exit(0);
29 }
30
31 size_t fileSize = static_cast<size_t>(file.tellg());
32 file.seekg(0);
33
34 std::vector<unsigned char> buffer(fileSize);
35 file.read(reinterpret_cast<char*>(buffer.data()), fileSize);
36
37 if (buffer.size() >= 54 && buffer[0] == 'B' && buffer[1] == 'M') {
38 width = *reinterpret_cast<int*>(&buffer[18]);
39 height = *reinterpret_cast<int*>(&buffer[22]);
40 channels = *reinterpret_cast<short*>(&buffer[28]);
41
42 if (channels == 24 || channels == 32) {
43 int bytesPerPixel = channels / 8;
44 int padding = (4 - (width * bytesPerPixel) % 4) % 4;
45
46 std::vector<unsigned char> newBuffer(width * height * 4);
47
48 for (int i = 0; i < height; ++i) {
49 for (int j = 0; j < width; ++j) {
50 int inputIndex = (height - i - 1) * (width * bytesPerPixel + padding) + j * bytesPerPixel;
51 int outputIndex = i * width + j;
52
53 newBuffer[outputIndex * 4] = buffer[inputIndex + 2];
54 newBuffer[outputIndex * 4 + 1] = buffer[inputIndex + 1];
55 newBuffer[outputIndex * 4 + 2] = buffer[inputIndex];
56 newBuffer[outputIndex * 4 + 3] = (channels == 24) ? 255 : buffer[inputIndex + 3];
57 }
58 }
59
60 buffer = std::move(newBuffer);
61 channels = 4;
62 } else {
63 throw std::runtime_error("Unsupported image channel count. Only 24-bit and 32-bit images are supported.");
64 }
65 } else {
66 throw std::runtime_error("Unsupported image format. Only BMP is supported.");
67 }
68
69 file.close();
70
71 return buffer;
72 }
73
74 static void freeImage(std::vector<unsigned char>& imageData) {
75 imageData.clear();
76 }
77};
78
79#endif
static void freeImage(std::vector< unsigned char > &imageData)
Definition Image.hpp:74
static std::vector< unsigned char > loadImage(const char *filename, int &width, int &height, int &channels)
Definition Image.hpp:23