blind-linear-gradient.c (2091B)
1 /* See LICENSE file for copyright and license details. */ 2 #ifndef TYPE 3 #include "common.h" 4 5 USAGE("[-b] -w width -h height") 6 7 static int bilinear = 0; 8 static size_t width = 0; 9 static size_t height = 0; 10 11 #define FILE "blind-linear-gradient.c" 12 #include "define-functions.h" 13 14 int 15 main(int argc, char *argv[]) 16 { 17 struct stream stream; 18 void (*process)(struct stream *stream); 19 20 ARGBEGIN { 21 case 'b': 22 bilinear = 1; 23 break; 24 case 'w': 25 width = etozu_flag('w', UARGF(), 1, SIZE_MAX); 26 break; 27 case 'h': 28 height = etozu_flag('h', UARGF(), 1, SIZE_MAX); 29 break; 30 default: 31 usage(); 32 } ARGEND; 33 34 if (!width || !height || argc) 35 usage(); 36 37 eopen_stream(&stream, NULL); 38 39 SELECT_PROCESS_FUNCTION(&stream); 40 CHECK_N_CHAN(&stream, 4, 4); 41 42 if (stream.width > 2 || stream.height > 2 || stream.width * stream.height != 2) 43 eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); 44 45 stream.width = width; 46 stream.height = height; 47 fprint_stream_head(stdout, &stream); 48 efflush(stdout, "<stdout>"); 49 process(&stream); 50 return 0; 51 } 52 53 #else 54 55 static void 56 PROCESS(struct stream *stream) 57 { 58 typedef TYPE pixel_t[4]; 59 pixel_t buf[BUFSIZ / sizeof(pixel_t)]; 60 TYPE *params, x1, y1, x2, y2, norm2; 61 TYPE x, y; 62 size_t i, ix, iy, ptr = 0; 63 64 for (;;) { 65 while (stream->ptr < stream->frame_size) { 66 if (!eread_stream(stream, stream->frame_size - stream->ptr)) { 67 ewriteall(STDOUT_FILENO, buf, ptr * sizeof(*buf), "<stdout>"); 68 return; 69 } 70 } 71 params = (TYPE *)stream->buf; 72 x1 = (params)[0]; 73 y1 = (params)[1]; 74 x2 = (params)[4]; 75 y2 = (params)[5]; 76 memmove(stream->buf, stream->buf + stream->frame_size, 77 stream->ptr -= stream->frame_size); 78 79 x2 -= x1; 80 y2 -= y1; 81 norm2 = x2 * x2 + y2 * y2; 82 83 for (iy = 0; iy < height; iy++) { 84 y = (TYPE)iy - y1; 85 for (ix = 0; ix < width; ix++) { 86 x = (TYPE)ix - x1; 87 x = (x * x2 + y * y2) / norm2; 88 if (bilinear) 89 x = abs(x); 90 for (i = 0; i < stream->n_chan; i++) 91 buf[ptr][i] = x; 92 if (++ptr == ELEMENTSOF(buf)) { 93 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); 94 ptr = 0; 95 } 96 } 97 } 98 } 99 } 100 101 #endif