blind-affine-colour.c (3345B)
1 /* See LICENSE file for copyright and license details. */ 2 #ifndef TYPE 3 #include "common.h" 4 5 USAGE("[-alp] matrix-stream") 6 7 static int skip_alpha = 0; 8 static int linear = 0; 9 static int per_pixel = 0; 10 static size_t dim; 11 12 #define FILE "blind-affine-colour.c" 13 #include "define-functions.h" 14 15 int 16 main(int argc, char *argv[]) 17 { 18 struct stream colour, matrix; 19 void (*process)(struct stream *colour, struct stream *matrix); 20 size_t h; 21 22 ARGBEGIN { 23 case 'a': 24 skip_alpha = 1; 25 break; 26 case 'l': 27 linear = 1; 28 break; 29 case 'p': 30 per_pixel = 1; 31 break; 32 default: 33 usage(); 34 } ARGEND; 35 36 if (argc != 1) 37 usage(); 38 39 eopen_stream(&colour, NULL); 40 eopen_stream(&matrix, argv[0]); 41 42 SELECT_PROCESS_FUNCTION(&colour); 43 if (skip_alpha && colour.alpha_chan != -1) 44 CHECK_CHANS(&colour, == (short int)(colour.n_chan - 1), == colour.luma_chan); 45 else 46 skip_alpha = 0; 47 48 if (strcmp(colour.pixfmt, matrix.pixfmt)) 49 eprintf("videos use incompatible pixel formats\n"); 50 51 dim = colour.n_chan - (size_t)skip_alpha + (size_t)!linear; 52 h = matrix.height, matrix.height = dim; 53 echeck_dimensions(&matrix, WIDTH | HEIGHT, "matrix"); 54 matrix.height = h; 55 56 if (per_pixel) { 57 if (matrix.height != dim * colour.height || matrix.width != dim * colour.width) 58 eprintf("the matrice should have the size %zux%zu, but are %zux%zu", 59 dim * colour.height, dim * colour.width, matrix.height, matrix.width); 60 } else { 61 if (matrix.height != dim || matrix.width != dim) 62 eprintf("the matrice should have the size %zux%zu, but are %zux%zu", 63 dim, dim, matrix.height, matrix.width); 64 } 65 66 fprint_stream_head(stdout, &colour); 67 efflush(stdout, "<stdout>"); 68 process(&colour, &matrix); 69 return 0; 70 } 71 72 #else 73 74 static void 75 PROCESS(struct stream *colour, struct stream *matrix) 76 { 77 char *mbuf; 78 TYPE *mat, *pixel, V[5], M[ELEMENTSOF(V)][ELEMENTSOF(V)]; 79 size_t ptr, i, j, w, x = 0, y = 0, cn; 80 81 mbuf = emalloc2(dim, matrix->row_size); 82 mat = (TYPE *)mbuf; 83 w = matrix->width * matrix->n_chan; 84 cn = colour->n_chan - (size_t)skip_alpha; 85 86 memset(M, 0, sizeof(M)); 87 for (i = 0; i < ELEMENTSOF(V); i++) 88 M[i][i] = V[i] = 1; 89 90 do { 91 for (ptr = 0; ptr + colour->pixel_size <= colour->ptr; x = (x + 1) % colour->width, ptr += colour->pixel_size) { 92 if (!x) { 93 if (!y && !eread_segment(matrix, mbuf, dim * matrix->row_size)) 94 break; 95 if (!per_pixel) { 96 if (!y) { 97 mat = (TYPE *)mbuf; 98 for (i = 0; i < dim; i++, mat += w) 99 for (j = 0; j < dim; j++) 100 M[i][j] = mat[j * matrix->n_chan + 1] 101 * mat[(j + 1) * matrix->n_chan - 1]; 102 } 103 y = (y + 1) % colour->height; 104 } 105 } 106 if (per_pixel) { 107 mat = (TYPE *)(mbuf + x * dim * matrix->pixel_size); 108 for (i = 0; i < dim; i++, mat += w) 109 for (j = 0; j < dim; j++) 110 M[i][j] = mat[j * matrix->n_chan + 1] 111 * mat[(j + 1) * matrix->n_chan - 1]; 112 } 113 pixel = (TYPE *)(colour->buf + ptr); 114 for (i = 0; i < dim; i++) { 115 V[i] = 0; 116 for (j = 0; j < cn; j++) 117 V[i] += M[i][j] * pixel[j]; 118 for (; j < dim; j++) 119 V[i] += M[i][j]; 120 } 121 for (i = 0; i < cn; i++) 122 pixel[i] = V[i] / V[cn]; 123 } 124 ewriteall(STDOUT_FILENO, colour->buf, ptr, "<stdout>"); 125 memmove(colour->buf, colour->buf + ptr, colour->ptr -= ptr); 126 } while (eread_stream(colour, SIZE_MAX)); 127 if (colour->ptr) 128 eprintf("%s: incomplete frame\n", colour->file); 129 130 free(mbuf); 131 } 132 133 #endif