Skip to content

Commit 7b5bfea

Browse files
updating to latest
1 parent 093a518 commit 7b5bfea

File tree

5 files changed

+270
-0
lines changed

5 files changed

+270
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,7 @@
3030
*.exe
3131
*.out
3232
*.app
33+
34+
# directory and vs code files
35+
build/
36+
.vscode/

Image-Converter.h

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#ifndef IMAGE_CONVERTER_H
2+
#define IMAGE_CONVERTER_H
3+
4+
#include <iostream>
5+
#include <fstream>
6+
#include <vector>
7+
#include <tuple>
8+
#include <png.h>
9+
#include "Render-Engine.h"
10+
11+
using namespace std;
12+
13+
// function declaration
14+
std::vector<std::vector<png_byte>> read_png_file(const char* filename, int& width, int& height);
15+
16+
void get_image_data(const char* image_name) {
17+
int width, height;
18+
std::vector<std::vector<png_byte>> pixel_data = read_png_file(image_name, width, height);
19+
20+
for (int y = 0; y < height; y++) {
21+
png_bytep row = pixel_data[y].data();
22+
for (int x = 0; x < width; x++) {
23+
24+
// this checks if we have gone past the limits of the canvas
25+
if (x > WIDTH || y > HEIGHT) {
26+
break;
27+
}
28+
29+
png_bytep px = &(row[x * 4]);
30+
// px[0] = red, px[1] = green, px[2] = blue, px[3] = alpha
31+
if ((int)px[3] == 0) {
32+
continue;
33+
}
34+
Color pixel_colour = {(int)px[0], (int)px[1], (int)px[2]};
35+
pixel_matrix[y][x] = pixel_colour;
36+
}
37+
}
38+
}
39+
40+
41+
// Function to read PNG file and get pixel data
42+
std::vector<std::vector<png_byte>> read_png_file(const char* filename, int& width, int& height) {
43+
FILE* fp = fopen(filename, "rb");
44+
if (!fp) {
45+
throw std::runtime_error("Error: Could not open file.");
46+
}
47+
48+
// Create and initialize the png_struct with the default error handling.
49+
png_structp png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
50+
if (!png) {
51+
fclose(fp);
52+
throw std::runtime_error("Error: png_create_read_struct failed.");
53+
}
54+
55+
png_infop info = png_create_info_struct(png);
56+
if (!info) {
57+
png_destroy_read_struct(&png, NULL, NULL);
58+
fclose(fp);
59+
throw std::runtime_error("Error: png_create_info_struct failed.");
60+
}
61+
62+
if (setjmp(png_jmpbuf(png))) {
63+
png_destroy_read_struct(&png, &info, NULL);
64+
fclose(fp);
65+
throw std::runtime_error("Error: setjmp(png_jmpbuf(png)) failed.");
66+
}
67+
68+
png_init_io(png, fp);
69+
png_read_info(png, info);
70+
71+
width = png_get_image_width(png, info);
72+
height = png_get_image_height(png, info);
73+
png_byte color_type = png_get_color_type(png, info);
74+
png_byte bit_depth = png_get_bit_depth(png, info);
75+
76+
// Read any color_type into 8bit depth, RGBA format.
77+
if (bit_depth == 16)
78+
png_set_strip_16(png);
79+
80+
if (color_type == PNG_COLOR_TYPE_PALETTE)
81+
png_set_palette_to_rgb(png);
82+
83+
// PNG_COLOR_TYPE_GRAY_ALPHA is always 8 or 16bit depth.
84+
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
85+
png_set_expand_gray_1_2_4_to_8(png);
86+
87+
if (png_get_valid(png, info, PNG_INFO_tRNS))
88+
png_set_tRNS_to_alpha(png);
89+
90+
if (color_type == PNG_COLOR_TYPE_RGB ||
91+
color_type == PNG_COLOR_TYPE_GRAY ||
92+
color_type == PNG_COLOR_TYPE_PALETTE)
93+
png_set_filler(png, 0xFF, PNG_FILLER_AFTER);
94+
95+
if (color_type == PNG_COLOR_TYPE_GRAY ||
96+
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
97+
png_set_gray_to_rgb(png);
98+
99+
png_read_update_info(png, info);
100+
101+
std::vector<std::vector<png_byte>> pixel_data(height, std::vector<png_byte>(png_get_rowbytes(png, info)));
102+
std::vector<png_bytep> row_pointers(height);
103+
104+
for (int y = 0; y < height; y++) {
105+
row_pointers[y] = pixel_data[y].data();
106+
}
107+
108+
png_read_image(png, row_pointers.data());
109+
110+
fclose(fp);
111+
png_destroy_read_struct(&png, &info, NULL);
112+
113+
return pixel_data;
114+
}
115+
116+
117+
118+
119+
120+
#endif

Makefile

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
pixel_engine:main.cpp
2+
g++ -o build/pixel_engine main.cpp Render-Engine.h Image-Converter.h -lm -lpthread -lX11 -lpng -Wall -Wextra
3+
4+
# CXX = g++
5+
# CXXFLAGS = -Wall -Wextra -std=c++11
6+
# LDFLAGS = -lm -lpthread -lX11 -lpng
7+
8+
# SOURCES = main.cpp
9+
# HEADERS = Render-Engine.h Image-Converter.h
10+
# OBJECTS = $(SOURCES:.cpp=.o)
11+
# TARGET = build/pixel_engine
12+
13+
# all: $(TARGET)
14+
15+
# $(TARGET): $(OBJECTS)
16+
# $(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
17+
18+
# %.o: %.cpp $(HEADERS)
19+
# $(CXX) $(CXXFLAGS) -c $< -o $@
20+
21+
# clean:
22+
# rm -f $(OBJECTS) $(TARGET)

Render-Engine.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
#ifndef RENDER_ENGINE_H
2+
#define RENDER_ENGINE_H
3+
4+
5+
6+
#include <unordered_map>
7+
#include <iostream>
8+
#include <unistd.h>
9+
#include <utility>
10+
#include <cstdlib>
11+
#include <vector>
12+
#include <string>
13+
14+
15+
16+
struct Color {
17+
int r, g, b;
18+
};
19+
20+
const int WIDTH = 200;
21+
const int HEIGHT = 200;
22+
23+
const Color NULL_COLOR = {-1, -1, -1};
24+
25+
std::unordered_map<char, Color> colour_map = {
26+
{'R', {255, 0, 0}}, // Bright red
27+
{'G', {0, 255, 0}}, // Bright green
28+
{'B', {0, 0, 255}}, // Bright blue
29+
{'Y', {255, 255, 0}}, // Yellow
30+
{'M', {255, 0, 255}}, // Magenta
31+
{'C', {0, 255, 255}}, // Cyan
32+
{'g', {100, 100, 100}}, // Grey
33+
};
34+
35+
Color pixel_matrix[WIDTH][HEIGHT];
36+
37+
38+
//* ----------------------------------------------------------------------------------------------------------------------------- Functions start here
39+
40+
Color random_color(){
41+
return {(rand() % 255) + 1, (rand() % 255) + 1, (rand() % 255) + 1} ;
42+
}
43+
44+
// Function to compare two Color structs
45+
bool operator==(const Color& c1, const Color& c2) {
46+
return (c1.r == c2.r && c1.g == c2.g && c1.b == c2.b);
47+
}
48+
49+
void initialize() {
50+
// this sets a new seed for the random number generation
51+
srand((unsigned) time(0));
52+
53+
for (int y = 0; y < HEIGHT; y++){
54+
for (int x = 0; x < WIDTH; x++){
55+
pixel_matrix[y][x] = NULL_COLOR;
56+
}
57+
}
58+
}
59+
60+
void print_single_pixel(Color CLin) {
61+
// ANSI escape code for setting text color with RGB values
62+
std::cout << "\033[38;2;" << CLin.r << ";" << CLin.g << ";" << CLin.b << "m" << "██" << "\033[0m";
63+
}
64+
65+
void render() {
66+
for (int y = 0; y < HEIGHT; y++){
67+
for (int x = 0; x < WIDTH; x++){
68+
if (pixel_matrix[y][x] == NULL_COLOR) {
69+
std::cout << " ";
70+
continue;
71+
}
72+
print_single_pixel(pixel_matrix[y][x]);
73+
}
74+
std::cout << "\n";
75+
}
76+
}
77+
78+
// prints out the test to make sure pixel rendering is working
79+
void test_pixels() {
80+
std::cout << "rendering test: ";
81+
for(auto i:colour_map) {
82+
std::cout << i.first << " : ";
83+
print_single_pixel(i.second);
84+
std::cout << " ";
85+
}
86+
std::cout << "\n";
87+
}
88+
89+
90+
91+
#endif

main.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <iostream>
2+
#include "Render-Engine.h"
3+
#include "Image-Converter.h"
4+
5+
//* compile command: g++ -o build/pixel_engine main.cpp Render-Engine.h Image-Converter.h -lm -lpthread -lX11 -lpng -Wall -Wextra
6+
7+
int main(int argc, char* argv[]) {
8+
9+
if (argc != 2) {
10+
std::cerr << "Usage: " << argv[0] << " <image_file>" << "\n";
11+
return 1;
12+
}
13+
const char* image_name = argv[1];
14+
15+
initialize();
16+
17+
get_image_data(image_name);
18+
19+
render();
20+
//std::vector<std::vector<png_byte>> pixel_data = read_png_file(image_name, width, height);
21+
22+
// Process the pixel data
23+
// for (int y = 0; y < height; y++) {
24+
// png_bytep row = pixel_data[y].data();
25+
// for (int x = 0; x < width; x++) {
26+
// png_bytep px = &(row[x * 4]);
27+
// // px[0] = red, px[1] = green, px[2] = blue, px[3] = alpha
28+
// std::cout << "Pixel at (" << x << ", " << y << "): R=" << (int)px[0] << " G=" << (int)px[1] << " B=" << (int)px[2] << " A=" << (int)px[3] << std::endl;
29+
// }
30+
// }
31+
32+
return 0;
33+
}

0 commit comments

Comments
 (0)