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