44*/
55#include <pthread.h>
66#include <stdbool.h>
7+ #include <stdio.h>
78#include <stdlib.h>
9+ #include <unistd.h>
810#include <X11/Xlib.h>
911#include <X11/X.h>
1012
@@ -32,6 +34,13 @@ typedef struct Screenshot {
3234} Screenshot ;
3335
3436
37+ unsigned char calc_diff (unsigned char one , unsigned char two ) {
38+ /** Calculate the absolute difference between two values */
39+ int diff = (int ) one - (int ) two ;
40+ return diff < 0 ? - diff : diff ;
41+ }
42+
43+
3544CaptureArgs * init_capture (int divider , int sat_bias , int lower , int upper ,
3645 bool brightness_norm , unsigned char * target_color ,
3746 pthread_mutex_t * target_lock , bool * exit_flag ,
@@ -62,39 +71,6 @@ CaptureArgs* init_capture(int divider, int sat_bias, int lower, int upper,
6271}
6372
6473
65- void capturer (struct CaptureArgs * args ) {
66- /** Function designed to be run in a thread, captures screenshots
67- *
68- */
69- while (true) {
70- pthread_mutex_lock (args -> exit_lock );
71- bool exit = * (args -> exit_flag );
72- pthread_mutex_unlock (args -> exit_lock );
73- if (exit )
74- break ;
75-
76- unsigned char target [3 ];
77- Screenshot * screenshot ;
78-
79- capture (& screenshot , args -> gwa , args -> display , args -> root );
80- calc_dominant_color (screenshot -> data , screenshot -> w , screenshot -> h ,
81- target , args -> divider , args -> saturation_bias ,
82- args -> lower_threshold , args -> upper_threshold ,
83- args -> brightness_norm );
84-
85- free (screenshot -> data );
86- free (screenshot );
87-
88- pthread_mutex_lock (args -> keyboard_lock );
89- pthread_mutex_lock (args -> target_lock );
90- for (int i = 0 ; i < 3 ; i ++ )
91- args -> target_color [i ] = target [i ];
92- pthread_mutex_unlock (args -> target_lock );
93- pthread_mutex_unlock (args -> keyboard_lock );
94- }
95- }
96-
97-
9874void capture (Screenshot * * screenshot , XWindowAttributes gwa ,
9975 Display * display , Window root ) {
10076 /** Capture screenshot and save it to Screenshot struct
@@ -108,6 +84,9 @@ void capture(Screenshot** screenshot, XWindowAttributes gwa,
10884
10985 (* screenshot )-> data = (unsigned char * ) malloc (
11086 width * height * 3 * sizeof (unsigned char ));
87+ (* screenshot )-> w = width ;
88+ (* screenshot )-> h = height ;
89+
11190 XImage * img = XGetImage (
11291 display , root , 0 , 0 , width , height , AllPlanes , ZPixmap );
11392 unsigned long masks [3 ] = {
@@ -136,18 +115,18 @@ void calc_dominant_color(unsigned char* data, int w, int h,
136115 unsigned long colors [3 ] = {0 };
137116 unsigned long n_pixels = 0 ;
138117
118+ divider = divider == 0 ? 1 : divider ;
139119 int width = w / divider ;
140120
141121 /// Summing of pixels fitting criteria
142122 for (int x = 0 ; x < width ; x ++ ) {
143123 for (int y = 0 ; y < h ; y ++ ) {
144124 unsigned int sum = 0 ;
145- unsigned char r , g , b ;
146125 int max_diff = 0 ;
147- unsigned char * pixel = data [x + y * w ] ;
126+ unsigned char * pixel = & ( data [( x + y * w ) * 3 ]) ;
148127 for (int i = 0 ; i < 3 ; i ++ ) {
149128 int first = i , second = i + 1 < 3 ? i + 1 : 0 ;
150- unsigned char diff = pixel [first ] - pixel [second ];
129+ unsigned char diff = calc_diff ( pixel [first ], pixel [second ]) ;
151130 max_diff = diff > max_diff ? diff : max_diff ;
152131 sum += pixel [i ];
153132 }
@@ -160,19 +139,58 @@ void calc_dominant_color(unsigned char* data, int w, int h,
160139 }
161140
162141 /// Averaging
163- unsigned char color [3 ];
164142 unsigned char max = 0 ;
165143 for (int i = 0 ; i < 3 ; i ++ ) {
166144 if (n_pixels == 0 ) {
167145 target [i ] = 0xFF ; // Error condition
168146 continue ;
169147 }
170148 target [i ] = (unsigned char ) (colors [i ] / n_pixels );
171- max = color [i ] > max ? color [i ] : max ;
149+ max = target [i ] > max ? target [i ] : max ;
172150 }
173151
152+ max = max == 0 ? 0xFF : max ;
153+
174154 /// Normalization
175155 if (brightness_norm && max != 0xFF )
176156 for (int i = 0 ; i < 3 ; i ++ )
177- target [i ] = (unsigned char ) ((double ) color [i ] * (255.0 / (double ) max ));
178- }
157+ target [i ] = (unsigned char ) ((double ) target [i ] * (255.0 / (double ) max ));
158+
159+ }
160+
161+
162+ void capturer (struct CaptureArgs * args ) {
163+ /** Function designed to be run in a thread, captures screenshots
164+ *
165+ */
166+ unsigned char target [3 ], previous [3 ];
167+
168+ while (true) {
169+ pthread_mutex_lock (args -> exit_lock );
170+ bool exit = * (args -> exit_flag );
171+ pthread_mutex_unlock (args -> exit_lock );
172+ if (exit )
173+ break ;
174+
175+ Screenshot * screenshot ;
176+
177+ capture (& screenshot , args -> gwa , args -> display , args -> root );
178+
179+ calc_dominant_color (screenshot -> data , screenshot -> w , screenshot -> h ,
180+ target , args -> divider , args -> saturation_bias ,
181+ args -> lower_threshold , args -> upper_threshold ,
182+ args -> brightness_norm );
183+
184+ free (screenshot -> data );
185+ free (screenshot );
186+
187+ pthread_mutex_lock (args -> keyboard_lock );
188+ pthread_mutex_lock (args -> target_lock );
189+ for (int i = 0 ; i < 3 ; i ++ ) {
190+ args -> target_color [i ] = target [i ];
191+ previous [i ] = target [i ];
192+ }
193+ pthread_mutex_unlock (args -> target_lock );
194+ pthread_mutex_unlock (args -> keyboard_lock );
195+ }
196+ }
0 commit comments