Skip to content

Commit 2130c09

Browse files
committed
Move 'image2png' function to 'export_png.c', rename it
1 parent d123b40 commit 2130c09

6 files changed

Lines changed: 151 additions & 106 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ CC=gcc
33
CFLAGS=-std=c99 -Wall -Wextra -Wpedantic -ggdb3
44
LDLIBS=-lm -lpng
55

6-
SRC=main.c args.c read_file.c image.c util.c generate_ascii.c generate_bigrams.c generate_dotplot.c generate_entropy.c generate_grayscale.c generate_histogram.c
6+
SRC=main.c args.c read_file.c image.c util.c generate_ascii.c generate_bigrams.c generate_dotplot.c generate_entropy.c generate_grayscale.c generate_histogram.c export_png.c
77
OBJ=$(addprefix obj/, $(addsuffix .o, $(SRC)))
88

99
BIN=bin-graph

src/export_png.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright 2025 8dcc
3+
*
4+
* This file is part of bin-graph.
5+
*
6+
* This program is free software: you can redistribute it and/or modify it under
7+
* the terms of the GNU General Public License as published by the Free Software
8+
* Foundation, either version 3 of the License, or any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13+
* details.
14+
*
15+
* You should have received a copy of the GNU General Public License along with
16+
* this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include <errno.h>
20+
#include <stdlib.h>
21+
#include <string.h>
22+
23+
#include <png.h>
24+
25+
#include "include/export.h"
26+
#include "include/image.h"
27+
#include "include/read_file.h"
28+
#include "include/util.h"
29+
30+
/* Bytes per pixel of the PNG image (R, G, B) */
31+
#define PNG_BPP 3
32+
33+
void export_png(Image* image, const char* filename, int zoom) {
34+
FILE* fd = fopen(filename, "wb");
35+
if (fd == NULL)
36+
DIE("Can't open file '%s': %s", filename, strerror(errno));
37+
38+
png_structp png =
39+
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
40+
if (png == NULL)
41+
DIE("Can't create 'png_structp'. Aborting.");
42+
43+
png_infop info = png_create_info_struct(png);
44+
if (info == NULL)
45+
DIE("Can't create 'png_infop'. Aborting.");
46+
47+
/* The actual PNG image dimensions, remember that the Image is unscaled */
48+
const size_t png_height = image->height * zoom;
49+
const size_t png_width = image->width * zoom;
50+
51+
/* Specify the PNG info */
52+
png_init_io(png, fd);
53+
png_set_IHDR(png,
54+
info,
55+
png_width,
56+
png_height,
57+
8,
58+
PNG_COLOR_TYPE_RGB,
59+
PNG_INTERLACE_NONE,
60+
PNG_COMPRESSION_TYPE_DEFAULT,
61+
PNG_FILTER_TYPE_DEFAULT);
62+
png_write_info(png, info);
63+
64+
/*
65+
* Allocate the PNG rows. Since png_bytep is typedef'd to a pointer, this is
66+
* a (void**).
67+
*/
68+
png_bytep* rows = calloc(png_height, sizeof(png_bytep));
69+
if (rows == NULL)
70+
DIE("Failed to allocate PNG rows");
71+
72+
for (size_t y = 0; y < png_height; y++) {
73+
rows[y] = malloc(png_width * PNG_BPP);
74+
if (rows[y] == NULL)
75+
DIE("Failed to allocate PNG row %zu", y);
76+
}
77+
78+
/*
79+
* Write the 'bytes' array we received into the 'rows' array we just
80+
* allocated.
81+
*
82+
* The outer loops iterate the unscaled pixels, and are needed for accessing
83+
* the 'bytes->data' array.
84+
*/
85+
for (size_t y = 0; y < image->height; y++) {
86+
for (size_t x = 0; x < image->width; x++) {
87+
Color color = image->pixels[image->width * y + x];
88+
89+
/* Draw a rectangle of side 'zoom' */
90+
for (int rect_y = 0; rect_y < zoom; rect_y++) {
91+
for (int rect_x = 0; rect_x < zoom; rect_x++) {
92+
const png_bytep row = rows[zoom * y + rect_y];
93+
94+
/* Note that we are using RGB, not RGBA */
95+
row[PNG_BPP * (zoom * x + rect_x)] = color.r;
96+
row[PNG_BPP * (zoom * x + rect_x) + 1] = color.g;
97+
row[PNG_BPP * (zoom * x + rect_x) + 2] = color.b;
98+
}
99+
}
100+
}
101+
}
102+
103+
/* Write the rows into the PNG structure */
104+
png_write_image(png, rows);
105+
png_write_end(png, NULL);
106+
107+
/* Free each pointer of the 'rows' array, and the array itself */
108+
for (size_t y = 0; y < png_height; y++)
109+
free(rows[y]);
110+
free(rows);
111+
112+
fclose(fd);
113+
png_destroy_write_struct(&png, &info);
114+
}

