-
Notifications
You must be signed in to change notification settings - Fork 0
/
modification_and_write_image.c
127 lines (103 loc) · 3.42 KB
/
modification_and_write_image.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "modification_and_write_image.h"
newimg* ppm_desaturate(u_char* image, int width, int height)
{
int x, y;
newimg * newimage=(newimg*)malloc(sizeof(newimg));
newimage->width=width;
newimage->height=height;
// For each pixel ...
for (x = 0 ; x < width ; x++)
{
for (y = 0 ; y < height ; y++)
{
u_int grey_lvl = 0;
int rgb_canal;
// Compute the grey level
for (rgb_canal = 0 ; rgb_canal < 3 ; rgb_canal++)
{
grey_lvl += image[ 3 * (y * width + x) + rgb_canal ];
}
grey_lvl /= 3;
assert(grey_lvl >= 0 && grey_lvl <=255);
// Set the corresponding pixel's value in new_image
memset(&image[3 * (y * width + x)], grey_lvl, 3);
}
}
newimage->data=image;
return newimage;
}
newimg* ppm_shrink(u_char** image, int *width, int *height, int factor)
{
// Compute new image size and allocate memory for the new image
int new_width = (*width) / factor;
int new_height = (*height) / factor;
u_char* new_image = (u_char*) malloc(3 * new_width * new_height * sizeof(*new_image));
newimg * newimage=(newimg*)malloc(sizeof(newimg));
newimage->width=new_width;
newimage->height=new_height;
// Precompute factor^2 (for performance reasons)
int factor_squared = factor * factor;
// For each pixel of the new image...
int x, y;
for (x = 0 ; x < new_width ; x++)
{
for (y = 0 ; y < new_height ; y++)
{
// ... compute the average RGB values of the set of pixels (a square of side factor)
// that correspond to the pixel we are creating.
// Initialize RGB values for the new image's pixel
u_int red = 0;
u_int green = 0;
u_int blue = 0;
// Compute coordinates and index of the first (top-left) pixel from the
// model image corresponding to the pixel we are creating
int x0 = x * factor;
int y0 = y * factor;
int i0 = 3 * (y0 * (*width) + x0);
// Compute RGB values for the new pixel
int dx, dy;
for (dx = 0 ; dx < factor ; dx++)
{
for (dy = 0 ; dy < factor ; dy++)
{
// Compute the offset of the current pixel (in the model image)
// with regard to the top-left pixel of the current "set of pixels"
int delta_i = 3 * (dy * (*width) + dx);
// Accumulate RGB values
red += (*image)[i0+delta_i];
green += (*image)[i0+delta_i+1];
blue += (*image)[i0+delta_i+2];
}
}
// Divide RGB values to get the mean values
red /= factor_squared;
green /= factor_squared;
blue /= factor_squared;
// Set new pixel's RGB values
new_image[ 3 * (y * new_width + x) ] = red;
new_image[ 3 * (y * new_width + x) + 1 ] = green;
new_image[ 3 * (y * new_width + x) + 2 ] = blue;
}
}
// Update image
newimage->data=new_image;
return newimage;
}
void ppm_write_to_file(newimg* newimage, char *name)
{
//open the file
FILE *file=fopen(name,"wb");
int width = newimage->width;
int height = newimage->height;
u_char *data = newimage->data;
// Write header
fprintf(file, "P6\n%d %d\n255\n", width, height);
// Write pixels
fwrite(data, 3, width*height, file);
//close the file
fclose(file);
}