blind-radial-gradient.c (2874B)
1 /* See LICENSE file for copyright and license details. */ 2 #ifndef TYPE 3 #include "common.h" 4 5 USAGE("-w width -h height") 6 7 static size_t width = 0; 8 static size_t height = 0; 9 static int with_params; 10 11 #define FILE "blind-radial-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 'w': 22 width = etozu_flag('w', UARGF(), 1, SIZE_MAX); 23 break; 24 case 'h': 25 height = etozu_flag('h', UARGF(), 1, SIZE_MAX); 26 break; 27 default: 28 usage(); 29 } ARGEND; 30 31 if (!width || !height || argc) 32 usage(); 33 34 eopen_stream(&stream, NULL); 35 36 SELECT_PROCESS_FUNCTION(&stream); 37 CHECK_N_CHAN(&stream, 4, 4); 38 39 if (stream.width > 3 || stream.height > 3 || 40 stream.width * stream.height < 2 || 41 stream.width * stream.height > 3) 42 eprintf("<stdin>: each frame must contain exactly 2 pixels\n"); 43 44 with_params = stream.width * stream.height == 3; 45 46 stream.width = width; 47 stream.height = height; 48 fprint_stream_head(stdout, &stream); 49 efflush(stdout, "<stdout>"); 50 process(&stream); 51 return 0; 52 } 53 54 #else 55 56 static void 57 PROCESS(struct stream *stream) 58 { 59 typedef TYPE pixel_t[4]; 60 pixel_t buf[BUFSIZ / sizeof(pixel_t)]; 61 TYPE *params, x1, y1, x2, y2, norm, rd = 1, pe = 2, re = 2, e = 0.5; 62 TYPE x, y, p, r, rx, ry; 63 size_t i, ix, iy, ptr = 0; 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 if (with_params) { 77 pe = (params)[8]; 78 re = (params)[9]; 79 rd = (params)[10]; 80 e = 1 / sqrt(pe * re); 81 } 82 memmove(stream->buf, stream->buf + stream->frame_size, 83 stream->ptr -= stream->frame_size); 84 85 x2 -= x1; 86 y2 -= y1; 87 norm = sqrt(x2 * x2 + y2 * y2); 88 89 if (!with_params) { 90 for (iy = 0; iy < height; iy++) { 91 y = (TYPE)iy - y1; 92 y *= y; 93 for (ix = 0; ix < width; ix++) { 94 x = (TYPE)ix - x1; 95 x = sqrt(x * x + y) / norm; 96 for (i = 0; i < stream->n_chan; i++) 97 buf[ptr][i] = x; 98 if (++ptr == ELEMENTSOF(buf)) { 99 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); 100 ptr = 0; 101 } 102 } 103 } 104 } else { 105 for (iy = 0; iy < height; iy++) { 106 y = (TYPE)iy - y1; 107 for (ix = 0; ix < width; ix++) { 108 x = (TYPE)ix - x1; 109 p = (x * x2 + y * y2) / norm; 110 rx = x - p * x2 / norm; 111 ry = y - p * y2 / norm; 112 r = sqrt(rx * rx + ry * ry) / rd; 113 p = pow(abs(p / norm), pe); 114 r = pow(abs(r / norm), re); 115 x = pow(p + r, e); 116 for (i = 0; i < stream->n_chan; i++) 117 buf[ptr][i] = x; 118 if (++ptr == ELEMENTSOF(buf)) { 119 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); 120 ptr = 0; 121 } 122 } 123 } 124 } 125 } 126 } 127 128 #endif