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+}