commit 963b9b9
pita
·
2026-06-29 18:46:56 +0000 UTC
parent 963b9b9
intial
1 files changed,
+180,
-0
+180,
-0
1@@ -0,0 +1,180 @@
2+#include <stdio.h>
3+#include <stdlib.h>
4+#include <math.h>
5+#include <time.h>
6+#include <string.h>
7+
8+typedef struct {
9+ int width;
10+ int height;
11+ unsigned char *data;
12+} Ppm;
13+
14+void rotate_image(Ppm *src, Ppm *dst, double degrees) {
15+ double radians = degrees * (3.1415926 / 180.0);
16+ double cos_t = cos(radians);
17+ double sin_t = sin(radians);
18+ int cx = src->width / 2;
19+ int cy = src->height / 2;
20+ int dst_y, dst_x;
21+ int dx, dy, src_x, src_y, dst_idx;
22+
23+ for (dst_y = 0; dst_y < dst->height; dst_y++) {
24+ for (dst_x = 0; dst_x < dst->width; dst_x++) {
25+
26+ /* make the center be 0,0 */
27+ dx = dst_x - cx;
28+ dy = dst_y - cy;
29+
30+ /* calulate rotation */
31+ src_x = (int)floor(dx * cos_t + dy * sin_t + 0.5) + cx;
32+ src_y = (int)floor(-dx * sin_t + dy * cos_t + 0.5) + cy;
33+
34+ /* 2d image to 1d array */
35+ dst_idx = (dst_y * dst->width + dst_x) * 3;
36+
37+ if (src_x >= 0 && src_x < src->width &&
38+ src_y >= 0 && src_y < src->height) {
39+
40+ int src_idx = (src_y * src->width + src_x) * 3;
41+
42+ dst->data[dst_idx] = src->data[src_idx];
43+ dst->data[dst_idx + 1] = src->data[src_idx + 1];
44+ dst->data[dst_idx + 2] = src->data[src_idx + 2];
45+
46+ } else {
47+ dst->data[dst_idx] = 255;
48+ dst->data[dst_idx + 1] = 255;
49+ dst->data[dst_idx + 2] = 255;
50+ }
51+ }
52+ }
53+}
54+
55+void place_tile(Ppm *tile, Ppm *grid, int tile_col, int tile_row) {
56+ int x, y, src_idx, dst_idx, dst_x, dst_y;
57+
58+ for (y = 0; y < tile->height; y++) {
59+ for (x = 0; x < tile->width; x++) {
60+
61+ /* calculate index starting in the given col and row */
62+ dst_x = tile_col * tile->width + x;
63+ dst_y = tile_row * tile->height + y;
64+
65+ /* 2d image to 1d array in the current image*/
66+ src_idx = (y * tile->width + x) * 3;
67+
68+ /* 2d image to 1d array in the whole grid*/
69+ dst_idx = (dst_y * grid->width + dst_x) * 3;
70+
71+ /* move the pixels over */
72+ grid->data[dst_idx] = tile->data[src_idx];
73+ grid->data[dst_idx + 1] = tile->data[src_idx + 1];
74+ grid->data[dst_idx + 2] = tile->data[src_idx + 2];
75+ }
76+ }
77+}
78+
79+int main(void) {
80+ FILE *in, *out;
81+ char magic[3];
82+ int width, height, max_val;
83+ int i, val, cell;
84+ double degrees[9];
85+ Ppm src, rotated, grid;
86+
87+ srand((unsigned int)time(NULL));
88+
89+ for (cell = 0; cell < 9; cell++)
90+ degrees[cell] = (double)(rand() % 3600) / 10.0;
91+
92+ in = fopen("theclassic.ppm", "r");
93+ if (!in) {
94+ perror("failed to open file, theclassic.ppm");
95+ return 1;
96+ }
97+
98+ fscanf(in, "%2s %d %d %d", magic, &width, &height, &max_val);
99+
100+ if (magic[0] != 'P' || magic[1] != '3') {
101+ fprintf(stderr, "only P3 plx(ascii)\n");
102+ fclose(in);
103+ return 1;
104+ }
105+
106+ src.width = width;
107+ src.height = height;
108+ src.data = (unsigned char *)malloc(width * height * 3);
109+
110+ rotated.width = width;
111+ rotated.height = height;
112+ rotated.data = (unsigned char *)malloc(width * height * 3);
113+
114+ grid.width = width * 3;
115+ grid.height = height * 3;
116+
117+ size_t src_size = (size_t)width * height * 3;
118+ size_t grid_size = (size_t)grid.width * grid.height * 3;
119+
120+ grid.data = (unsigned char *)malloc(grid_size);
121+
122+ if (!src.data || !rotated.data || !grid.data) {
123+ fprintf(stderr, "Memory allocation failed.\n");
124+ return 1;
125+ }
126+
127+ /* avoid garbage pixels */
128+ memset(grid.data, 255, grid_size);
129+
130+ for (i = 0; i < src_size; i++) {
131+ fscanf(in, "%d", &val);
132+ src.data[i] = (unsigned char)val;
133+ }
134+ fclose(in);
135+
136+ for (cell = 0; cell < 9; cell++) {
137+ int tile_col = cell % 3;
138+ int tile_row = cell / 3;
139+
140+ rotate_image(&src, &rotated, degrees[cell]);
141+ place_tile(&rotated, &grid, tile_col, tile_row);
142+ }
143+
144+ out = fopen("output.ppm", "w");
145+ if (!out) {
146+ perror("failed to open the file output.ppm");
147+ return 1;
148+ }
149+
150+ /* write the header */
151+ fprintf(out, "P3\n%d %d\n255\n", grid.width, grid.height);
152+
153+ for (i = 0; i < (int)grid_size; i+=3) {
154+ if (grid.data[i] == 0 && grid.data[i + 1] == 0 && grid.data[i + 2] == 0)
155+ switch (rand() % 4) {
156+ case 0: fprintf(out, "0 0 0 "); break;
157+ case 1: fprintf(out, "255 0 0 "); break;
158+ case 2: fprintf(out, "0 255 0 "); break;
159+ case 3: fprintf(out, "0 0 255 "); break;
160+ }
161+ else {
162+ fprintf(out, "%d %d %d ",
163+ grid.data[i],
164+ grid.data[i + 1],
165+ grid.data[i + 2]);
166+ }
167+
168+ if ((i + 1) % (grid.width * 3) == 0) {
169+ fprintf(out, "\n");
170+ }
171+ }
172+
173+ fclose(out);
174+
175+ free(src.data);
176+ free(rotated.data);
177+ free(grid.data);
178+
179+ printf("done %s (%dx%d)\n", "output.ppm", grid.width, grid.height);
180+ return 0;
181+}