blind-extend.c (2504B)
1 /* See LICENSE file for copyright and license details. */ 2 #include "common.h" 3 4 USAGE("[-l left] [-r right] [-a above] [-b below] [-t]") 5 6 int 7 main(int argc, char *argv[]) 8 { 9 struct stream stream; 10 char *buf, *image; 11 size_t m, imgw, imgh, rown; 12 size_t xoff, yoff, h, x, y; 13 size_t left = 0, right = 0, top = 0, bottom = 0; 14 int tile = 0; 15 16 ARGBEGIN { 17 case 'l': 18 left = etozu_flag('l', UARGF(), 0, SIZE_MAX); 19 break; 20 case 'r': 21 right = etozu_flag('r', UARGF(), 0, SIZE_MAX); 22 break; 23 case 'a': 24 top = etozu_flag('a', UARGF(), 0, SIZE_MAX); 25 break; 26 case 'b': 27 bottom = etozu_flag('b', UARGF(), 0, SIZE_MAX); 28 break; 29 case 't': 30 tile = 1; 31 break; 32 default: 33 usage(); 34 } ARGEND; 35 36 if (argc) 37 usage(); 38 39 eopen_stream(&stream, NULL); 40 41 echeck_dimensions(&stream, WIDTH | HEIGHT, NULL); 42 buf = emalloc(stream.frame_size); 43 44 if (stream.width > SIZE_MAX - left) 45 eprintf("<stdout>: output video is too wide\n"); 46 imgw = stream.width + left; 47 if (imgw > SIZE_MAX - right) 48 eprintf("<stdout>: output video is too wide\n"); 49 imgw += right; 50 if (stream.height > SIZE_MAX - top) 51 eprintf("<stdout>: output video is too tall\n"); 52 imgh = stream.height + top; 53 if (imgh > SIZE_MAX - bottom) 54 eprintf("<stdout>: output video is too tall\n"); 55 imgh += bottom; 56 echeck_dimensions_custom(imgw, imgh, 0, stream.pixel_size, "output", "<stdout>"); 57 m = imgh * (imgw *= stream.pixel_size); 58 image = tile ? emalloc(m) : ecalloc(1, m); 59 60 stream.width += left + right; 61 h = stream.height += top + bottom; 62 fprint_stream_head(stdout, &stream); 63 efflush(stdout, "<stdout>"); 64 stream.width -= left + right; 65 stream.height -= top + bottom; 66 67 left *= stream.pixel_size; 68 right *= stream.pixel_size; 69 rown = stream.width * stream.pixel_size; 70 71 xoff = (rown - left % rown) % rown; 72 yoff = (stream.height - top % stream.height) % stream.height; 73 74 while (eread_frame(&stream, buf)) { 75 if (!tile) { 76 for (y = 0; y < stream.height; y++) 77 memcpy(image + left + (y + top) * imgw, buf + y * rown, rown); 78 } else { 79 for (y = 0; y < stream.height; y++) 80 for (x = 0; x < imgw; x++) 81 image[x + (y + top) * imgw] = buf[(x + xoff) % rown + y * rown]; 82 for (y = 0; y < top; y++) 83 memcpy(image + y * imgw, image + ((y + yoff) % stream.height + top) * imgw, imgw); 84 for (y = top + stream.height; y < h; y++) 85 memcpy(image + y * imgw, image + ((y + yoff) % stream.height + top) * imgw, imgw); 86 } 87 ewriteall(STDOUT_FILENO, image, m, "<stdout>"); 88 } 89 90 free(buf); 91 free(image); 92 return 0; 93 }