14
14
#include <fcntl.h>
15
15
#include <getopt.h>
16
16
17
+ #if FARBHERD == 1
18
+ #include <farbherd.h>
19
+ #endif
20
+
17
21
#include "conversion.h"
18
22
19
23
#define eprintf (...) fprintf(stderr, __VA_ARGS__)
20
24
#define MIN (x , y ) (((x) < (y)) ? (x) : (y))
21
25
#define MAX (x , y ) (((x) > (y)) ? (x) : (y))
22
26
#define PPOS (x , y ) (x + (y*w))
23
27
#define COPY4 (src , srci , dst , dsti ) \
24
- dst[dsti + 0] = src[srci + 0]; \
25
- dst[dsti + 1] = src[srci + 1]; \
26
- dst[dsti + 2] = src[srci + 2]; \
27
- dst[dsti + 3] = src[srci + 3] \
28
+ if (src != dst) { \
29
+ dst[dsti + 0] = src[srci + 0]; \
30
+ dst[dsti + 1] = src[srci + 1]; \
31
+ dst[dsti + 2] = src[srci + 2]; \
32
+ dst[dsti + 3] = src[srci + 3]; \
33
+ }
28
34
29
35
static void usage (char * self , int status ) {
30
36
eprintf ("Usage: <farbfeld source> | %s [-x|-y] [-t type] [-l min] [-u max] [type] [args..] | <farbfeld sink>\n" , self );
@@ -75,14 +81,15 @@ static void ffparse(FILE* food, FILE* out, uint32_t* w, uint32_t* h) {
75
81
}
76
82
77
83
// Global crap.
78
- uint32_t w , h ;
84
+ static uint32_t w , h ;
85
+ static int farbherd = 0 ;
79
86
80
87
// Selection options
81
88
static int options ;
82
89
#define SEL_X 0
83
90
#define SEL_Y 1
84
91
85
- static int detection ;
92
+ static int detection = 0 ;
86
93
#define SEL_BRUTE 0
87
94
#define SEL_EDGES 1 // soon.
88
95
@@ -150,7 +157,8 @@ static inline void sort(pixel* queue, int amount, uint16_t* img, int x, int y) {
150
157
int i ;
151
158
for (i = 0 ; i < amount ; i ++ ) {
152
159
int p = ((options == SEL_X ) ? PPOS ((x - amount + i ), y ) : PPOS (x , (y - amount + i ))) * 4 ;
153
- COPY4 (queue [i ].orig , 0 , img , p );
160
+ int op = (dir == DIR_NORMAL ) ? i : (amount - i );
161
+ COPY4 (queue [op ].orig , 0 , img , p );
154
162
}
155
163
}
156
164
@@ -176,63 +184,123 @@ static inline void compare(int x, int y, uint16_t* img, pixel* queue, int* amoun
176
184
}
177
185
}
178
186
179
- static int do_stuff (void ) {
180
- // parse input image
181
- ffparse (stdin , stdout , & w , & h );
182
-
183
- uint16_t * img = malloc (w * h * 8 );
184
- if (!img ) {
185
- fprintf (stderr , "Error: Failed to alloc framebuffer.\n" );
186
- return 2 ;
187
- }
188
-
189
- pixel * queue = calloc ((options == SEL_X ) ? w : h , sizeof (pixel ));
190
- if (!queue ) {
191
- fprintf (stderr , "Error: Failed to alloc sorting queue.\n" );
192
- return 2 ;
193
- }
194
-
187
+ static void sort_img (uint16_t * img , uint16_t * out , pixel * queue , uint32_t w , uint32_t h ) {
195
188
pixel px_min ;
196
189
pixel px_max ;
197
190
px_min .px [0 ] = min ; px_min .px [1 ] = min ;
198
191
px_min .px [2 ] = min ; px_min .px [3 ] = min ;
199
192
px_max .px [0 ] = max ; px_max .px [1 ] = max ;
200
193
px_max .px [2 ] = max ; px_max .px [3 ] = max ;
201
194
202
- chew (stdin , img , w * h * 8 );
195
+ if (img != out ) {
196
+ memcpy (out , img , w * h * 8 );
197
+ }
203
198
204
199
// process
205
200
pixel current ;
206
201
unsigned int x , y ;
207
202
if (options == SEL_X ) {
208
203
for (y = 0 ; y < h ; y ++ ) {
209
204
int amount = 0 ;
210
- for (x = 0 ; x < w ; x ++ )
211
- compare (x , y , img , queue , & amount , & current , & px_min , & px_max );
212
- sort (queue , amount , img , w , y );
205
+ for (x = 0 ; x < w ; x ++ ) {
206
+ //COPY4(img, PPOS(x, y) * 4, out, PPOS(x, y) * 4);
207
+ compare (x , y , out , queue , & amount , & current , & px_min , & px_max );
208
+ }
209
+ sort (queue , amount , out , w , y );
213
210
}
214
211
} else {
215
212
for (x = 0 ; x < w ; x ++ ) {
216
213
int amount = 0 ;
217
- for (y = 0 ; y < h ; y ++ )
218
- compare (x , y , img , queue , & amount , & current , & px_min , & px_max );
219
- sort (queue , amount , img , x , h );
214
+ for (y = 0 ; y < h ; y ++ ) {
215
+ //COPY4(img, PPOS(x, y) * 4, out, PPOS(x, y) * 4);
216
+ compare (x , y , out , queue , & amount , & current , & px_min , & px_max );
217
+ }
218
+ sort (queue , amount , out , x , h );
220
219
}
221
220
}
221
+ }
222
+
223
+ static int nom_farbfeld (void ) {
224
+ // parse input image
225
+ ffparse (stdin , stdout , & w , & h );
226
+
227
+ uint16_t * img = malloc (w * h * 8 );
228
+ if (!img ) {
229
+ fprintf (stderr , "Error: Failed to alloc framebuffer.\n" );
230
+ return 2 ;
231
+ }
222
232
233
+ pixel * queue = calloc ((options == SEL_X ) ? w : h , sizeof (pixel ));
234
+ if (!queue ) {
235
+ fprintf (stderr , "Error: Failed to alloc sorting queue.\n" );
236
+ return 2 ;
237
+ }
238
+
239
+ chew (stdin , img , w * h * 8 );
240
+ sort_img (img , img , queue , w , h );
223
241
spew (stdout , img , w * h * 8 );
224
242
fflush (stdout );
225
243
return 0 ;
226
244
}
227
245
246
+ #if FARBHERD == 1
247
+ static int nom_farbherd (void ) {
248
+ farbherd_header_t head ;
249
+ if (farbherd_read_farbherd_header (stdin , & head )) {
250
+ fprintf (stderr , "Failed to read farbherd header.\n" );
251
+ return 1 ;
252
+ }
253
+ farbherd_write_farbherd_header (stdout , head );
254
+ fflush (stdout );
255
+
256
+ size_t datasize = farbherd_datasize (head .imageHead );
257
+ uint16_t * work = calloc (1 , datasize );
258
+ uint16_t * input = calloc (1 , datasize );
259
+ uint16_t * output = malloc (datasize );
260
+ if (!work || !input || !output ) {
261
+ fprintf (stderr , "Failed to allocate work memory.\n" );
262
+ return 1 ;
263
+ }
264
+
265
+ w = head .imageHead .width ;
266
+ h = head .imageHead .height ;
267
+
268
+ pixel * queue = calloc ((options == SEL_X ) ? w : h , sizeof (pixel ));
269
+ if (!queue ) {
270
+ fprintf (stderr , "Error: Failed to alloc sorting queue.\n" );
271
+ return 2 ;
272
+ }
273
+
274
+ farbherd_frame_t inputframe ;
275
+ if (farbherd_init_farbherd_frame (& inputframe , head )) {
276
+ fprintf (stderr , "Failed to allocate incoming frame memory\n" );
277
+ return 1 ;
278
+ }
279
+
280
+ while (1 ) {
281
+ if (farbherd_read_farbherd_frame (stdin , & inputframe , head ))
282
+ return 0 ;
283
+ farbherd_apply_delta (input , inputframe .deltas , datasize );
284
+
285
+ // do the sorting.
286
+ sort_img (input , output , queue , w , h );
287
+
288
+ farbherd_calc_apply_delta (work , output , datasize );
289
+ fwrite (output , datasize , 1 , stdout );
290
+ fflush (stdout );
291
+ }
292
+ return 0 ;
293
+ }
294
+ #endif
295
+
228
296
// entry point.
229
297
int main (int argc , char * argv []) {
230
298
if (argc < 2 )
231
299
usage (argv [0 ], 1 );
232
300
233
301
// parse arguments
234
302
int opt ;
235
- while ((opt = getopt (argc , argv , "xyiu :l:t:" )) != -1 ) {
303
+ while ((opt = getopt (argc , argv , "xyrhu :l:t:" )) != -1 ) {
236
304
switch (opt ) {
237
305
case 'x' :
238
306
options = SEL_X ;
@@ -241,10 +309,14 @@ int main(int argc, char* argv[]) {
241
309
options = SEL_Y ;
242
310
break ;
243
311
244
- case 'i ' :
312
+ case 'r ' :
245
313
dir = DIR_REVERSE ;
246
314
break ;
247
315
316
+ case 'h' :
317
+ farbherd = 1 ;
318
+ break ;
319
+
248
320
case 'l' :
249
321
min = atof (optarg );
250
322
break ;
@@ -280,5 +352,12 @@ int main(int argc, char* argv[]) {
280
352
usage (argv [0 ], 1 );
281
353
}
282
354
283
- return do_stuff ();
355
+ if (farbherd ) {
356
+ #if FARBHERD == 1
357
+ return nom_farbherd ();
358
+ #endif
359
+ fprintf (stderr , "Farbherd is not supported in this build. :(\n" );
360
+ return 2 ;
361
+ }
362
+ return nom_farbfeld ();
284
363
}
0 commit comments