blind-square-gradient.c (2330B)
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_multiplier; 10 11 #define FILE "blind-square-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 or 3 pixels\n"); 43 44 with_multiplier = 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; 62 TYPE x, y, p, r, rx, ry; 63 size_t 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_multiplier) 77 rd = (params)[9]; 78 memmove(stream->buf, stream->buf + stream->frame_size, 79 stream->ptr -= stream->frame_size); 80 81 x2 -= x1; 82 y2 -= y1; 83 norm = sqrt(x2 * x2 + y2 * y2); 84 x2 /= norm; 85 y2 /= norm; 86 87 for (iy = 0; iy < height; iy++) { 88 y = (TYPE)iy - y1; 89 for (ix = 0; ix < width; ix++) { 90 x = (TYPE)ix - x1; 91 p = x * x2 + y * y2; 92 rx = x - p * x2; 93 ry = y - p * y2; 94 r = sqrt(rx * rx + ry * ry) / rd; 95 p = abs(p); 96 x = MAX(p, r) / norm; 97 buf[ptr][0] = buf[ptr][1] = buf[ptr][2] = buf[ptr][3] = x; 98 if (++ptr == ELEMENTSOF(buf)) { 99 ewriteall(STDOUT_FILENO, buf, sizeof(buf), "<stdout>"); 100 ptr = 0; 101 } 102 } 103 } 104 } 105 } 106 107 #endif