Skip to content

Commit 1713830

Browse files
feat: spiral
1 parent a93600f commit 1713830

File tree

10 files changed

+119
-1526
lines changed

10 files changed

+119
-1526
lines changed

.github/Contributor_Guide/Project_Tour.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ Now, open up helpers.c. Here’s where the implementation of the functions decla
4343
### Compile
4444
Paste This in you Terminal(without quotes):
4545

46-
"gcc -g -std=c11 -Wall -Wextra -Wshadow filter.c helpers.c -o filter -lm"
46+
"gcc -g -std=c11 -Wall -Wextra -Wshadow filter.c helpers.c image_io.c bmp_io.c png_io.c jpeg_io.c -o filter -lm"
4747

4848

4949
### Run

ex2.png

-205 KB
Binary file not shown.

filter.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,15 @@ int main(int argc, char *argv[])
1111
char *filters = "bgrsivtdGomB:S";
1212

1313

14-
char filterArr[argc-3];
14+
/* allocate filter array on heap (was stack-allocated and later freed) */
15+
char *filterArr = NULL;
1516
int filterCount = 0;
17+
/* allocate enough space for possible flags; argc is an upper bound */
18+
filterArr = malloc(sizeof(char) * (argc > 0 ? argc : 1));
19+
if (filterArr == NULL) {
20+
fprintf(stderr, "Memory allocation failed\n");
21+
return 1;
22+
}
1623
int brightness_value = 0;
1724

1825
// gets all filter flags and checks validity

filter.exe

115 KB
Binary file not shown.

helpers.c

Lines changed: 94 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -425,39 +425,111 @@ void oilpaint(int height, int width, RGBTRIPLE image[height][width]){
425425
}
426426

427427

