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