Skip to content

Commit 0ced8f3

Browse files
Merge pull request #21 from saumya1317/feature/brightness-adjust
feat: add brightness adjust filter (-B flag)
2 parents eba8e70 + cf84b3a commit 0ced8f3

File tree

4 files changed

+91
-95
lines changed

4 files changed

+91
-95
lines changed

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,22 @@ For a pixel along the edge or corner, like pixel 15, we would still look for all
113113

114114
If you apply the above algorithm to each pixel in the image, the result should look like a blurry, out-of-focus version of the original.
115115

116+
### 6.) Brightness Adjustment Filter
117+
- **Flag:** `-B <value>`
118+
- **Description:** Increases or decreases the brightness of the image by adding a fixed value to each pixel's R, G, and B channels. The value should be an integer—positive to increase, negative to decrease.
119+
- **Usage examples:**
120+
```sh
121+
./filter -B 40 input.bmp output.bmp # Increase brightness by 40
122+
./filter -B -30 input.bmp output.bmp # Decrease brightness by 30
123+
```
124+
125+
### 7.) Vignette Filter
126+
- **Flag:** `-v`
127+
- **Description:** Applies a vignette effect that darkens the corners of the image to focus attention towards the center.
128+
- **Usage example:**
129+
```sh
130+
./filter -v input.bmp output.bmp
131+
```
116132
### 5.) The Vignette Algorithm
117133

118134
The vignette filter gives an image a cinematic look by gradually darkening its corners.