428+
// Pixelate (mosaic) filter: average color in blocks
429+
void pixelate(int height, int width, RGBTRIPLE image[height][width])
430+
{
431+
int block = 10; // block size (pixels)
432+
for (int by = 0; by < height; by += block)
433+
{
434+
for (int bx = 0; bx < width; bx += block)
435+
{
436+
long sumR = 0, sumG = 0, sumB = 0;
437+
int count = 0;
438+
for (int y = by; y < by + block && y < height; y++)
439+
{
440+
for (int x = bx; x < bx + block && x < width; x++)
441+
{
442+
sumR += image[y][x].rgbtRed;
443+
sumG += image[y][x].rgbtGreen;
444+
sumB += image[y][x].rgbtBlue;
445+
count++;
446+
}
447+
}
448+
if (count == 0) continue;
449+
uint8_t avgR = (uint8_t)(sumR / count);
450+
uint8_t avgG = (uint8_t)(sumG / count);
451+
uint8_t avgB = (uint8_t)(sumB / count);
452+
453+
for (int y = by; y < by + block && y < height; y++)
454+
{
455+
for (int x = bx; x < bx + block && x < width; x++)
456+
{
457+
image[y][x].rgbtRed = avgR;
458+
image[y][x].rgbtGreen = avgG;
459+
image[y][x].rgbtBlue = avgB;
460+
}
461+
}
462+
}
463+
}
464+
}
465+
466+
428467
void spiral(int height, int width, RGBTRIPLE image[height][width])
429468
{
430469
RGBTRIPLE (*output)[width] = calloc(height, width * sizeof(RGBTRIPLE));
431470
double cx = width / 2.0;
432471
double cy = height / 2.0;
433472
double max_r = sqrt(cx * cx + cy * cy);
434473
double k = 4.0;
435-
for (int y=0;y<height;y++)
474+
475+
for (int y = 0; y < height; y++)
436476
{
437-
for (int x=0;x<width;x++)
477+
for (int x = 0; x < width; x++)
438478
{
439-
double dx=x-cx;
440-
double dy=y-cy;
441-
double r=sqrt(dx*dx+dy*dy);
442-
double theta=atan2(dy,dx);
443-
double factor=(max_r-r)/max_r;
444-
double theta_new=theta+k*factor;
445-
446-
double x_new=cx+r*cos(theta_new);
447-
double y_new=cy+r*sin(theta_new);
448-
449-
if (x_new>=0&&x_new<width&&y_new>=0&&y_new<height)
450-
{
451-
output[y][x]=image[(int)y_new][(int)x_new];
452-
}
453-
else
454-
{
455-
output[y][x]=(RGBTRIPLE){0, 0, 0};
456-
}
479+
double dx = x - cx;
480+
double dy = y - cy;
481+
double r = sqrt(dx * dx + dy * dy);
482+
double theta = atan2(dy, dx);
483+
double factor = (max_r - r) / max_r;
484+
if (factor < 0.0) factor = 0.0;
485+
double theta_new = theta + k * factor;
486+
487+
double x_new = cx + r * cos(theta_new);
488+
double y_new = cy + r * sin(theta_new);
489+
490+
/* Clamp coordinates to source image to avoid empty/black pixels */
491+
if (x_new < 0.0) x_new = 0.0;
492+
if (x_new > (double)(width - 1)) x_new = (double)(width - 1);
493+
if (y_new < 0.0) y_new = 0.0;
494+
if (y_new > (double)(height - 1)) y_new = (double)(height - 1);
495+
496+
/* Bilinear interpolation for smooth sampling */
497+
int x0 = (int)floor(x_new);
498+
int x1 = x0 + 1;
499+
if (x1 >= width) x1 = x0;
500+
int y0 = (int)floor(y_new);
501+
int y1 = y0 + 1;
502+
if (y1 >= height) y1 = y0;
503+
504+
double wx = x_new - x0;
505+
double wy = y_new - y0;
506+
507+
RGBTRIPLE p00 = image[y0][x0];
508+
RGBTRIPLE p10 = image[y0][x1];
509+
RGBTRIPLE p01 = image[y1][x0];
510+
RGBTRIPLE p11 = image[y1][x1];
511+
512+
double r_val = (1 - wx) * (1 - wy) * p00.rgbtRed
513+
+ wx * (1 - wy) * p10.rgbtRed
514+
+ (1 - wx) * wy * p01.rgbtRed
515+
+ wx * wy * p11.rgbtRed;
516+
double g_val = (1 - wx) * (1 - wy) * p00.rgbtGreen
517+
+ wx * (1 - wy) * p10.rgbtGreen
518+
+ (1 - wx) * wy * p01.rgbtGreen
519+
+ wx * wy * p11.rgbtGreen;
520+
double b_val = (1 - wx) * (1 - wy) * p00.rgbtBlue
521+
+ wx * (1 - wy) * p10.rgbtBlue
522+
+ (1 - wx) * wy * p01.rgbtBlue
523+
+ wx * wy * p11.rgbtBlue;
524+
525+
output[y][x].rgbtRed = (uint8_t)round(r_val);
526+
output[y][x].rgbtGreen = (uint8_t)round(g_val);
527+
output[y][x].rgbtBlue = (uint8_t)round(b_val);
457528
}
458529
}
459-
for (int y=0;y<height;y++)
460-
for (int x=0; x<width; x++)
530+
531+
for (int y = 0; y < height; y++)
532+
for (int x = 0; x < width; x++)
461533
image[y][x] = output[y][x];
462534

463535
free(output);

image_io.c

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,23 @@ ImageFormat get_format_from_extension(const char *filename) {
5454
return IMAGE_FORMAT_UNKNOWN;
5555
}
5656
extern int read_bmp(const char *filename, ImageData *img);
57-
extern int read_png(const char *filename, ImageData *img);
58-
extern int read_jpeg(const char *filename, ImageData *img);
5957
extern int write_bmp(const char *filename, ImageData *img);
60-
extern int write_png(const char *filename, ImageData *img);
61-
extern int write_jpeg(const char *filename, ImageData *img);
58+
59+
/* Fallback stubs for PNG/JPEG handlers when libpng/libjpeg dev headers are not available.
60+
These return non-zero to indicate failure; read_image/write_image will report unsupported
61+
formats if these are invoked. Keeping them here avoids needing extra files. */
62+
int read_png(const char *filename, ImageData *img) {
63+
(void)filename; (void)img; return 1; /* fail */
64+
}
65+
int write_png(const char *filename, ImageData *img) {
66+
(void)filename; (void)img; return 1; /* fail */
67+
}
68+
int read_jpeg(const char *filename, ImageData *img) {
69+
(void)filename; (void)img; return 1; /* fail */
70+
}
71+
int write_jpeg(const char *filename, ImageData *img) {
72+
(void)filename; (void)img; return 1; /* fail */
73+
}
6274
// Read image from file
6375
int read_image(const char *filename, ImageData *img) {
6476
if (!filename || !img) {

out.bmp

-68.7 MB
Binary file not shown.

output.bmp

-68.7 MB
Binary file not shown.

output.png

-1.08 MB
Binary file not shown.

0 commit comments

Comments
 (0)