]> git.sesse.net Git - mlt/blob - src/tests/test_properties/test_properties.cpp
Add mlt_color and mlt_properties_get_color().
[mlt] / src / tests / test_properties / test_properties.cpp
1 /*
2  * Copyright (C) 2013 Dan Dennedy <dan@dennedy.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with consumer library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include <QString>
20 #include <QtTest>
21
22 #include <mlt++/Mlt.h>
23 using namespace Mlt;
24
25 extern "C" {
26 #define __DARWIN__
27 #include <framework/mlt_property.h>
28 #include <framework/mlt_animation.h>
29 }
30 #include <cfloat>
31
32 class TestProperties: public QObject
33 {
34     Q_OBJECT
35     locale_t locale;
36
37 public:
38     TestProperties() {
39 #if defined(__linux__) || defined(__DARWIN__)
40         locale = newlocale( LC_NUMERIC_MASK, "POSIX", NULL );
41 #endif
42     }
43
44 private Q_SLOTS:
45     void InstantiationIsAReference()
46     {
47         Properties p;
48         QCOMPARE(p.ref_count(), 1);
49     }
50
51     void CopyAddsReference()
52     {
53         Properties p;
54         Properties q = p;
55         QCOMPARE(p.ref_count(), 2);
56     }
57
58     void DestructionRemovesReference()
59     {
60         Properties p;
61         Properties* q = new Properties(p);
62         QCOMPARE(p.ref_count(), 2);
63         delete q;
64         QCOMPARE(p.ref_count(), 1);
65     }
66
67     void SetAndGetString()
68     {
69         Properties p;
70         p.set("key", "value");
71         QVERIFY(p.get("key"));
72         QVERIFY(QString(p.get("key")) != QString(""));
73         QCOMPARE(p.get("key"), "value");
74     }
75
76     void SetAndGetInt()
77     {
78         Properties p;
79         int i = 1;
80         p.set("key", i);
81         QCOMPARE(p.get_int("key"), i);
82     }
83
84     void SetAndGetDouble()
85     {
86         Properties p;
87         double d = 1.0;
88         p.set("key", d);
89         QCOMPARE(p.get_double("key"), d);
90     }
91
92     void SetAndGetInt64()
93     {
94         Properties p;
95         int64_t i = 1LL << 32;
96         p.set("key", i);
97         QCOMPARE(p.get_int64("key"), i);
98     }
99
100     void SetAndGetData()
101     {
102         Properties p;
103         const char *value = "value";
104         char* const s = strdup(value);
105         p.set("key", s, strlen(s), free);
106         int size = 0;
107         QCOMPARE((char*) p.get_data("key", size), value);
108         QCOMPARE(size, int(strlen(value)));
109     }
110
111     void IntFromString()
112     {
113         Properties p;
114         const char *s = "-1";
115         int i = -1;
116         p.set("key", i);
117         QCOMPARE(p.get("key"), s);
118         p.set("key", s);
119         QCOMPARE(p.get_int("key"), i);
120     }
121
122     void Int64FromString()
123     {
124         Properties p;
125         const char *s = "-1";
126         int64_t i = -1;
127         p.set("key", i);
128         QCOMPARE(p.get("key"), s);
129         p.set("key", s);
130         QCOMPARE(p.get_int64("key"), i);
131     }
132
133     void DoubleFromString()
134     {
135         Properties p;
136         const char *s = "-1.23456";
137         double d = -1.23456;
138         p.set("key", d);
139         QCOMPARE(p.get("key"), s);
140         p.set("key", s);
141         QCOMPARE(p.get_double("key"), d);
142     }
143
144     void SetNullRemovesProperty()
145     {
146         Properties p;
147         const char *s = NULL;
148         p.set("key", "value");
149         p.set("key", s);
150         QCOMPARE(p.get("key"), s);
151     }
152
153     void SetAndGetHexColor()
154     {
155         Properties p;
156         const char *hexColorString = "0xaabbccdd";
157         int hexColorInt = 0xaabbccdd;
158         p.set("key", hexColorString);
159         QCOMPARE(p.get_int("key"), hexColorInt);
160     }
161
162     void SetAndGetCssColor()
163     {
164         Properties p;
165         const char *cssColorString = "#aabbcc";
166         int cssColorInt = 0xaabbccff;
167         p.set("key", cssColorString);
168         QCOMPARE(p.get_int("key"), cssColorInt);
169
170         const char *cssColorAlphaString = "#00aabbcc";
171         int cssColorAlphaInt = 0xaabbcc00;
172         p.set("key", cssColorAlphaString);
173         QCOMPARE(p.get_int("key"), cssColorAlphaInt);
174     }
175
176     void SetAndGetTimeCode()
177     {
178         Profile profile;
179         Properties p;
180         p.set("_profile", profile.get_profile(), 0);
181         const char *timeString = "11:22:33:04";
182         p.set("key", timeString);
183         QCOMPARE(p.get_int("key"), 1023829);
184         p.set("key", 1023829);
185         QCOMPARE(p.get_time("key", mlt_time_smpte), timeString);
186     }
187
188     void SetAndGetTimeClock()
189     {
190         Profile profile;
191         Properties p;
192         p.set("_profile", profile.get_profile(), 0);
193         const char *timeString = "11:22:33.400";
194         p.set("key", timeString);
195         QCOMPARE(p.get_int("key"), 1023835);
196         p.set("key", 1023835);
197         QCOMPARE(p.get_time("key", mlt_time_clock), timeString);
198     }
199
200     void SetSimpleMathExpression()
201     {
202         Properties p;
203         p.set("key", "@16.0/9.0 *2 +3 -1");
204         QCOMPARE(p.get_int("key"), 5);
205         QCOMPARE(p.get_double("key"), 16.0/9.0 *2 +3 -1);
206     }
207
208     void PassOneProperty()
209     {
210         Properties p[2];
211         const char *s = "value";
212         p[0].set("key", s);
213         QCOMPARE(p[1].get("key"), (void*) 0);
214         p[1].pass_property(p[0], "key");
215         QCOMPARE(p[1].get("key"), s);
216     }
217
218     void PassMultipleByPrefix()
219     {
220         Properties p[2];
221         const char *s = "value";
222         p[0].set("key.one", s);
223         p[0].set("key.two", s);
224         QCOMPARE(p[1].get("key.one"), (void*) 0);
225         QCOMPARE(p[1].get("key.two"), (void*) 0);
226         p[1].pass_values(p[0], "key.");
227         QCOMPARE(p[1].get("one"), s);
228         QCOMPARE(p[1].get("two"), s);
229     }
230
231     void PassMultipleByList()
232     {
233         Properties p[2];
234         const char *s = "value";
235         p[0].set("key.one", s);
236         p[0].set("key.two", s);
237         QCOMPARE(p[1].get("key.one"), (void*) 0);
238         QCOMPARE(p[1].get("key.two"), (void*) 0);
239         p[1].pass_list(p[0], "key.one key.two");
240         QCOMPARE(p[1].get("key.one"), s);
241         QCOMPARE(p[1].get("key.two"), s);
242     }
243
244     void MirrorProperties()
245     {
246         Properties p[2];
247         p[0].mirror(p[1]);
248         p[0].set("key", "value");
249         QCOMPARE(p[1].get("key"), "value");
250     }
251
252     void InheritProperties()
253     {
254         Properties p[2];
255         p[0].set("key", "value");
256         QVERIFY(p[1].get("key") == 0);
257         p[1].inherit(p[0]);
258         QCOMPARE(p[1].get("key"), "value");
259     }
260
261     void ParseString()
262     {
263         Properties p;
264         QCOMPARE(p.get("key"), (void*) 0);
265         p.parse("key=value");
266         QCOMPARE(p.get("key"), "value");
267         p.parse("key=\"new value\"");
268         QCOMPARE(p.get("key"), "new value");
269     }
270
271     void RenameProperty()
272     {
273         Properties p;
274         p.set("key", "value");
275         QVERIFY(p.get("new key") == 0);
276         p.rename("key", "new key");
277         QCOMPARE(p.get("new key"), "value");
278     }
279
280     void SequenceDetected()
281     {
282         Properties p;
283         p.set("1", 1);
284         p.set("2", 2);
285         p.set("3", 3);
286         QVERIFY(p.is_sequence());
287         p.set("four", 4);
288         QVERIFY(!p.is_sequence());
289     }
290
291     void SerializesToYamlTiny()
292     {
293         Properties p[2];
294         p[0].set("key1", "value1");
295         p[0].set("key2", "value2");
296         p[1].set("1", "value3");
297         p[1].set("2", "value4");
298         p[0].set("seq", p[1].get_properties(), 0);
299         QCOMPARE(p[0].serialise_yaml(),
300                 "---\n"
301                 "key1: value1\n"
302                 "key2: value2\n"
303                 "seq:\n"
304                 "  - value3\n"
305                 "  - value4\n"
306                 "...\n");
307     }
308
309     void RadixRespondsToLocale()
310     {
311         Properties p;
312         p.set_lcnumeric("en_US");
313         p.set("key", "0.125");
314         QCOMPARE(p.get_double("key"), double(1) / double(8));
315         p.set_lcnumeric("de_DE");
316         p.set("key", "0,125");
317         QCOMPARE(p.get_double("key"), double(1) / double(8));
318     }
319
320     void DoubleAnimation()
321     {
322         double fps = 25.0;
323         mlt_animation a = mlt_animation_new();
324         struct mlt_animation_item_s item;
325
326         mlt_animation_parse(a, "50=1; 60=60; 100=0", 100, fps, locale);
327         mlt_animation_remove(a, 60);
328         char *a_serialized = mlt_animation_serialize(a);
329         QCOMPARE(a_serialized, "50=1;100=0");
330         if (a_serialized) free(a_serialized);
331         item.property = mlt_property_init();
332
333         mlt_animation_get_item(a, &item, 10);
334         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
335         QCOMPARE(item.is_key, 0);
336
337         mlt_animation_get_item(a, &item, 50);
338         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
339         QCOMPARE(item.is_key, 1);
340
341         mlt_animation_get_item(a, &item, 75);
342         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.5);
343         QCOMPARE(item.is_key, 0);
344
345         mlt_animation_get_item(a, &item, 100);
346         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
347         QCOMPARE(item.is_key, 1);
348
349         mlt_animation_get_item(a, &item, 110);
350         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
351         QCOMPARE(item.is_key, 0);
352
353         mlt_property_close(item.property);
354         mlt_animation_close(a);
355     }
356
357     void IntAnimation()
358     {
359         double fps = 25.0;
360         mlt_animation a = mlt_animation_new();
361         struct mlt_animation_item_s item;
362
363         mlt_animation_parse(a, "50=100; 60=60; 100=0", 100, fps, locale);
364         mlt_animation_remove(a, 60);
365         char *a_serialized = mlt_animation_serialize(a);
366         QCOMPARE(a_serialized, "50=100;100=0");
367         if (a_serialized) free(a_serialized);
368         item.property = mlt_property_init();
369
370         mlt_animation_get_item(a, &item, 10);
371         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
372         QCOMPARE(item.is_key, 0);
373
374         mlt_animation_get_item(a, &item, 50);
375         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
376         QCOMPARE(item.is_key, 1);
377
378         mlt_animation_get_item(a, &item, 75);
379         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 50);
380         QCOMPARE(item.is_key, 0);
381
382         mlt_animation_get_item(a, &item, 100);
383         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
384         QCOMPARE(item.is_key, 1);
385
386         mlt_animation_get_item(a, &item, 110);
387         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
388         QCOMPARE(item.is_key, 0);
389
390         mlt_property_close(item.property);
391         mlt_animation_close(a);
392     }
393
394     void AnimationWithTimeValueKeyframes()
395     {
396         double fps = 25.0;
397         mlt_animation a = mlt_animation_new();
398         struct mlt_animation_item_s item;
399
400         mlt_animation_parse(a, ":2.0=1; :4.0=0", 100, fps, locale);
401         char *a_serialized = mlt_animation_serialize(a);
402         // Time serializes to frame units :-\.
403         QCOMPARE(a_serialized, "50=1;100=0");
404         if (a_serialized) free(a_serialized);
405         item.property = mlt_property_init();
406
407         mlt_animation_get_item(a, &item, 10);
408         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
409         QCOMPARE(item.is_key, 0);
410
411         mlt_animation_get_item(a, &item, 50);
412         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 1.0);
413         QCOMPARE(item.is_key, 1);
414
415         mlt_animation_get_item(a, &item, 75);
416         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.5);
417         QCOMPARE(item.is_key, 0);
418
419         mlt_animation_get_item(a, &item, 100);
420         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
421         QCOMPARE(item.is_key, 1);
422
423         mlt_animation_get_item(a, &item, 110);
424         QCOMPARE(mlt_property_get_double(item.property, fps, locale), 0.0);
425         QCOMPARE(item.is_key, 0);
426
427         mlt_property_close(item.property);
428         mlt_animation_close(a);
429     }
430
431     void DiscreteIntAnimation()
432     {
433         double fps = 25.0;
434         mlt_animation a = mlt_animation_new();
435         struct mlt_animation_item_s item;
436
437         mlt_animation_parse(a, "50|=100; 60|=60; 100|=0", 100, fps, locale);
438         char *a_serialized = mlt_animation_serialize(a);
439         QCOMPARE(a_serialized, "50|=100;60|=60;100|=0");
440         if (a_serialized) free(a_serialized);
441         item.property = mlt_property_init();
442
443         mlt_animation_get_item(a, &item, 10);
444         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
445         QCOMPARE(item.is_key, 0);
446
447         mlt_animation_get_item(a, &item, 50);
448         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
449         QCOMPARE(item.is_key, 1);
450
451         mlt_animation_get_item(a, &item, 55);
452         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 100);
453         QCOMPARE(item.is_key, 0);
454
455         mlt_animation_get_item(a, &item, 60);
456         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 60);
457         QCOMPARE(item.is_key, 1);
458
459         mlt_animation_get_item(a, &item, 75);
460         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 60);
461         QCOMPARE(item.is_key, 0);
462
463         mlt_animation_get_item(a, &item, 100);
464         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
465         QCOMPARE(item.is_key, 1);
466
467         mlt_animation_get_item(a, &item, 110);
468         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
469         QCOMPARE(item.is_key, 0);
470
471         mlt_property_close(item.property);
472         mlt_animation_close(a);
473     }
474
475     void StringAnimation()
476     {
477         double fps = 25.0;
478         mlt_animation a = mlt_animation_new();
479         struct mlt_animation_item_s item;
480
481         mlt_animation_parse(a, "50=hello world; 60=\"good night\"; 100=bar", 100, fps, locale);
482         char *a_serialized = mlt_animation_serialize(a);
483         QCOMPARE(a_serialized, "50=hello world;60=\"good night\";100=bar");
484         if (a_serialized) free(a_serialized);
485         item.property = mlt_property_init();
486
487         mlt_animation_get_item(a, &item, 10);
488         QCOMPARE(mlt_property_get_string(item.property), "hello world");
489         QCOMPARE(item.is_key, 0);
490
491         mlt_animation_get_item(a, &item, 50);
492         QCOMPARE(mlt_property_get_string(item.property), "hello world");
493         QCOMPARE(item.is_key, 1);
494
495         mlt_animation_get_item(a, &item, 75);
496         QCOMPARE(mlt_property_get_string(item.property), "\"good night\"");
497         QCOMPARE(item.is_key, 0);
498
499         mlt_animation_get_item(a, &item, 100);
500         QCOMPARE(mlt_property_get_string(item.property), "bar");
501         QCOMPARE(item.is_key, 1);
502
503         mlt_animation_get_item(a, &item, 110);
504         QCOMPARE(mlt_property_get_string(item.property), "bar");
505         QCOMPARE(item.is_key, 0);
506
507         mlt_property_close(item.property);
508         mlt_animation_close(a);
509     }
510
511     void test_property_anim_get_double()
512     {
513         double fps = 25.0;
514         mlt_property p = mlt_property_init();
515         mlt_property_set_string(p, "10=100; 20=200");
516         QCOMPARE(mlt_property_get_double(p, fps, locale), 10.0);
517         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 0, 100), 100.0);
518         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 15, 100), 150.0);
519         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 20, 100), 200.0);
520
521         mlt_property_set_string(p, "1.5");
522         QCOMPARE(mlt_property_get_double(p, fps, locale), 1.5);
523         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 10, 100), 1.5);
524
525         mlt_property_close(p);
526     }
527
528     void test_property_anim_get_int()
529     {
530         double fps = 25.0;
531         mlt_property p = mlt_property_init();
532         mlt_property_set_string(p, "10=100; 20=200");
533         QCOMPARE(mlt_property_get_int(p, fps, locale), 10);
534         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 0, 100), 100);
535         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 15, 100), 150);
536         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 20, 100), 200);
537
538         mlt_property_set_string(p, "1.5");
539         QCOMPARE(mlt_property_get_int(p, fps, locale), 1);
540         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 10, 100), 1);
541
542         mlt_property_close(p);
543     }
544
545     void SmoothIntAnimation()
546     {
547         double fps = 25.0;
548         mlt_animation a = mlt_animation_new();
549         struct mlt_animation_item_s item;
550
551         mlt_animation_parse(a, "0=80;10~=80; 20~=30; 30~=40; 40~=28; 50=90; 60=0; 70=60; 80=20", 100, fps, locale);
552         item.property = mlt_property_init();
553         char *a_serialized = mlt_animation_serialize(a);
554         QCOMPARE(a_serialized, "0=80;10~=80;20~=30;30~=40;40~=28;50=90;60=0;70=60;80=20");
555         if (a_serialized) free(a_serialized);
556
557         mlt_animation_get_item(a, &item, 10);
558         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 80);
559         QCOMPARE(item.is_key, 1);
560
561         mlt_animation_get_item(a, &item, 50);
562         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 90);
563         QCOMPARE(item.is_key, 1);
564
565         mlt_animation_get_item(a, &item, 55);
566         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 45);
567         QCOMPARE(item.is_key, 0);
568
569         mlt_animation_get_item(a, &item, 60);
570         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 0);
571         QCOMPARE(item.is_key, 1);
572
573         mlt_animation_get_item(a, &item, 75);
574         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 40);
575         QCOMPARE(item.is_key, 0);
576
577         mlt_animation_get_item(a, &item, 100);
578         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 20);
579         QCOMPARE(item.is_key, 0);
580
581         mlt_animation_get_item(a, &item, 110);
582         QCOMPARE(mlt_property_get_int(item.property, fps, locale), 20);
583         QCOMPARE(item.is_key, 0);
584
585         mlt_property_close(item.property);
586         mlt_animation_close(a);
587     }
588
589     void test_property_anim_set_double()
590     {
591         double fps = 25.0;
592         mlt_property p = mlt_property_init();
593         mlt_property_set_string(p, "10=100; 20=200");
594         mlt_property_anim_set_double(p, 1.5, fps, locale, mlt_keyframe_linear, 30, 100);
595         QCOMPARE(mlt_property_get_double(p, fps, locale), 10.0);
596         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 0, 100), 100.0);
597         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 15, 100), 150.0);
598         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 20, 100), 200.0);
599         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 25, 100), 100.75);
600         QCOMPARE(mlt_property_anim_get_double(p, fps, locale, 30, 100), 1.5);
601         mlt_property_close(p);
602     }
603
604     void test_property_anim_set_int()
605     {
606         double fps = 25.0;
607         mlt_property p = mlt_property_init();
608         mlt_property_set_string(p, "10=100; 20=200");
609         mlt_property_anim_set_int(p, 300, fps, locale, mlt_keyframe_linear, 30, 100);
610         QCOMPARE(mlt_property_get_int(p, fps, locale), 10);
611         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 0, 100), 100);
612         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 15, 100), 150);
613         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 20, 100), 200);
614         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 25, 100), 250);
615         QCOMPARE(mlt_property_anim_get_int(p, fps, locale, 30, 100), 300);
616         mlt_property_close(p);
617     }
618
619     void PercentAsRatio()
620     {
621         Properties p;
622         p.set("foo", "12.3%");
623         QCOMPARE(p.get_double("foo"), 0.123);
624         p.set("foo", "456 %");
625         QCOMPARE(p.get_double("foo"), 456.0);
626     }
627
628     void PropertiesAnimInt()
629     {
630         int len = 50;
631         Properties p;
632         p.set_lcnumeric("POSIX");
633
634         // Construct animation from scratch
635         p.anim_set("foo",   0,  0, len);
636         p.anim_set("foo", 100, 50, len, mlt_keyframe_smooth);
637         QCOMPARE(p.anim_get_int("foo",  0, len), 0);
638         QCOMPARE(p.anim_get_int("foo", 25, len), 50);
639         QCOMPARE(p.anim_get_int("foo", 50, len), 100);
640         QCOMPARE(p.get("foo"), "0=0;50~=100");
641
642         // Animation from string value
643         p.set("foo", "10=100;20=200");
644         QCOMPARE(p.anim_get_int("foo",  0, len), 100);
645         QCOMPARE(p.anim_get_int("foo", 15, len), 150);
646         QCOMPARE(p.anim_get_int("foo", 20, len), 200);
647
648         // Animation from string using time clock values
649         // Need to set a profile so fps can be used to convert time to frames.
650         Profile profile("dv_pal");
651         p.set("_profile", profile.get_profile(), 0);
652         p.set("foo", ":0.0=100; :2.0=200");
653         QCOMPARE(p.anim_get_int("foo",  0, len), 100);
654         QCOMPARE(p.anim_get_int("foo", 25, len), 150);
655         QCOMPARE(p.anim_get_int("foo", 50, len), 200);
656     }
657
658     void PropertiesAnimDouble()
659     {
660         int len = 50;
661         Properties p;
662         p.set_lcnumeric("POSIX");
663
664         // Construct animation from scratch
665         p.anim_set("foo",   0.0,  0, len);
666         p.anim_set("foo", 100.0, 50, len, mlt_keyframe_smooth);
667         QCOMPARE(p.anim_get_double("foo",  0, len), 0.0);
668         QCOMPARE(p.anim_get_double("foo", 25, len), 50.0);
669         QCOMPARE(p.anim_get_double("foo", 50, len), 100.0);
670         QCOMPARE(p.get("foo"), "0=0;50~=100");
671
672         // Animation from string value
673         p.set("foo", "10=100.2;20=200.8");
674         QCOMPARE(p.anim_get_double("foo",  0, len), 100.2);
675         QCOMPARE(p.anim_get_double("foo", 15, len), 150.5);
676         QCOMPARE(p.anim_get_double("foo", 20, len), 200.8);
677
678         // Animation from string using time clock values
679         // Need to set a profile so fps can be used to convert time to frames.
680         Profile profile("dv_pal");
681         p.set("_profile", profile.get_profile(), 0);
682         p.set("foo", ":0.0=100; :2.0=200");
683         QCOMPARE(p.anim_get_double("foo",  0, len), 100.0);
684         QCOMPARE(p.anim_get_double("foo", 25, len), 150.0);
685         QCOMPARE(p.anim_get_double("foo", 50, len), 200.0);
686     }
687
688     void PropertiesStringAnimation()
689     {
690         Properties p;
691         int len = 50;
692         p.anim_set("key", "foo", 10, len);
693         p.anim_set("key", "bar", 30, len);
694         QCOMPARE(p.get("key"), "10|=foo;30|=bar");
695         p.set("key", "0=; 10=foo bar; 30=hello world");
696         QCOMPARE(p.anim_get("key",  1, len), "");
697         QCOMPARE(p.anim_get("key", 15, len), "foo bar");
698         QCOMPARE(p.anim_get("key", 45, len), "hello world");
699     }
700
701     void test_mlt_rect()
702     {
703         mlt_property p = mlt_property_init();
704         mlt_rect r = { 1, 2, 3, 4, 5 };
705
706         mlt_property_set_rect( p, r );
707         QCOMPARE(mlt_property_get_string(p), "1 2 3 4 5");
708         r.o = DBL_MIN;
709         mlt_property_set_rect( p, r );
710         QCOMPARE(mlt_property_get_string(p), "1 2 3 4");
711         r.w = DBL_MIN;
712         r.h = DBL_MIN;
713         mlt_property_set_rect( p, r );
714         QCOMPARE(mlt_property_get_string(p), "1 2");
715
716         mlt_property_set_string(p, "1.1/2.2:3.3x4.4:5.5");
717         r = mlt_property_get_rect(p, locale);
718         QCOMPARE(r.x, 1.1);
719         QCOMPARE(r.y, 2.2);
720         QCOMPARE(r.w, 3.3);
721         QCOMPARE(r.h, 4.4);
722         QCOMPARE(r.o, 5.5);
723
724         mlt_property_set_string(p, "1.1 2.2");
725         r = mlt_property_get_rect(p, locale);
726         QCOMPARE(r.x, 1.1);
727         QCOMPARE(r.y, 2.2);
728         QCOMPARE(r.w, DBL_MIN);
729
730         mlt_property_set_int64(p, UINT_MAX);
731         r = mlt_property_get_rect(p, locale);
732         QCOMPARE(r.x, double(UINT_MAX));
733
734         mlt_property_close(p);
735     }
736
737     void SetAndGetRect()
738     {
739         Properties p;
740         mlt_rect r;
741         r.x = 1.1;
742         r.y = 2.2;
743         r.w = 3.3;
744         r.h = 4.4;
745         r.o = 5.5;
746         p.set("key", r);
747         mlt_rect q = p.get_rect("key");
748         QCOMPARE(q.x, 1.1);
749         QCOMPARE(q.y, 2.2);
750         QCOMPARE(q.w, 3.3);
751         QCOMPARE(q.h, 4.4);
752         QCOMPARE(q.o, 5.5);
753         p.set("key", 10, 20, 30, 40);
754         q = p.get_rect("key");
755         QCOMPARE(q.x, 10.0);
756         QCOMPARE(q.y, 20.0);
757         QCOMPARE(q.w, 30.0);
758         QCOMPARE(q.h, 40.0);
759     }
760
761     void RectFromString()
762     {
763         Properties p;
764         p.set_lcnumeric("POSIX");
765         const char *s = "1.1 2.2 3.3 4.4 5.5";
766         mlt_rect r = { 1.1, 2.2, 3.3, 4.4, 5.5 };
767         p.set("key", r);
768         QCOMPARE(p.get("key"), s);
769         p.set("key", s);
770         r = p.get_rect("key");
771         QCOMPARE(r.x, 1.1);
772         QCOMPARE(r.y, 2.2);
773         QCOMPARE(r.w, 3.3);
774         QCOMPARE(r.h, 4.4);
775         QCOMPARE(r.o, 5.5);
776     }
777
778     void RectAnimation()
779     {
780         int len = 50;
781         mlt_rect r1 = { 0, 0, 200, 200, 0 };
782         mlt_rect r2 = { 100, 100, 400, 400, 1.0 };
783         Properties p;
784         p.set_lcnumeric("POSIX");
785
786         // Construct animation from scratch
787         p.anim_set("key", r1,  0, len);
788         p.anim_set("key", r2, 50, len);
789         QCOMPARE(p.anim_get_rect("key",  0, len).x, 0.0);
790         QCOMPARE(p.anim_get_rect("key", 25, len).x, 50.0);
791         QCOMPARE(p.anim_get_rect("key", 25, len).y, 50.0);
792         QCOMPARE(p.anim_get_rect("key", 25, len).w, 300.0);
793         QCOMPARE(p.anim_get_rect("key", 25, len).h, 300.0);
794         QCOMPARE(p.anim_get_rect("key", 25, len).o, 0.5);
795         QCOMPARE(p.anim_get_rect("key", 50, len).x, 100.0);
796         QCOMPARE(p.get("key"), "0=0 0 200 200 0;50=100 100 400 400 1");
797
798         // Animation from string value
799         QCOMPARE(p.anim_get_rect("key",  0, len).x, 0.0);
800         QCOMPARE(p.anim_get_rect("key",  0, len).y, 0.0);
801         QCOMPARE(p.anim_get_rect("key",  0, len).w, 200.0);
802         QCOMPARE(p.anim_get_rect("key",  0, len).h, 200.0);
803         QCOMPARE(p.anim_get_rect("key",  0, len).o, 0.0);
804         QCOMPARE(p.anim_get_rect("key", 50, len).x, 100.0);
805         QCOMPARE(p.anim_get_rect("key", 50, len).y, 100.0);
806         QCOMPARE(p.anim_get_rect("key", 50, len).w, 400.0);
807         QCOMPARE(p.anim_get_rect("key", 50, len).h, 400.0);
808         QCOMPARE(p.anim_get_rect("key", 50, len).o, 1.0);
809         QCOMPARE(p.anim_get_rect("key", 15, len).x, 30.0);
810         QCOMPARE(p.anim_get_rect("key", 15, len).y, 30.0);
811         QCOMPARE(p.anim_get_rect("key", 15, len).w, 260.0);
812         QCOMPARE(p.anim_get_rect("key", 15, len).h, 260.0);
813         QCOMPARE(p.anim_get_rect("key", 15, len).o, 0.3);
814
815         // Smooth animation
816         p.set("key", "0~=0/0:200x200:0; 50=100/100:400x400:1");
817         QCOMPARE(p.anim_get_rect("key",  0, len).x, 0.0);
818         QCOMPARE(p.anim_get_rect("key",  0, len).y, 0.0);
819         QCOMPARE(p.anim_get_rect("key",  0, len).w, 200.0);
820         QCOMPARE(p.anim_get_rect("key",  0, len).h, 200.0);
821         QCOMPARE(p.anim_get_rect("key",  0, len).o, 0.0);
822         QCOMPARE(p.anim_get_rect("key", 50, len).x, 100.0);
823         QCOMPARE(p.anim_get_rect("key", 50, len).y, 100.0);
824         QCOMPARE(p.anim_get_rect("key", 50, len).w, 400.0);
825         QCOMPARE(p.anim_get_rect("key", 50, len).h, 400.0);
826         QCOMPARE(p.anim_get_rect("key", 50, len).o, 1.0);
827         QCOMPARE(p.anim_get_rect("key", 15, len).x, 25.8);
828         QCOMPARE(p.anim_get_rect("key", 15, len).y, 25.8);
829         QCOMPARE(p.anim_get_rect("key", 15, len).w, 251.6);
830         QCOMPARE(p.anim_get_rect("key", 15, len).h, 251.6);
831         QCOMPARE(p.anim_get_rect("key", 15, len).o, 0.258);
832
833         // Using percentages
834         p.set("key", "0=0 0; 50=100% 200%");
835         QCOMPARE(p.anim_get_rect("key", 25, len).x, 0.5);
836         QCOMPARE(p.anim_get_rect("key", 25, len).y, 1.0);
837     }
838
839     void ColorFromInt()
840     {
841         Properties p;
842         p.set_lcnumeric("POSIX");
843         p.set("key", (int) 0xaabbccdd);
844         mlt_color color = p.get_color("key");
845         QCOMPARE(color.r, quint8(0xaa));
846         QCOMPARE(color.g, quint8(0xbb));
847         QCOMPARE(color.b, quint8(0xcc));
848         QCOMPARE(color.a, quint8(0xdd));
849         p.set("key", *((int*) &color));
850         QCOMPARE(p.get_int("key"), int(0xddccbbaa));
851     }
852
853     void ColorFromString()
854     {
855         Properties p;
856         p.set_lcnumeric("POSIX");
857         p.set("key", "red");
858         mlt_color color = p.get_color("key");
859         QCOMPARE(color.r, quint8(0xff));
860         QCOMPARE(color.g, quint8(0x00));
861         QCOMPARE(color.b, quint8(0x00));
862         QCOMPARE(color.a, quint8(0xff));
863         p.set("key", "#deadd00d");
864         color = p.get_color("key");
865         QCOMPARE(color.r, quint8(0xad));
866         QCOMPARE(color.g, quint8(0xd0));
867         QCOMPARE(color.b, quint8(0x0d));
868         QCOMPARE(color.a, quint8(0xde));
869     }
870 };
871
872 QTEST_APPLESS_MAIN(TestProperties)
873
874 #include "test_properties.moc"