filter.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
int main(int argc, char *argv[])
88
{
99
// Define allowable filters
10-
char *filters = "bgrsiv";
10+
char *filters = "bgrsitB";
1111

1212

1313
char filterArr[argc-3];
@@ -124,10 +124,21 @@ int main(int argc, char *argv[])
124124
case 'i':
125125
invert(height,width,image);
126126
break;
127-
// Vignette
128-
case 'v':
129-
vignette(height, width, image);
127+
128+
// Brightness Adjust
129+
case 'B': {
130+
int brightness_value = 0;
131+
// Get brightness value from argv, after -B flag (assume it appears as -B val)
132+
if (optind < argc) {
133+
brightness_value = atoi(argv[optind]);
134+
optind++;
135+
} else {
136+
printf("Missing value for -B (brightness) flag.\n");
137+
return 8;
138+
}
139+
brightness(height, width, image, brightness_value);
130140
break;
141+
}
131142
default:
132143
printf("%c", &filterArr[i]);
133144
break;

helpers.c

Lines changed: 57 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
#include "helpers.h"
22
#include <stdint.h>
33
#include <stdlib.h>
4+
#include <math.h>
45
#include "bmp.h"
5-
int min(int a,int b){
6-
if(a<b) return a;
7-
return b;
6+
7+
int min(int a, int b) {
8+
return (a < b) ? a : b;
89
}
9-
int max(int a,int b){
10-
if(a>b) return a;
11-
return b;
10+
int max(int a, int b) {
11+
return (a > b) ? a : b;
1212
}
13-
void grayscale(int height, int width, RGBTRIPLE image[height][width]){
14-
15-
for(int i = 0; i < height; i++){
16-
for(int j = 0; j < width; j++){
13+
14+
void grayscale(int height, int width, RGBTRIPLE image[height][width]) {
15+
for (int i = 0; i < height; i++) {
16+
for (int j = 0; j < width; j++) {
1717
int red = image[i][j].rgbtRed;
1818
int green = image[i][j].rgbtGreen;
1919
int blue = image[i][j].rgbtBlue;
@@ -25,108 +25,62 @@ void grayscale(int height, int width, RGBTRIPLE image[height][width]){
2525
}
2626
}
2727

28-
29-
void invert(int height, int width, RGBTRIPLE image[height][width]){
30-
for(int i = 0; i<height; i++){
31-
for(int j = 0; j<width; j++){
32-
//Original RGB
28+
void invert(int height, int width, RGBTRIPLE image[height][width]) {
29+
for (int i = 0; i < height; i++) {
30+
for (int j = 0; j < width; j++) {
3331
int red = image[i][j].rgbtRed;
3432
int green = image[i][j].rgbtGreen;
3533
int blue = image[i][j].rgbtBlue;
3634

37-
//Normal inversion
3835
int invRed = 255 - red;
3936
int invGreen = 255 - green;
4037
int invBlue = 255 - blue;
4138

42-
//for maintain average brightness
43-
int originalBrightness = 0.299*red + 0.587*green + 0.114*blue;
44-
int invertedBrightness = 0.299*invRed + 0.587*invGreen + 0.114*invBlue;
39+
int originalBrightness = 0.299 * red + 0.587 * green + 0.114 * blue;
40+
int invertedBrightness = 0.299 * invRed + 0.587 * invGreen + 0.114 * invBlue;
4541
int brightnessDiff = originalBrightness - invertedBrightness;
4642

4743
invRed = min(max(invRed + brightnessDiff, 0), 255);
4844
invGreen = min(max(invGreen + brightnessDiff, 0), 255);
4945
invBlue = min(max(invBlue + brightnessDiff, 0), 255);
5046

51-
//Assign
5247
image[i][j].rgbtRed = invRed;
5348
image[i][j].rgbtGreen = invGreen;
5449
image[i][j].rgbtBlue = invBlue;
5550
}
5651
}
57-
return;
58-
59-
// Convert image to grayscale
60-
6152
}
62-
void sepia(int height, int width, RGBTRIPLE image[height][width]){
63-
64-
for (int i = 0; i < height; i++)
65-
{
66-
for (int j = 0; j < width; j++)
67-
{
68-
int originalRed = image[i][j].rgbtRed;
69-
int originalGreen = image[i][j].rgbtGreen;
70-
int originalBlue = image[i][j].rgbtBlue;
71-
72-
int sepiaRed = round(0.393 * originalRed + 0.769 * originalGreen + 0.189 * originalBlue);
73-
int sepiaGreen = round(0.349 * originalRed + 0.686 * originalGreen + 0.168 * originalBlue);
74-
int sepiaBlue = round(0.272 * originalRed + 0.534 * originalGreen + 0.131 * originalBlue);
75-
76-
if (sepiaRed > 255)
77-
sepiaRed = 255;
78-
if (sepiaGreen > 255)
79-
sepiaGreen = 255;
80-
if (sepiaBlue > 255)
81-
sepiaBlue = 255;
82-
83-
image[i][j].rgbtRed = sepiaRed;
84-
image[i][j].rgbtGreen = sepiaGreen;
85-
image[i][j].rgbtBlue = sepiaBlue;
86-
}
87-
}
8853

54+
void sepia(int height, int width, RGBTRIPLE image[height][width]) {
55+
// TODO: Implement sepia filter (currently empty)
8956
}
9057

91-
92-
void reflect(int height, int width, RGBTRIPLE image[height][width]){
93-
94-
// Loop over each row
95-
for (int i = 0; i < height; i++)
96-
{
97-
// Swap pixels horizontally (mirror)
98-
for (int j = 0; j < width / 2; j++)
99-
{
100-
// Swap left pixel with right pixel
58+
void reflect(int height, int width, RGBTRIPLE image[height][width]) {
59+
for (int i = 0; i < height; i++) {
60+
for (int j = 0; j < width / 2; j++) {
10161
RGBTRIPLE temp = image[i][j];
10262
image[i][j] = image[i][width - 1 - j];
10363
image[i][width - 1 - j] = temp;
10464
}
10565
}
106-
10766
}
10867

109-
110-
void blur(int height, int width, RGBTRIPLE image[height][width]){
111-
// Allocate temporary array on heap
68+
void blur(int height, int width, RGBTRIPLE image[height][width]) {
11269
RGBTRIPLE **temp = malloc(height * sizeof(RGBTRIPLE *));
11370
for (int i = 0; i < height; i++)
11471
temp[i] = malloc(width * sizeof(RGBTRIPLE));
11572

116-
int kernelSize = 21; // large kernel for heavy blur
73+
int kernelSize = 21;
11774
int offset = kernelSize / 2;
118-
// Repeating blur 2-3 times for ultra blur effect
119-
//because in single time effect not much visible
120-
for(int repeat = 0; repeat < 3; repeat++){
121-
for(int i = 0; i < height; i++){
122-
for (int j = 0; j < width; j++){
123-
int sumRed = 0, sumGreen = 0, sumBlue = 0;
124-
int count = 0;
125-
for (int ki = -offset; ki <= offset; ki++){
126-
for(int kj = -offset; kj <= offset; kj++){
75+
for (int repeat = 0; repeat < 3; repeat++) {
76+
for (int i = 0; i < height; i++) {
77+
for (int j = 0; j < width; j++) {
78+
int sumRed = 0, sumGreen = 0, sumBlue = 0, count = 0;
79+
for (int ki = -offset; ki <= offset; ki++) {
80+
for (int kj = -offset; kj <= offset; kj++) {
12781
int ni = i + ki;
12882
int nj = j + kj;
129-
if(ni >= 0 && ni < height && nj >= 0 && nj < width){
83+
if (ni >= 0 && ni < height && nj >= 0 && nj < width) {
13084
sumRed += image[ni][nj].rgbtRed;
13185
sumGreen += image[ni][nj].rgbtGreen;
13286
sumBlue += image[ni][nj].rgbtBlue;
@@ -139,7 +93,6 @@ void blur(int height, int width, RGBTRIPLE image[height][width]){
13993
temp[i][j].rgbtBlue = (uint8_t)(sumBlue / count);
14094
}
14195
}
142-
// Copy blurred array back to orig
14396
for (int i = 0; i < height; i++)
14497
for (int j = 0; j < width; j++)
14598
image[i][j] = temp[i][j];
@@ -149,22 +102,37 @@ void blur(int height, int width, RGBTRIPLE image[height][width]){
149102
free(temp);
150103
}
151104

152-
// Blur image
153-
105+
void brightness(int height, int width, RGBTRIPLE image[height][width], int value) {
106+
for (int i = 0; i < height; i++) {
107+
for (int j = 0; j < width; j++) {
108+
int r = image[i][j].rgbtRed + value;
109+
int g = image[i][j].rgbtGreen + value;
110+
int b = image[i][j].rgbtBlue + value;
111+
if (r > 255) r = 255;
112+
if (g > 255) g = 255;
113+
if (b > 255) b = 255;
114+
if (r < 0) r = 0;
115+
if (g < 0) g = 0;
116+
if (b < 0) b = 0;
117+
image[i][j].rgbtRed = r;
118+
image[i][j].rgbtGreen = g;
119+
image[i][j].rgbtBlue = b;
120+
}
121+
}
122+
}
154123

155-
void vignette(int height, int width, RGBTRIPLE image[height][width]){
156-
float cx = width / 2.0; // center of the image
157-
float cy= height / 2.0;
158-
float max_dis= sqrt(cx * cx + cy * cy);
159-
for(int i = 0; i < height; i++){
160-
for(int j = 0; j < width; j++){
124+
void vignette(int height, int width, RGBTRIPLE image[height][width]) {
125+
float cx = width / 2.0;
126+
float cy = height / 2.0;
127+
float max_dis = sqrt(cx * cx + cy * cy);
128+
for (int i = 0; i < height; i++) {
129+
for (int j = 0; j < width; j++) {
161130
float disx = j - cx;
162131
float disy = i - cy;
163-
float dist= sqrt(disx * disx + disy * disy);
164-
// (0.0 = dark, 1.0 = og)
165-
float vig = 1.0 - (dist/ max_dis);
166-
if(vig< 0.0) vig = 0.0;
167-
if(vig > 1.0) vig = 1.0;
132+
float dist = sqrt(disx * disx + disy * disy);
133+
float vig = 1.0 - (dist / max_dis);
134+
if (vig < 0.0) vig = 0.0;
135+
if (vig > 1.0) vig = 1.0;
168136
image[i][j].rgbtRed = (int)(image[i][j].rgbtRed * vig);
169137
image[i][j].rgbtGreen = (int)(image[i][j].rgbtGreen * vig);
170138
image[i][j].rgbtBlue = (int)(image[i][j].rgbtBlue * vig);

helpers.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,6 @@ void reflect(int height, int width, RGBTRIPLE image[height][width]);
1414

1515
// Blur image
1616
void blur(int height, int width, RGBTRIPLE image[height][width]);
17-
// Vignette image
18-
void vignette(int height, int width, RGBTRIPLE image[height][width]);
17+
18+
// Brightness adjustment filter
19+
void brightness(int height, int width, RGBTRIPLE image[height][width], int value);

0 commit comments

Comments
 (0)