11#include "helpers.h"
22#include <stdint.h>
33#include <stdlib.h>
4- #include <math.h>
54#include "bmp.h"
6-
7- int min ( int a , int b ) {
8- return ( a < b ) ? a : b ;
5+ int min ( int a , int b ){
6+ if ( a < b ) return a ;
7+ return b ;
98}
10- int max (int a , int b ) {
11- return (a > b ) ? a : b ;
9+ int max (int a ,int b ){
10+ if (a > b ) return a ;
11+ return b ;
1212}
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 ++ ) {
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 ++ ){
1717 int red = image [i ][j ].rgbtRed ;
1818 int green = image [i ][j ].rgbtGreen ;
1919 int blue = image [i ][j ].rgbtBlue ;
@@ -25,62 +25,108 @@ void grayscale(int height, int width, RGBTRIPLE image[height][width]) {
2525 }
2626}
2727
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 ++ ) {
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
3133 int red = image [i ][j ].rgbtRed ;
3234 int green = image [i ][j ].rgbtGreen ;
3335 int blue = image [i ][j ].rgbtBlue ;
3436
37+ //Normal inversion
3538 int invRed = 255 - red ;
3639 int invGreen = 255 - green ;
3740 int invBlue = 255 - blue ;
3841
39- int originalBrightness = 0.299 * red + 0.587 * green + 0.114 * blue ;
40- int invertedBrightness = 0.299 * invRed + 0.587 * invGreen + 0.114 * invBlue ;
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 ;
4145 int brightnessDiff = originalBrightness - invertedBrightness ;
4246
4347 invRed = min (max (invRed + brightnessDiff , 0 ), 255 );
4448 invGreen = min (max (invGreen + brightnessDiff , 0 ), 255 );
4549 invBlue = min (max (invBlue + brightnessDiff , 0 ), 255 );
4650
51+ //Assign
4752 image [i ][j ].rgbtRed = invRed ;
4853 image [i ][j ].rgbtGreen = invGreen ;
4954 image [i ][j ].rgbtBlue = invBlue ;
5055 }
5156 }
57+ return ;
58+
59+ // Convert image to grayscale
60+
5261}
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+ }
5388
54- void sepia (int height , int width , RGBTRIPLE image [height ][width ]) {
55- // TODO: Implement sepia filter (currently empty)
5689}
5790
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 ++ ) {
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
61101 RGBTRIPLE temp = image [i ][j ];
62102 image [i ][j ] = image [i ][width - 1 - j ];
63103 image [i ][width - 1 - j ] = temp ;
64104 }
65105 }
106+
66107}
67108
68- void blur (int height , int width , RGBTRIPLE image [height ][width ]) {
109+
110+ void blur (int height , int width , RGBTRIPLE image [height ][width ]){
111+ // Allocate temporary array on heap
69112 RGBTRIPLE * * temp = malloc (height * sizeof (RGBTRIPLE * ));
70113 for (int i = 0 ; i < height ; i ++ )
71114 temp [i ] = malloc (width * sizeof (RGBTRIPLE ));
72115
73- int kernelSize = 21 ;
116+ int kernelSize = 21 ; // large kernel for heavy blur
74117 int offset = kernelSize / 2 ;
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 ++ ) {
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 ++ ){
81127 int ni = i + ki ;
82128 int nj = j + kj ;
83- if (ni >= 0 && ni < height && nj >= 0 && nj < width ) {
129+ if (ni >= 0 && ni < height && nj >= 0 && nj < width ){
84130 sumRed += image [ni ][nj ].rgbtRed ;
85131 sumGreen += image [ni ][nj ].rgbtGreen ;
86132 sumBlue += image [ni ][nj ].rgbtBlue ;
@@ -93,6 +139,7 @@ void blur(int height, int width, RGBTRIPLE image[height][width]) {
93139 temp [i ][j ].rgbtBlue = (uint8_t )(sumBlue / count );
94140 }
95141 }
142+ // Copy blurred array back to orig
96143 for (int i = 0 ; i < height ; i ++ )
97144 for (int j = 0 ; j < width ; j ++ )
98145 image [i ][j ] = temp [i ][j ];
@@ -102,37 +149,22 @@ void blur(int height, int width, RGBTRIPLE image[height][width]) {
102149 free (temp );
103150}
104151
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- }
152+ // Blur image
153+
123154
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 ++ ) {
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 ++ ){
130161 float disx = j - cx ;
131162 float disy = i - cy ;
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 ;
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 ;
136168 image [i ][j ].rgbtRed = (int )(image [i ][j ].rgbtRed * vig );
137169 image [i ][j ].rgbtGreen = (int )(image [i ][j ].rgbtGreen * vig );
138170 image [i ][j ].rgbtBlue = (int )(image [i ][j ].rgbtBlue * vig );
0 commit comments