Skip to content

Commit ac33f1c

Browse files
committed
[ADD] - Png to BMP
Additionally added a class that converts png back to a bmp format, converting the colour format of the image to proper form.
1 parent 38d6fd3 commit ac33f1c

File tree

2 files changed

+125
-0
lines changed

2 files changed

+125
-0
lines changed

src/converters/png_to_bmp.c

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <png.h>
4+
5+
int png_to_bmp(const char *input_filename, const char *output_filename)
6+
{
7+
// Open PNG file for reading
8+
FILE *input_file = fopen(input_filename, "rb");
9+
if (!input_file)
10+
{
11+
fprintf(stderr, "Error: could not open input file %s\n", input_filename);
12+
return 1;
13+
}
14+
// Create PNG read struct
15+
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
16+
if (!png_ptr)
17+
{
18+
fprintf(stderr, "Error: could not create PNG read struct\n");
19+
fclose(input_file);
20+
return 1;
21+
}
22+
// Create PNG info struct
23+
png_infop info_ptr = png_create_info_struct(png_ptr);
24+
if (!info_ptr)
25+
{
26+
fprintf(stderr, "Error: could not create PNG info struct\n");
27+
png_destroy_read_struct(&png_ptr, NULL, NULL);
28+
fclose(input_file);
29+
return 1;
30+
}
31+
// Set error handling
32+
if (setjmp(png_jmpbuf(png_ptr)))
33+
{
34+
fprintf(stderr, "Error: PNG error\n");
35+
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
36+
fclose(input_file);
37+
return 1;
38+
}
39+
// Initialize PNG I/O
40+
png_init_io(png_ptr, input_file);
41+
// Read PNG header info
42+
png_read_info(png_ptr, info_ptr);
43+
// Get PNG image attributes
44+
int width = png_get_image_width(png_ptr, info_ptr);
45+
int height = png_get_image_height(png_ptr, info_ptr);
46+
int color_type = png_get_color_type(png_ptr, info_ptr);
47+
int bit_depth = png_get_bit_depth(png_ptr, info_ptr);
48+
// Make sure it's a valid format for conversion
49+
if (color_type != PNG_COLOR_TYPE_RGB || bit_depth != 8)
50+
{
51+
fprintf(stderr, "Error: unsupported PNG format\n");
52+
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
53+
fclose(input_file);
54+
return 1;
55+
}
56+
// Allocate memory for PNG image data
57+
png_bytep *row_pointers = (png_bytep *)malloc(height * sizeof(png_bytep));
58+
if (!row_pointers)
59+
{
60+
fprintf(stderr, "Error: could not allocate memory for PNG image data\n");
61+
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
62+
fclose(input_file);
63+
return 1;
64+
}
65+
for (int y = 0; y < height; y++)
66+
{
67+
row_pointers[y] = (png_byte *)malloc(png_get_rowbytes(png_ptr, info_ptr));
68+
if (!row_pointers[y])
69+
{
70+
fprintf(stderr, "Error: could not allocate memory for PNG image data\n");
71+
for (int i = 0; i < y; i++)
72+
free(row_pointers[i]);
73+
free(row_pointers);
74+
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
75+
fclose(input_file);
76+
return 1;
77+
}
78+
}
79+
// Read PNG image data
80+
png_read_image(png_ptr, row_pointers);
81+
// Close PNG file
82+
png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
83+
fclose(input_file);
84+
// Open BMP file for writing
85+
FILE *output_file = fopen(output_filename, "wb");
86+
if (!output_file)
87+
{
88+
fprintf(stderr, "Error: could not open output file %s\n", output_filename);
89+
for (int y = 0; y < height; y++)
90+
free(row_pointers[y]);
91+
free(row_pointers);
92+
return 1;
93+
}
94+
// Write BMP header
95+
unsigned char header[54] = {
96+
'B', 'M', 0, 0, 0, 0, 0, 0, 0, 0, 54, 0, 0, 0, 40, 0,
97+
0, 0, (unsigned char)(width), (unsigned char)(width >> 8), (unsigned char)(width >> 16), (unsigned char)(width >> 24),
98+
(unsigned char)(height), (unsigned char)(height >> 8), (unsigned char)(height >> 16), (unsigned char)(height >> 24),
99+
1, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
100+
fwrite(header, sizeof(unsigned char), 54, output_file);
101+
// Write BMP image data
102+
for (int y = height - 1; y >= 0; y--)
103+
{
104+
for (int x = 0; x < width; x++)
105+
{
106+
png_bytep pixel = &(row_pointers[y][x * 3]);
107+
fwrite(&pixel[2], sizeof(png_byte), 1, output_file);
108+
fwrite(&pixel[1], sizeof(png_byte), 1, output_file);
109+
fwrite(&pixel[0], sizeof(png_byte), 1, output_file);
110+
}
111+
// Add padding
112+
for (int p = 0; p < (4 - (width * 3) % 4) % 4; p++)
113+
fputc(0, output_file);
114+
}
115+
// Close BMP file
116+
fclose(output_file);
117+
// Free memory
118+
for (int y = 0; y < height; y++)
119+
free(row_pointers[y]);
120+
free(row_pointers);
121+
printf("Converted %s to %s\n", input_filename, output_filename);
122+
return 0;
123+
}

src/main.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#include "gtk_gui.c"
22
//#include "converters/bmp_to_jpeg.c" // Include this line to test the bmp_to_jpeg function
33
//#include "converters/bmp_to_png.c"
4+
//#include "converters/png_to_bmp.c"
45

56
int main(int argc, char **argv)
67
{
78
//Include the following line to test the bmp_to_jpeg function
89
//bmp_to_jpeg("assets/images/test_image.bmp", "assets/images/testjpg.jpg");
910
//bmp_to_png("assets/images/test_image_negative.bmp", "assets/images/testpng.png");
11+
//png_to_bmp("assets/images/testpng.png", "assets/images/test_i.bmp");
1012

1113
GtkApplication *app;
1214
int status;

0 commit comments

Comments
 (0)