blind-spectrum.c (4885B)
1 /* See LICENSE file for copyright and license details. */ 2 #ifndef TYPE 3 #include "common.h" 4 5 USAGE("[-y] [-z depth] spectrum-stream") 6 7 static int luma = 0; 8 static size_t nz = 1; 9 10 #define FILE "blind-spectrum.c" 11 #include "define-functions.h" 12 13 int 14 main(int argc, char *argv[]) 15 { 16 struct stream stream, spectrum; 17 void (*process)(struct stream *stream, struct stream *spectrum); 18 19 ARGBEGIN { 20 case 'y': 21 luma = 1; 22 break; 23 case 'z': 24 nz = etozu_flag('z', UARGF(), 1, SIZE_MAX); 25 break; 26 default: 27 usage(); 28 } ARGEND; 29 30 if (argc != 1) 31 usage(); 32 33 eopen_stream(&stream, NULL); 34 eopen_stream(&spectrum, argv[0]); 35 36 SELECT_PROCESS_FUNCTION(&stream); 37 CHECK_CHANS(&stream, == 3, == (luma ? 1 : stream.luma_chan)); 38 CHECK_N_CHAN(&stream, 4, 4); 39 40 if (stream.n_chan != spectrum.n_chan || stream.encoding != spectrum.encoding) 41 eprintf("videos use incompatible pixel formats\n"); 42 43 echeck_dimensions(&spectrum, WIDTH | HEIGHT, "spectrum"); 44 45 fprint_stream_head(stdout, &stream); 46 efflush(stdout, "<stdout>"); 47 process(&stream, &spectrum); 48 return 0; 49 } 50 51 #else 52 53 static void 54 PROCESS(struct stream *stream, struct stream *spectrum) 55 { 56 TYPE *table = emalloc2(nz, spectrum->frame_size); 57 size_t i, n, m = 0; 58 TYPE x, y, z, a, x1, y1, z1, a1, x2, y2, z2, a2, ix, iy, iz, wx, wy, wz; 59 size_t s, t, nx, ny, nxy; 60 nx = spectrum->width; 61 ny = spectrum->height; 62 nxy = nx * ny; 63 if (luma) 64 ny = nxy * nz; 65 do { 66 if (!m) { 67 m = stream->frame_size; 68 for (i = 0; i < nz; i++) { 69 if (!eread_frame(spectrum, ((char *)table) + i * spectrum->frame_size)) { 70 if (!i) 71 goto done; 72 eprintf("%s: incomplete frame set\n", spectrum->file); 73 } 74 } 75 } 76 n = MIN(stream->ptr, m) / stream->pixel_size; 77 for (i = 0; i < n; i++) { 78 if (luma) { 79 iy = ((TYPE *)(stream->buf))[4 * i + 1]; 80 iy = MIN(MAX(iy, (TYPE)0), (TYPE)1); 81 iy *= (TYPE)(ny - 1); 82 s = (size_t)iy; 83 t = s + 1; 84 t = t == ny ? ny - 1 : t; 85 wy = mod(iy, (TYPE)1); 86 x = table[4 * s + 0] * (1 - wy) + table[4 * t + 0] * wy; 87 y = table[4 * s + 1] * (1 - wy) + table[4 * t + 1] * wy; 88 z = table[4 * s + 2] * (1 - wy) + table[4 * t + 2] * wy; 89 a = table[4 * s + 3] * (1 - wy) + table[4 * t + 3] * wy; 90 } else { 91 ix = ((TYPE *)(stream->buf))[4 * i + 0]; 92 iy = ((TYPE *)(stream->buf))[4 * i + 1]; 93 iz = ((TYPE *)(stream->buf))[4 * i + 2]; 94 ix = MIN(MAX(ix, (TYPE)0), (TYPE)1); 95 iy = MIN(MAX(iy, (TYPE)0), (TYPE)1); 96 iz = MIN(MAX(iz, (TYPE)0), (TYPE)1); 97 ix *= (TYPE)(nx - 1); 98 iy *= (TYPE)(ny - 1); 99 iz *= (TYPE)(nz - 1); 100 wx = mod(ix, (TYPE)1); 101 wy = mod(iy, (TYPE)1); 102 wz = mod(iz, (TYPE)1); 103 s = (size_t)ix; 104 t = s + 1; 105 t = t == nx ? nx - 1 : t; 106 s += (size_t)iy * nx; 107 t += (size_t)iy * nx; 108 s += (size_t)iz * nxy; 109 t += (size_t)iz * nxy; 110 x = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx; 111 y = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx; 112 z = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx; 113 a = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx; 114 if ((size_t)iy != ny - 1) { 115 s += nx, t += nx; 116 x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx; 117 y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx; 118 z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx; 119 a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx; 120 x = x * (1 - wy) + x2 * wy; 121 y = y * (1 - wy) + y2 * wy; 122 z = z * (1 - wy) + z2 * wy; 123 a = a * (1 - wy) + a2 * wy; 124 s -= nx, t -= nx; 125 } 126 if ((size_t)iz != nz - 1) { 127 s += nxy, t += nxy; 128 x1 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx; 129 y1 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx; 130 z1 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx; 131 a1 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx; 132 if ((size_t)iy != ny - 1) { 133 s += nx, t += nx; 134 x2 = table[4 * s + 0] * (1 - wx) + table[4 * t + 0] * wx; 135 y2 = table[4 * s + 1] * (1 - wx) + table[4 * t + 1] * wx; 136 z2 = table[4 * s + 2] * (1 - wx) + table[4 * t + 2] * wx; 137 a2 = table[4 * s + 3] * (1 - wx) + table[4 * t + 3] * wx; 138 x1 = x1 * (1 - wy) + x2 * wy; 139 y1 = y1 * (1 - wy) + y2 * wy; 140 z1 = z1 * (1 - wy) + z2 * wy; 141 a1 = a1 * (1 - wy) + a2 * wy; 142 } 143 x = x * (1 - wz) + x1 * wz; 144 y = y * (1 - wz) + y1 * wz; 145 z = z * (1 - wz) + z1 * wz; 146 a = a * (1 - wz) + a1 * wz; 147 } 148 } 149 ((TYPE *)(stream->buf))[4 * i + 0] = x; 150 ((TYPE *)(stream->buf))[4 * i + 1] = y; 151 ((TYPE *)(stream->buf))[4 * i + 2] = z; 152 ((TYPE *)(stream->buf))[4 * i + 3] *= a; 153 } 154 n *= stream->pixel_size; 155 m -= n; 156 ewriteall(STDOUT_FILENO, stream->buf, n, "<stdout>"); 157 memmove(stream->buf, stream->buf + n, stream->ptr -= n); 158 } while (eread_stream(stream, SIZE_MAX)); 159 if (stream->ptr) 160 eprintf("%s: incomplete frame\n", stream->file); 161 done: 162 free(table); 163 } 164 165 #endif