src/image.c

Lines changed: 1 addition & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,15 @@
1717
*/
1818

1919
#include <assert.h>
20-
#include <errno.h>
2120
#include <stdbool.h>
2221
#include <stdlib.h>
2322
#include <string.h>
24-
#include <ctype.h>
25-
26-
#include <png.h>
2723

24+
#include "include/image.h"
2825
#include "include/args.h"
2926
#include "include/read_file.h"
30-
#include "include/image.h"
3127
#include "include/util.h"
3228

33-
/* Bytes per pixel of the PNG image (R, G, B) */
34-
#define PNG_BPP 3
35-
36-
/*----------------------------------------------------------------------------*/
37-
3829
bool image_init(Image* image, size_t width, size_t height) {
3930
assert(image != NULL);
4031

@@ -53,8 +44,6 @@ void image_deinit(Image* image) {
5344
image->pixels = NULL;
5445
}
5546

56-
/*----------------------------------------------------------------------------*/
57-
5847
void image_transform_squares(Image* image, size_t square_side) {
5948
const int square_size = square_side * square_side;
6049
const size_t total_pixels = image->width * image->height;
@@ -98,88 +87,3 @@ void image_transform_squares(Image* image, size_t square_side) {
9887
free(image->pixels);
9988
image->pixels = new_pixels;
10089
}
101-
102-
/*----------------------------------------------------------------------------*/
103-
104-
void image2png(Image* image, const char* filename, int zoom) {
105-
FILE* fd = fopen(filename, "wb");
106-
if (fd == NULL)
107-
DIE("Can't open file '%s': %s", filename, strerror(errno));
108-
109-
png_structp png =
110-
png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
111-
if (png == NULL)
112-
DIE("Can't create 'png_structp'. Aborting.");
113-
114-
png_infop info = png_create_info_struct(png);
115-
if (info == NULL)
116-
DIE("Can't create 'png_infop'. Aborting.");
117-
118-
/* The actual PNG image dimensions, remember that the Image is unscaled */
119-
const size_t png_height = image->height * zoom;
120-
const size_t png_width = image->width * zoom;
121-
122-
/* Specify the PNG info */
123-
png_init_io(png, fd);
124-
png_set_IHDR(png,
125-
info,
126-
png_width,
127-
png_height,
128-
8,
129-
PNG_COLOR_TYPE_RGB,
130-
PNG_INTERLACE_NONE,
131-
PNG_COMPRESSION_TYPE_DEFAULT,
132-
PNG_FILTER_TYPE_DEFAULT);
133-
png_write_info(png, info);
134-
135-
/*
136-
* Allocate the PNG rows. Since png_bytep is typedef'd to a pointer, this is
137-
* a (void**).
138-
*/
139-
png_bytep* rows = calloc(png_height, sizeof(png_bytep));
140-
if (rows == NULL)
141-
DIE("Failed to allocate PNG rows");
142-
143-
for (size_t y = 0; y < png_height; y++) {
144-
rows[y] = malloc(png_width * PNG_BPP);
145-
if (rows[y] == NULL)
146-
DIE("Failed to allocate PNG row %zu", y);
147-
}
148-
149-
/*
150-
* Write the 'bytes' array we received into the 'rows' array we just
151-
* allocated.
152-
*
153-
* The outer loops iterate the unscaled pixels, and are needed for accessing
154-
* the 'bytes->data' array.
155-
*/
156-
for (size_t y = 0; y < image->height; y++) {
157-
for (size_t x = 0; x < image->width; x++) {
158-
Color color = image->pixels[image->width * y + x];
159-
160-
/* Draw a rectangle of side 'zoom' */
161-
for (int rect_y = 0; rect_y < zoom; rect_y++) {
162-
for (int rect_x = 0; rect_x < zoom; rect_x++) {
163-
const png_bytep row = rows[zoom * y + rect_y];
164-
165-
/* Note that we are using RGB, not RGBA */
166-
row[PNG_BPP * (zoom * x + rect_x)] = color.r;
167-
row[PNG_BPP * (zoom * x + rect_x) + 1] = color.g;
168-
row[PNG_BPP * (zoom * x + rect_x) + 2] = color.b;
169-
}
170-
}
171-
}
172-
}
173-
174-
/* Write the rows into the PNG structure */
175-
png_write_image(png, rows);
176-
png_write_end(png, NULL);
177-
178-
/* Free each pointer of the 'rows' array, and the array itself */
179-
for (size_t y = 0; y < png_height; y++)
180-
free(rows[y]);
181-
free(rows);
182-
183-
fclose(fd);
184-
png_destroy_write_struct(&png, &info);
185-
}

src/include/export.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Copyright 2025 8dcc
3+
*
4+
* This file is part of bin-graph.
5+
*
6+
* This program is free software: you can redistribute it and/or modify it under
7+
* the terms of the GNU General Public License as published by the Free Software
8+
* Foundation, either version 3 of the License, or any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful, but WITHOUT
11+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13+
* details.
14+
*
15+
* You should have received a copy of the GNU General Public License along with
16+
* this program. If not, see <https://www.gnu.org/licenses/>.
17+
*/
18+
19+
#ifndef EXPORT_H_
20+
#define EXPORT_H_ 1
21+
22+
#include "image.h"
23+
24+
/*
25+
* Export the specified 'Image' structure into a PNG file with the specified
26+
* name, using 'zoom' for scaling.
27+
*
28+
* TODO: Return boolean instead of using 'DIE'.
29+
*/
30+
void export_png(Image* image, const char* filename, int zoom);
31+
32+
#endif /* EXPORT_H_ */

src/include/image.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,4 @@ void image_deinit(Image* image);
5353
*/
5454
void image_transform_squares(Image* image, size_t square_side);
5555

56-
/*
57-
* Write the specified 'Image' structure into a PNG file with the specified
58-
* name, using 'zoom' for scaling.
59-
*/
60-
void image2png(Image* image, const char* filename, int zoom);
61-
6256
#endif /* IMAGE_H_ */

src/main.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include "include/read_file.h"
2727
#include "include/image.h"
2828
#include "include/generate.h"
29+
#include "include/export.h"
2930
#include "include/util.h"
3031

3132
int main(int argc, char** argv) {
@@ -61,8 +62,8 @@ int main(int argc, char** argv) {
6162
if (args.transform_squares_side > 1)
6263
image_transform_squares(image, args.transform_squares_side);
6364

64-
/* Write the Image structure to the PNG file */
65-
image2png(image, args.output_filename, args.output_zoom);
65+
/* Write the 'Image' structure to the PNG file */
66+
export_png(image, args.output_filename, args.output_zoom);
6667

6768
/* We are done with the image, free it */
6869
image_deinit(image);

0 commit comments

Comments
 (0)