Skip to content

Commit 930f49b

Browse files
committed
farbherd support; reverse sorting direction.
1 parent cc24cdb commit 930f49b

File tree

2 files changed

+118
-33
lines changed

2 files changed

+118
-33
lines changed

Makefile

+6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1+
# ff-sort
2+
# change this...
13
CC ?= cc
24
CFLAGS ?= -Os
35
CPPFLAGS += -pedantic -Wall -Wextra
6+
FARBHERD=1
47

58
DESTDIR ?= /usr/local
69

10+
# but not this..
11+
CPPFLAGS += -DFARBHERD=$(FARBHERD)
12+
713
BINS=ff-sort
814
all: $(BINS)
915

ff-sort.c

+112-33
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,23 @@
1414
#include <fcntl.h>
1515
#include <getopt.h>
1616

17+
#if FARBHERD == 1
18+
#include <farbherd.h>
19+
#endif
20+
1721
#include "conversion.h"
1822

1923
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
2024
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
2125
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
2226
#define PPOS(x, y) (x + (y*w))
2327
#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+
}
2834

2935
static void usage(char* self, int status) {
3036
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) {
7581
}
7682

7783
// Global crap.
78-
uint32_t w, h;
84+
static uint32_t w, h;
85+
static int farbherd = 0;
7986

8087
// Selection options
8188
static int options;
8289
#define SEL_X 0
8390
#define SEL_Y 1
8491

85-
static int detection;
92+
static int detection = 0;
8693
#define SEL_BRUTE 0
8794
#define SEL_EDGES 1 // soon.
8895

@@ -150,7 +157,8 @@ static inline void sort(pixel* queue, int amount, uint16_t* img, int x, int y) {
150157
int i;
151158
for (i = 0; i < amount; i++) {
152159
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);
154162
}
155163
}
156164

@@ -176,63 +184,123 @@ static inline void compare(int x, int y, uint16_t* img, pixel* queue, int* amoun
176184
}
177185
}
178186

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) {
195188
pixel px_min;
196189
pixel px_max;
197190
px_min.px[0] = min; px_min.px[1] = min;
198191
px_min.px[2] = min; px_min.px[3] = min;
199192
px_max.px[0] = max; px_max.px[1] = max;
200193
px_max.px[2] = max; px_max.px[3] = max;
201194

202-
chew(stdin, img, w * h * 8);
195+
if (img != out) {
196+
memcpy(out, img, w * h * 8);
197+
}
203198

204199
// process
205200
pixel current;
206201
unsigned int x, y;
207202
if (options == SEL_X) {
208203
for (y = 0; y < h; y++) {
209204
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);
213210
}
214211
} else {
215212
for (x = 0; x < w; x++) {
216213
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);
220219
}
221220
}
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+
}
222232

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);
223241
spew(stdout, img, w * h * 8);
224242
fflush(stdout);
225243
return 0;
226244
}
227245

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+
228296
// entry point.
229297
int main(int argc, char* argv[]) {
230298
if (argc < 2)
231299
usage(argv[0], 1);
232300

233301
// parse arguments
234302
int opt;
235-
while ((opt = getopt(argc, argv, "xyiu:l:t:")) != -1) {
303+
while ((opt = getopt(argc, argv, "xyrhu:l:t:")) != -1) {
236304
switch (opt) {
237305
case 'x':
238306
options = SEL_X;
@@ -241,10 +309,14 @@ int main(int argc, char* argv[]) {
241309
options = SEL_Y;
242310
break;
243311

244-
case 'i':
312+
case 'r':
245313
dir = DIR_REVERSE;
246314
break;
247315

316+
case 'h':
317+
farbherd = 1;
318+
break;
319+
248320
case 'l':
249321
min = atof(optarg);
250322
break;
@@ -280,5 +352,12 @@ int main(int argc, char* argv[]) {
280352
usage(argv[0], 1);
281353
}
282354

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();
284363
}

0 commit comments

Comments
 (0)