Luma and composite fixes
[melted] / src / modules / lumas / luma.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdint.h>
4 #include <string.h>
5
6 typedef struct
7 {
8 int type;
9 int w;
10 int h;
11 int bands;
12 int rband;
13 int vmirror;
14 int hmirror;
15 int dmirror;
16 int invert;
17 int offset;
18 int flip;
19 int flop;
20 int pflip;
21 int pflop;
22 int quart;
23 int rotate;
24 }
25 luma;
26
27 void luma_init( luma *this )
28 {
29 memset( this, 0, sizeof( luma ) );
30 this->type = 0;
31 this->w = 720;
32 this->h = 576;
33 this->bands = 1;
34 this->rband = 0;
35 this->vmirror = 0;
36 this->hmirror = 0;
37 this->dmirror = 0;
38 this->invert = 0;
39 this->offset = 0;
40 this->flip = 0;
41 this->flop = 0;
42 this->quart = 0;
43 this->pflop = 0;
44 this->pflip = 0;
45 }
46
47 static inline int sqrti( int n )
48 {
49 int p = 0;
50 int q = 1;
51 int r = n;
52 int h = 0;
53
54 while( q <= n )
55 q = 4 * q;
56
57 while( q != 1 )
58 {
59 q = q / 4;
60 h = p + q;
61 p = p / 2;
62 if ( r >= h )
63 {
64 p = p + q;
65 r = r - h;
66 }
67 }
68
69 return p;
70 }
71
72 uint16_t *luma_render( luma *this )
73 {
74 int i = 0;
75 int j = 0;
76 int k = 0;
77
78 if ( this->quart )
79 {
80 this->w *= 2;
81 this->h *= 2;
82 }
83
84 if ( this->rotate )
85 {
86 int t = this->w;
87 this->w = this->h;
88 this->h = t;
89 }
90
91 int max = ( 1 << 16 ) - 1;
92 uint16_t *image = malloc( this->w * this->h * sizeof( uint16_t ) );
93 uint16_t *end = image + this->w * this->h;
94 uint16_t *p = image;
95 uint16_t *r = image;
96 int lower = 0;
97 int lpb = this->h / this->bands;
98 int rpb = max / this->bands;
99 int direction = 1;
100
101 int half_w = this->w / 2;
102 int half_h = this->h / 2;
103
104 if ( !this->dmirror && ( this->hmirror || this->vmirror ) )
105 rpb *= 2;
106
107 for ( i = 0; i < this->bands; i ++ )
108 {
109 lower = i * rpb;
110 direction = 1;
111
112 if ( this->rband && i % 2 == 1 )
113 {
114 direction = -1;
115 lower += rpb;
116 }
117
118 switch( this->type )
119 {
120 case 1:
121 {
122 int length = sqrti( half_w * half_w + lpb * lpb / 4 );
123 int value;
124 int x = 0;
125 int y = 0;
126 for ( j = 0; j < lpb; j ++ )
127 {
128 y = j - lpb / 2;
129 for ( k = 0; k < this->w; k ++ )
130 {
131 x = k - half_w;
132 value = sqrti( x * x + y * y );
133 *p ++ = lower + ( direction * rpb * ( ( max * value ) / length ) / max ) + ( j * this->offset * 2 / lpb ) + ( j * this->offset / lpb );
134 }
135 }
136 }
137 break;
138
139 case 2:
140 {
141 for ( j = 0; j < lpb; j ++ )
142 {
143 int value = ( ( j * this->w ) / lpb ) - half_w;
144 if ( value > 0 )
145 value = - value;
146 for ( k = - half_w; k < value; k ++ )
147 *p ++ = lower + ( direction * rpb * ( ( max * abs( k ) ) / half_w ) / max );
148 for ( k = value; k < abs( value ); k ++ )
149 *p ++ = lower + ( direction * rpb * ( ( max * abs( value ) ) / half_w ) / max ) + ( j * this->offset * 2 / lpb ) + ( j * this->offset / lpb );
150 for ( k = abs( value ); k < half_w; k ++ )
151 *p ++ = lower + ( direction * rpb * ( ( max * abs( k ) ) / half_w ) / max );
152 }
153 }
154 break;
155
156 case 3:
157 {
158 int length;
159 for ( j = -half_h; j < half_h; j ++ )
160 {
161 if ( j < 0 )
162 {
163 for ( k = - half_w; k < half_w; k ++ )
164 {
165 length = sqrti( k * k + j * j );
166 *p ++ = ( max / 4 * k ) / ( length + 1 );
167 }
168 }
169 else
170 {
171 for ( k = half_w; k > - half_w; k -- )
172 {
173 length = sqrti( k * k + j * j );
174 *p ++ = ( max / 2 ) + ( max / 4 * k ) / ( length + 1 );
175 }
176 }
177 }
178 }
179 break;
180
181 default:
182 for ( j = 0; j < lpb; j ++ )
183 for ( k = 0; k < this->w; k ++ )
184 *p ++ = lower + ( direction * ( rpb * ( ( k * max ) / this->w ) / max ) ) + ( j * this->offset * 2 / lpb );
185 break;
186 }
187 }
188
189 if ( this->quart )
190 {
191 this->w /= 2;
192 this->h /= 2;
193 for ( i = 1; i < this->h; i ++ )
194 {
195 p = image + i * this->w;
196 r = image + i * 2 * this->w;
197 j = this->w;
198 while ( j -- > 0 )
199 *p ++ = *r ++;
200 }
201 }
202
203 if ( this->dmirror )
204 {
205 for ( i = 0; i < this->h; i ++ )
206 {
207 p = image + i * this->w;
208 r = end - i * this->w;
209 j = ( this->w * ( this->h - i ) ) / this->h;
210 while ( j -- )
211 *( -- r ) = *p ++;
212 }
213 }
214
215 if ( this->flip )
216 {
217 uint16_t t;
218 for ( i = 0; i < this->h; i ++ )
219 {
220 p = image + i * this->w;
221 r = p + this->w;
222 while( p != r )
223 {
224 t = *p;
225 *p ++ = *( -- r );
226 *r = t;
227 }
228 }
229 }
230
231 if ( this->flop )
232 {
233 uint16_t t;
234 r = end;
235 for ( i = 1; i < this->h / 2; i ++ )
236 {
237 p = image + i * this->w;
238 j = this->w;
239 while( j -- )
240 {
241 t = *( -- p );
242 *p = *( -- r );
243 *r = t;
244 }
245 }
246 }
247
248 if ( this->hmirror )
249 {
250 p = image;
251 while ( p < end )
252 {
253 r = p + this->w;
254 while ( p != r )
255 *( -- r ) = *p ++;
256 p += this->w / 2;
257 }
258 }
259
260 if ( this->vmirror )
261 {
262 p = image;
263 r = end;
264 while ( p != r )
265 *( -- r ) = *p ++;
266 }
267
268 if ( this->invert )
269 {
270 p = image;
271 r = image;
272 while ( p < end )
273 *p ++ = max - *r ++;
274 }
275
276 if ( this->pflip )
277 {
278 uint16_t t;
279 for ( i = 0; i < this->h; i ++ )
280 {
281 p = image + i * this->w;
282 r = p + this->w;
283 while( p != r )
284 {
285 t = *p;
286 *p ++ = *( -- r );
287 *r = t;
288 }
289 }
290 }
291
292 if ( this->pflop )
293 {
294 uint16_t t;
295 end = image + this->w * this->h;
296 r = end;
297 for ( i = 1; i < this->h / 2; i ++ )
298 {
299 p = image + i * this->w;
300 j = this->w;
301 while( j -- )
302 {
303 t = *( -- p );
304 *p = *( -- r );
305 *r = t;
306 }
307 }
308 }
309
310 if ( this->rotate )
311 {
312 uint16_t *image2 = malloc( this->w * this->h * sizeof( uint16_t ) );
313 for ( i = 0; i < this->h; i ++ )
314 {
315 p = image + i * this->w;
316 r = image2 + this->h - i - 1;
317 for ( j = 0; j < this->w; j ++ )
318 {
319 *r = *( p ++ );
320 r += this->h;
321 }
322 }
323 i = this->w;
324 this->w = this->h;
325 this->h = i;
326 free( image );
327 image = image2;
328 }
329
330 return image;
331 }
332
333 int main( int argc, char **argv )
334 {
335 int arg = 1;
336 int bpp = 8;
337
338 luma this;
339 uint16_t *image = NULL;
340
341 luma_init( &this );
342
343 for ( arg = 1; arg < argc - 1; arg ++ )
344 {
345 if ( !strcmp( argv[ arg ], "-bpp" ) )
346 bpp = atoi( argv[ ++ arg ] );
347 else if ( !strcmp( argv[ arg ], "-type" ) )
348 this.type = atoi( argv[ ++ arg ] );
349 else if ( !strcmp( argv[ arg ], "-w" ) )
350 this.w = atoi( argv[ ++ arg ] );
351 else if ( !strcmp( argv[ arg ], "-h" ) )
352 this.h = atoi( argv[ ++ arg ] );
353 else if ( !strcmp( argv[ arg ], "-bands" ) )
354 this.bands = atoi( argv[ ++ arg ] );
355 else if ( !strcmp( argv[ arg ], "-rband" ) )
356 this.rband = atoi( argv[ ++ arg ] );
357 else if ( !strcmp( argv[ arg ], "-hmirror" ) )
358 this.hmirror = atoi( argv[ ++ arg ] );
359 else if ( !strcmp( argv[ arg ], "-vmirror" ) )
360 this.vmirror = atoi( argv[ ++ arg ] );
361 else if ( !strcmp( argv[ arg ], "-dmirror" ) )
362 this.dmirror = atoi( argv[ ++ arg ] );
363 else if ( !strcmp( argv[ arg ], "-offset" ) )
364 this.offset = atoi( argv[ ++ arg ] );
365 else if ( !strcmp( argv[ arg ], "-invert" ) )
366 this.invert = atoi( argv[ ++ arg ] );
367 else if ( !strcmp( argv[ arg ], "-flip" ) )
368 this.flip = atoi( argv[ ++ arg ] );
369 else if ( !strcmp( argv[ arg ], "-flop" ) )
370 this.flop = atoi( argv[ ++ arg ] );
371 else if ( !strcmp( argv[ arg ], "-pflip" ) )
372 this.pflip = atoi( argv[ ++ arg ] );
373 else if ( !strcmp( argv[ arg ], "-pflop" ) )
374 this.pflop = atoi( argv[ ++ arg ] );
375 else if ( !strcmp( argv[ arg ], "-quart" ) )
376 this.quart = atoi( argv[ ++ arg ] );
377 else if ( !strcmp( argv[ arg ], "-rotate" ) )
378 this.rotate = atoi( argv[ ++ arg ] );
379 else
380 fprintf( stderr, "ignoring %s\n", argv[ arg ] );
381 }
382
383 if ( bpp != 8 && bpp != 16 )
384 {
385 fprintf( stderr, "Invalid bpp %d\n", bpp );
386 return 1;
387 }
388
389 image = luma_render( &this );
390
391 if ( bpp == 16 )
392 {
393 uint16_t *end = image + this.w * this.h;
394 uint16_t *p = image;
395 uint8_t *q = ( uint8_t * )image;
396 while ( p < end )
397 {
398 *p ++ = ( *q << 8 ) + *( q + 1 );
399 q += 2;
400 }
401 printf( "P5\n" );
402 printf( "%d %d\n", this.w, this.h );
403 printf( "65535\n" );
404 fwrite( image, this.w * this.h * sizeof( uint16_t ), 1, stdout );
405 }
406 else
407 {
408 uint16_t *end = image + this.w * this.h;
409 uint16_t *p = image;
410 uint8_t *q = ( uint8_t * )image;
411 while ( p < end )
412 *q ++ = ( uint8_t )( *p ++ >> 8 );
413 printf( "P5\n" );
414 printf( "%d %d\n", this.w, this.h );
415 printf( "255\n" );
416 fwrite( image, this.w * this.h, 1, stdout );
417 }
418
419 return 0;
420 }
421