Added gst-plugins-base-subtitles0.10-0.10.34 for Meego Harmattan 1.2
[mafwsubrenderer] / gst-plugins-base-subtitles0.10 / tests / check / libs / tag.c
1 /* GStreamer
2  *
3  * unit tests for the tag support library
4  *
5  * Copyright (C) 2006-2009 Tim-Philipp Müller <tim centricular net>
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public
18  * License along with this library; if not, write to the
19  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20  * Boston, MA 02111-1307, USA.
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include <gst/check/gstcheck.h>
28
29 #include <gst/tag/tag.h>
30 #include <gst/base/gstbytewriter.h>
31 #include <string.h>
32
33 GST_START_TEST (test_parse_extended_comment)
34 {
35   gchar *key, *val, *lang;
36
37   /* first check the g_return_val_if_fail conditions */
38   ASSERT_CRITICAL (gst_tag_parse_extended_comment (NULL, NULL, NULL, NULL,
39           FALSE));
40   ASSERT_CRITICAL (gst_tag_parse_extended_comment ("\377\000", NULL, NULL, NULL,
41           FALSE));
42
43   key = val = lang = NULL;
44   fail_unless (gst_tag_parse_extended_comment ("a=b", &key, &lang, &val,
45           FALSE) == TRUE);
46   fail_unless (key != NULL);
47   fail_unless (lang == NULL);
48   fail_unless (val != NULL);
49   fail_unless_equals_string (key, "a");
50   fail_unless_equals_string (val, "b");
51   g_free (key);
52   g_free (lang);
53   g_free (val);
54
55   key = val = lang = NULL;
56   fail_unless (gst_tag_parse_extended_comment ("a[l]=b", &key, &lang, &val,
57           FALSE) == TRUE);
58   fail_unless (key != NULL);
59   fail_unless (lang != NULL);
60   fail_unless (val != NULL);
61   fail_unless_equals_string (key, "a");
62   fail_unless_equals_string (lang, "l");
63   fail_unless_equals_string (val, "b");
64   g_free (key);
65   g_free (lang);
66   g_free (val);
67
68   key = val = lang = NULL;
69   fail_unless (gst_tag_parse_extended_comment ("foo=bar", &key, &lang, &val,
70           FALSE) == TRUE);
71   fail_unless (key != NULL);
72   fail_unless (lang == NULL);
73   fail_unless (val != NULL);
74   fail_unless_equals_string (key, "foo");
75   fail_unless_equals_string (val, "bar");
76   g_free (key);
77   g_free (lang);
78   g_free (val);
79
80   key = val = lang = NULL;
81   fail_unless (gst_tag_parse_extended_comment ("foo[fr]=bar", &key, &lang, &val,
82           FALSE) == TRUE);
83   fail_unless (key != NULL);
84   fail_unless (lang != NULL);
85   fail_unless (val != NULL);
86   fail_unless_equals_string (key, "foo");
87   fail_unless_equals_string (lang, "fr");
88   fail_unless_equals_string (val, "bar");
89   g_free (key);
90   g_free (lang);
91   g_free (val);
92
93   key = val = lang = NULL;
94   fail_unless (gst_tag_parse_extended_comment ("foo=[fr]bar", &key, &lang, &val,
95           FALSE) == TRUE);
96   fail_unless (key != NULL);
97   fail_unless (lang == NULL);
98   fail_unless (val != NULL);
99   fail_unless_equals_string (key, "foo");
100   fail_unless_equals_string (val, "[fr]bar");
101   g_free (key);
102   g_free (lang);
103   g_free (val);
104
105   /* test NULL for output locations */
106   fail_unless (gst_tag_parse_extended_comment ("foo[fr]=bar", NULL, NULL, NULL,
107           FALSE) == TRUE);
108
109   /* test strict mode (key must be specified) */
110   fail_unless (gst_tag_parse_extended_comment ("foo[fr]=bar", NULL, NULL, NULL,
111           TRUE) == TRUE);
112   fail_unless (gst_tag_parse_extended_comment ("foo=bar", NULL, NULL, NULL,
113           TRUE) == TRUE);
114   fail_unless (gst_tag_parse_extended_comment ("foobar", NULL, NULL, NULL,
115           TRUE) == FALSE);
116
117   /* test non-strict mode (if there's no key, that's fine too) */
118   fail_unless (gst_tag_parse_extended_comment ("foobar", NULL, NULL, NULL,
119           FALSE) == TRUE);
120   fail_unless (gst_tag_parse_extended_comment ("[fr]bar", NULL, NULL, NULL,
121           FALSE) == TRUE);
122
123   key = val = lang = NULL;
124   fail_unless (gst_tag_parse_extended_comment ("[fr]bar", &key, &lang, &val,
125           FALSE) == TRUE);
126   fail_unless (key == NULL);
127   fail_unless (lang == NULL);
128   fail_unless (val != NULL);
129   fail_unless_equals_string (val, "[fr]bar");
130   g_free (key);
131   g_free (lang);
132   g_free (val);
133 }
134
135 GST_END_TEST;
136
137 #define ASSERT_TAG_LIST_HAS_STRING(list,field,string)                      \
138   {                                                                        \
139     gboolean got_match = FALSE;                                            \
140     guint i, size;                                                         \
141                                                                            \
142     fail_unless (gst_tag_list_get_tag_size (list,field) > 0);              \
143     size = gst_tag_list_get_tag_size (list,field);                         \
144     for (i = 0; i < size; ++i) {                                           \
145       gchar *___s = NULL;                                                  \
146                                                                            \
147       fail_unless (gst_tag_list_get_string_index (list, field, i, &___s)); \
148       fail_unless (___s != NULL);                                          \
149       if (g_str_equal (___s, string)) {                                    \
150         got_match = TRUE;                                                  \
151         g_free (___s);                                                     \
152         break;                                                             \
153       }                                                                    \
154       g_free (___s);                                                       \
155     }                                                                      \
156     fail_unless (got_match);                                               \
157   }
158
159 #define ASSERT_TAG_LIST_HAS_UINT(list,field,num)                           \
160   {                                                                        \
161     guint ___n;                                                            \
162                                                                            \
163     fail_unless (gst_tag_list_get_tag_size (list,field) > 0);              \
164     fail_unless (gst_tag_list_get_tag_size (list,field) == 1);             \
165     fail_unless (gst_tag_list_get_uint_index (list, field, 0, &___n));     \
166     fail_unless_equals_int (___n, num);                                    \
167   }
168
169 #define MATCH_DOUBLE(p1, p2) ((p1 < p2 + 1e-6) && (p2 < p1 + 1e-6))
170 #define ASSERT_TAG_LIST_HAS_DOUBLE(list,field,d)                           \
171   {                                                                        \
172     gdouble ___d;                                                          \
173                                                                            \
174     fail_unless (gst_tag_list_get_tag_size (list,field) > 0);              \
175     fail_unless (gst_tag_list_get_tag_size (list,field) == 1);             \
176     fail_unless (gst_tag_list_get_double_index (list, field, 0, &___d));   \
177     fail_unless (MATCH_DOUBLE (d, ___d),                                   \
178         "%f does not match expected %f", ___d, d);                         \
179   }
180
181 GST_START_TEST (test_musicbrainz_tag_registration)
182 {
183   GstTagList *list;
184
185   gst_tag_register_musicbrainz_tags ();
186
187   list = gst_tag_list_new ();
188
189   /* musicbrainz tags aren't registered yet */
190   gst_vorbis_tag_add (list, "MUSICBRAINZ_TRACKID", "123456");
191   gst_vorbis_tag_add (list, "MUSICBRAINZ_ARTISTID", "234567");
192   gst_vorbis_tag_add (list, "MUSICBRAINZ_ALBUMID", "345678");
193   gst_vorbis_tag_add (list, "MUSICBRAINZ_ALBUMARTISTID", "4567890");
194   gst_vorbis_tag_add (list, "MUSICBRAINZ_TRMID", "5678901");
195   /* MUSICBRAINZ_SORTNAME = GST_TAG_ARTIST_SORTNAME now */
196   gst_vorbis_tag_add (list, "MUSICBRAINZ_SORTNAME", "Five, 678901");
197
198   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_TRACKID, "123456");
199   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_ARTISTID, "234567");
200   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_ALBUMID, "345678");
201   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_ALBUMARTISTID,
202       "4567890");
203   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_MUSICBRAINZ_TRMID, "5678901");
204   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST_SORTNAME, "Five, 678901");
205
206   gst_tag_list_free (list);
207 }
208
209 GST_END_TEST;
210
211 /* is there an easier way to compare two structures / tagslists? */
212 static gboolean
213 taglists_are_equal (const GstTagList * list_1, const GstTagList * list_2)
214 {
215   GstCaps *c_list_1 = gst_caps_new_empty ();
216   GstCaps *c_list_2 = gst_caps_new_empty ();
217   gboolean ret;
218
219   gst_caps_append_structure (c_list_1,
220       gst_structure_copy ((GstStructure *) list_1));
221   gst_caps_append_structure (c_list_2,
222       gst_structure_copy ((GstStructure *) list_2));
223
224   ret = gst_caps_is_equal (c_list_2, c_list_1);
225
226   gst_caps_unref (c_list_1);
227   gst_caps_unref (c_list_2);
228
229   return ret;
230 }
231
232 GST_START_TEST (test_vorbis_tags)
233 {
234   GstTagList *list;
235
236   list = gst_tag_list_new ();
237
238   /* NULL pointers aren't allowed */
239   ASSERT_CRITICAL (gst_vorbis_tag_add (NULL, "key", "value"));
240   ASSERT_CRITICAL (gst_vorbis_tag_add (list, NULL, "value"));
241   ASSERT_CRITICAL (gst_vorbis_tag_add (list, "key", NULL));
242
243   /* must be UTF-8 */
244   ASSERT_CRITICAL (gst_vorbis_tag_add (list, "key", "v\377lue"));
245   ASSERT_CRITICAL (gst_vorbis_tag_add (list, "k\377y", "value"));
246
247   /* key can't have a '=' in it */
248   ASSERT_CRITICAL (gst_vorbis_tag_add (list, "k=y", "value"));
249   ASSERT_CRITICAL (gst_vorbis_tag_add (list, "key=", "value"));
250
251   /* should be allowed in values though */
252   gst_vorbis_tag_add (list, "keeey", "va=ue");
253
254   /* add some tags */
255   gst_vorbis_tag_add (list, "TITLE", "Too");
256   gst_vorbis_tag_add (list, "ALBUM", "Aoo");
257   gst_vorbis_tag_add (list, "ARTIST", "Alboo");
258   gst_vorbis_tag_add (list, "PERFORMER", "Perfoo");
259   gst_vorbis_tag_add (list, "COPYRIGHT", "Copyfoo");
260   gst_vorbis_tag_add (list, "DESCRIPTION", "Descoo");
261   gst_vorbis_tag_add (list, "LICENSE", "Licoo");
262   gst_vorbis_tag_add (list, "LICENSE",
263       "http://creativecommons.org/licenses/by/3.0/");
264   gst_vorbis_tag_add (list, "LOCATION", "Bristol, UK");
265   gst_vorbis_tag_add (list, "ORGANIZATION", "Orgoo");
266   gst_vorbis_tag_add (list, "GENRE", "Goo");
267   gst_vorbis_tag_add (list, "CONTACT", "Coo");
268   gst_vorbis_tag_add (list, "COMMENT", "Stroodle is good");
269   gst_vorbis_tag_add (list, "COMMENT", "Peroxysulfid stroodles the brain");
270
271   gst_vorbis_tag_add (list, "TRACKNUMBER", "5");
272   gst_vorbis_tag_add (list, "TRACKTOTAL", "77");
273   gst_vorbis_tag_add (list, "DISCNUMBER", "1");
274   gst_vorbis_tag_add (list, "DISCTOTAL", "2");
275   gst_vorbis_tag_add (list, "DATE", "1954-12-31");
276
277   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_TITLE, "Too");
278   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ALBUM, "Aoo");
279   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST, "Alboo");
280   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_PERFORMER, "Perfoo");
281   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_COPYRIGHT, "Copyfoo");
282   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_DESCRIPTION, "Descoo");
283   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LICENSE, "Licoo");
284   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LICENSE_URI,
285       "http://creativecommons.org/licenses/by/3.0/");
286   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_GEO_LOCATION_NAME, "Bristol, UK");
287   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ORGANIZATION, "Orgoo");
288   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_GENRE, "Goo");
289   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_CONTACT, "Coo");
290   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_COMMENT,
291       "Peroxysulfid stroodles the brain");
292   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_COMMENT, "Stroodle is good");
293   ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_TRACK_NUMBER, 5);
294   ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_TRACK_COUNT, 77);
295   ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_ALBUM_VOLUME_NUMBER, 1);
296   ASSERT_TAG_LIST_HAS_UINT (list, GST_TAG_ALBUM_VOLUME_COUNT, 2);
297
298   {
299     GDate *date = NULL;
300
301     fail_unless (gst_tag_list_get_date (list, GST_TAG_DATE, &date));
302     fail_unless (date != NULL);
303     fail_unless (g_date_get_day (date) == 31);
304     fail_unless (g_date_get_month (date) == G_DATE_DECEMBER);
305     fail_unless (g_date_get_year (date) == 1954);
306
307     g_date_free (date);
308   }
309
310   /* unknown vorbis comments should go into a GST_TAG_EXTENDED_COMMENT */
311   gst_vorbis_tag_add (list, "CoEdSub_ID", "98172AF-973-10-B");
312   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_EXTENDED_COMMENT,
313       "CoEdSub_ID=98172AF-973-10-B");
314   gst_vorbis_tag_add (list, "RuBuWuHash", "1337BA42F91");
315   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_EXTENDED_COMMENT,
316       "RuBuWuHash=1337BA42F91");
317
318   gst_vorbis_tag_add (list, "REPLAYGAIN_REFERENCE_LOUDNESS", "89.");
319   ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_REFERENCE_LEVEL, 89.);
320   gst_vorbis_tag_add (list, "REPLAYGAIN_TRACK_GAIN", "+12.36");
321   ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_TRACK_GAIN, +12.36);
322   gst_vorbis_tag_add (list, "REPLAYGAIN_TRACK_PEAK", "0.96349");
323   ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_TRACK_PEAK, 0.96349);
324   gst_vorbis_tag_add (list, "REPLAYGAIN_ALBUM_GAIN", "+10.12");
325   ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_ALBUM_GAIN, +10.12);
326   /* now check that we can parse floating point numbers with any separator
327    * (',' or '.') regardless of the current locale */
328   gst_vorbis_tag_add (list, "REPLAYGAIN_ALBUM_PEAK", "0,98107");
329   ASSERT_TAG_LIST_HAS_DOUBLE (list, GST_TAG_ALBUM_PEAK, 0.98107);
330   gst_vorbis_tag_add (list, "LICENSE", "http://foo.com/license-1.html");
331
332   /* make sure we can convert back and forth without loss */
333   {
334     GstTagList *new_list, *even_newer_list;
335     GstBuffer *buf, *buf2;
336     gchar *vendor_id = NULL;
337
338     buf = gst_tag_list_to_vorbiscomment_buffer (list,
339         (const guint8 *) "\003vorbis", 7, "libgstunittest");
340     fail_unless (buf != NULL);
341     new_list = gst_tag_list_from_vorbiscomment_buffer (buf,
342         (const guint8 *) "\003vorbis", 7, &vendor_id);
343     fail_unless (new_list != NULL);
344     fail_unless (vendor_id != NULL);
345     g_free (vendor_id);
346     vendor_id = NULL;
347
348     GST_LOG ("new_list = %" GST_PTR_FORMAT, new_list);
349     fail_unless (taglists_are_equal (list, new_list));
350
351     buf2 = gst_tag_list_to_vorbiscomment_buffer (new_list,
352         (const guint8 *) "\003vorbis", 7, "libgstunittest");
353     fail_unless (buf2 != NULL);
354     even_newer_list = gst_tag_list_from_vorbiscomment_buffer (buf2,
355         (const guint8 *) "\003vorbis", 7, &vendor_id);
356     fail_unless (even_newer_list != NULL);
357     fail_unless (vendor_id != NULL);
358     g_free (vendor_id);
359     vendor_id = NULL;
360
361     GST_LOG ("even_newer_list = %" GST_PTR_FORMAT, even_newer_list);
362     fail_unless (taglists_are_equal (new_list, even_newer_list));
363
364     gst_tag_list_free (new_list);
365     gst_tag_list_free (even_newer_list);
366     gst_buffer_unref (buf);
367     gst_buffer_unref (buf2);
368   }
369
370   /* there can only be one language per taglist ... */
371   gst_tag_list_free (list);
372   list = gst_tag_list_new ();
373   gst_vorbis_tag_add (list, "LANGUAGE", "fr");
374   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "fr");
375
376   gst_tag_list_free (list);
377   list = gst_tag_list_new ();
378   gst_vorbis_tag_add (list, "LANGUAGE", "[fr]");
379   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "fr");
380
381   gst_tag_list_free (list);
382   list = gst_tag_list_new ();
383   gst_vorbis_tag_add (list, "LANGUAGE", "French [fr]");
384   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "fr");
385
386   gst_tag_list_free (list);
387   list = gst_tag_list_new ();
388   gst_vorbis_tag_add (list, "LANGUAGE", "[eng] English");
389   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "eng");
390
391   gst_tag_list_free (list);
392   list = gst_tag_list_new ();
393   gst_vorbis_tag_add (list, "LANGUAGE", "eng");
394   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "eng");
395
396   gst_tag_list_free (list);
397   list = gst_tag_list_new ();
398   gst_vorbis_tag_add (list, "LANGUAGE", "[eng]");
399   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "eng");
400
401   /* free-form *sigh* */
402   gst_tag_list_free (list);
403   list = gst_tag_list_new ();
404   gst_vorbis_tag_add (list, "LANGUAGE", "English");
405   ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_LANGUAGE_CODE, "English");
406
407   /* now, while we still have a taglist, test _to_vorbiscomment_buffer() */
408   {
409     GstBuffer *buf1, *buf2;
410
411     ASSERT_CRITICAL (gst_tag_list_to_vorbiscomment_buffer (NULL,
412             (const guint8 *) "x", 1, "x"));
413
414     buf1 = gst_tag_list_to_vorbiscomment_buffer (list, NULL, 0, NULL);
415     fail_unless (buf1 != NULL);
416
417     buf2 = gst_tag_list_to_vorbiscomment_buffer (list,
418         (const guint8 *) "foo", 3, NULL);
419     fail_unless (buf2 != NULL);
420
421     fail_unless (memcmp (GST_BUFFER_DATA (buf1), GST_BUFFER_DATA (buf2) + 3,
422             GST_BUFFER_SIZE (buf1)) == 0);
423
424     gst_buffer_unref (buf1);
425     gst_buffer_unref (buf2);
426   }
427
428   gst_tag_list_free (list);
429
430   /* make sure gst_tag_list_from_vorbiscomment_buffer() works with an
431    * empty ID (for Speex) */
432   {
433     const guint8 speex_comments_buf1[] = { 0x03, 0x00, 0x00, 0x00, 'f', 'o',
434       'o', 0x00, 0x00, 0x00, 0x00
435     };
436     GstBuffer *buf;
437     gchar *vendor = NULL;
438
439     buf = gst_buffer_new ();
440     GST_BUFFER_DATA (buf) = (guint8 *) speex_comments_buf1;
441     GST_BUFFER_SIZE (buf) = sizeof (speex_comments_buf1);
442
443     /* make sure it doesn't memcmp over the end of the buffer */
444     fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf,
445             (const guint8 *) "averylongstringbrownfoxjumpoverthefence", 39,
446             &vendor) == NULL);
447     fail_unless (vendor == NULL);
448
449     /* make sure it bails out if the ID doesn't match */
450     fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf,
451             (guint8 *) "short", 4, &vendor) == NULL);
452     fail_unless (vendor == NULL);
453
454     /* now read properly */
455     list = gst_tag_list_from_vorbiscomment_buffer (buf, NULL, 0, &vendor);
456     fail_unless (vendor != NULL);
457     fail_unless_equals_string (vendor, "foo");
458     fail_unless (list != NULL);
459     fail_unless (gst_structure_n_fields ((GstStructure *) list) == 0);
460     g_free (vendor);
461     gst_tag_list_free (list);
462
463     /* now again without vendor */
464     list = gst_tag_list_from_vorbiscomment_buffer (buf, NULL, 0, NULL);
465     fail_unless (list != NULL);
466     fail_unless (gst_structure_n_fields ((GstStructure *) list) == 0);
467     gst_tag_list_free (list);
468
469     gst_buffer_unref (buf);
470   }
471
472   /* the same with an ID */
473   {
474     const guint8 vorbis_comments_buf[] = { 0x03, 'v', 'o', 'r', 'b', 'i', 's',
475       0x03, 0x00, 0x00, 0x00, 'f', 'o', 'o', 0x01, 0x00, 0x00, 0x00,
476       strlen ("ARTIST=foo bar"), 0x00, 0x00, 0x00, 'A', 'R', 'T', 'I', 'S',
477       'T', '=', 'f', 'o', 'o', ' ', 'b', 'a', 'r'
478     };
479     GstBuffer *buf;
480     gchar *vendor = NULL;
481
482     buf = gst_buffer_new ();
483     GST_BUFFER_DATA (buf) = (guint8 *) vorbis_comments_buf;
484     GST_BUFFER_SIZE (buf) = sizeof (vorbis_comments_buf);
485
486     /* make sure it doesn't memcmp over the end of the buffer */
487     fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf,
488             (const guint8 *) "averylongstringbrownfoxjumpoverthefence", 39,
489             &vendor) == NULL);
490     fail_unless (vendor == NULL);
491
492     /* make sure it bails out if the ID doesn't match */
493     fail_unless (gst_tag_list_from_vorbiscomment_buffer (buf,
494             (guint8 *) "short", 4, &vendor) == NULL);
495     fail_unless (vendor == NULL);
496
497     /* now read properly */
498     list = gst_tag_list_from_vorbiscomment_buffer (buf,
499         (guint8 *) "\003vorbis", 7, &vendor);
500     fail_unless (vendor != NULL);
501     fail_unless_equals_string (vendor, "foo");
502     fail_unless (list != NULL);
503     fail_unless (gst_structure_n_fields ((GstStructure *) list) == 1);
504     ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST, "foo bar");
505     g_free (vendor);
506     gst_tag_list_free (list);
507
508     /* now again without vendor */
509     list = gst_tag_list_from_vorbiscomment_buffer (buf,
510         (guint8 *) "\003vorbis", 7, NULL);
511     fail_unless (list != NULL);
512     fail_unless (gst_structure_n_fields ((GstStructure *) list) == 1);
513     ASSERT_TAG_LIST_HAS_STRING (list, GST_TAG_ARTIST, "foo bar");
514     gst_tag_list_free (list);
515
516     gst_buffer_unref (buf);
517   }
518
519   /* check date with time */
520   {
521     GDate *date = NULL;
522
523     list = gst_tag_list_new ();
524     gst_vorbis_tag_add (list, "DATE", "2006-09-25 22:02:38");
525
526     fail_unless (gst_tag_list_get_date_index (list, GST_TAG_DATE, 0, &date));
527     fail_unless (date != NULL);
528     fail_unless (g_date_get_day (date) == 25);
529     fail_unless (g_date_get_month (date) == G_DATE_SEPTEMBER);
530     fail_unless (g_date_get_year (date) == 2006);
531
532     g_date_free (date);
533     gst_tag_list_free (list);
534   }
535
536   /* check date with month/day of 00-00 */
537   {
538     GDate *date = NULL;
539
540     list = gst_tag_list_new ();
541     gst_vorbis_tag_add (list, "DATE", "1992-00-00");
542
543     fail_unless (gst_tag_list_get_date_index (list, GST_TAG_DATE, 0, &date));
544     fail_unless (date != NULL);
545     fail_unless (g_date_get_year (date) == 1992);
546
547     g_date_free (date);
548     gst_tag_list_free (list);
549   }
550
551   /* check date with valid month, but day of 00 */
552   {
553     GDate *date = NULL;
554
555     list = gst_tag_list_new ();
556     gst_vorbis_tag_add (list, "DATE", "1992-05-00");
557
558     fail_unless (gst_tag_list_get_date_index (list, GST_TAG_DATE, 0, &date));
559     fail_unless (date != NULL);
560     fail_unless (g_date_get_year (date) == 1992);
561     fail_unless (g_date_get_month (date) == G_DATE_MAY);
562
563     g_date_free (date);
564     gst_tag_list_free (list);
565   }
566 }
567
568 GST_END_TEST;
569
570 GST_START_TEST (test_id3_tags)
571 {
572   guint i;
573
574   fail_unless (gst_tag_id3_genre_count () > 0);
575
576   for (i = 0; i < gst_tag_id3_genre_count (); ++i) {
577     const gchar *genre;
578
579     genre = gst_tag_id3_genre_get (i);
580     fail_unless (genre != NULL);
581   }
582
583   {
584     /* TODO: GstTagList *gst_tag_list_new_from_id3v1 (const guint8 *data) */
585   }
586
587   /* gst_tag_from_id3_tag */
588   fail_unless (gst_tag_from_id3_tag ("TALB") != NULL);
589   ASSERT_CRITICAL (gst_tag_from_id3_tag (NULL));
590   fail_unless (gst_tag_from_id3_tag ("R2D2") == NULL);
591   fail_unless_equals_string (gst_tag_from_id3_tag ("WCOP"),
592       GST_TAG_COPYRIGHT_URI);
593
594   /* gst_tag_from_id3_user_tag */
595   ASSERT_CRITICAL (gst_tag_from_id3_user_tag (NULL, "foo"));
596   ASSERT_CRITICAL (gst_tag_from_id3_user_tag ("foo", NULL));
597   fail_unless (gst_tag_from_id3_user_tag ("R2D2", "R2D2") == NULL);
598
599   /* gst_tag_to_id3_tag */
600   ASSERT_CRITICAL (gst_tag_to_id3_tag (NULL));
601   fail_unless (gst_tag_to_id3_tag ("R2D2") == NULL);
602   fail_unless (gst_tag_to_id3_tag (GST_TAG_ARTIST) != NULL);
603   fail_unless_equals_string (gst_tag_to_id3_tag (GST_TAG_COPYRIGHT_URI),
604       "WCOP");
605
606   fail_unless (GST_TYPE_TAG_IMAGE_TYPE != 0);
607   fail_unless (g_type_name (GST_TYPE_TAG_IMAGE_TYPE) != NULL);
608 }
609
610 GST_END_TEST;
611
612
613 GST_START_TEST (test_id3v1_utf8_tag)
614 {
615   const guint8 id3v1[128] = {
616     /* marker */
617     'T', 'A', 'G',
618     /* title (30 bytes) */
619     'D', 0xc3, 0xad, 'v', 'k', 'a', ' ', 's',
620     ' ', 'p', 'e', 'r', 'l', 'a', 'm', 'i',
621     ' ', 'v', 'e', ' ', 'v', 'l', 'a', 's',
622     'e', 'c', 'h', 0, 0, 0,
623     /* artist (30 bytes) */
624     'A', 'l', 'e', 0xc5, 0xa1, ' ', 'B', 'r', 'i', 'c', 'h', 't', 'a',
625     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
626     /* album (30 bytes) */
627     'B', 'e', 's', 't', ' ', 'o', 'f', ' ', '(', 'P', 'r', 'o', 's', 't',
628     0xc4, 0x9b, ' ', 0xc3, 0xba, 0xc5, 0xbe, 'a', 's', 'n', 0xc3, 0xbd, ')',
629     0, 0, 0,
630     /* year (4 bytes) */
631     '2', '0', '0', '0',
632     /* comment (28 bytes) */
633     '-', '-', '-', ' ', 0xc4, 0x8d, 'e', 's', 'k', 0xc3, 0xa9, ' ', 'p',
634     0xc3, 0xad, 's', 'n', 'i', 0xc4, 0x8d, 'k', 'y', ' ', '-', '-', '-',
635     0, 0,
636     /* track number */
637     0, 0,
638     /* genre */
639     0x11
640   };
641   GstTagList *tags;
642   GDate *d;
643   gchar *s;
644
645   /* set this, to make sure UTF-8 strings are really interpreted properly
646    * as UTF-8, regardless of the locale set */
647   g_setenv ("GST_ID3V1_TAG_ENCODING", "WINDOWS-1250", TRUE);
648
649   tags = gst_tag_list_new_from_id3v1 (id3v1);
650   fail_unless (tags != NULL);
651
652   GST_LOG ("Got tags: %" GST_PTR_FORMAT, tags);
653
654   s = NULL;
655   fail_unless (gst_tag_list_get_string (tags, GST_TAG_TITLE, &s));
656   fail_unless (s != NULL);
657   fail_unless_equals_string (s, "Dívka s perlami ve vlasech");
658   g_free (s);
659
660   s = NULL;
661   fail_unless (gst_tag_list_get_string (tags, GST_TAG_ARTIST, &s));
662   fail_unless (s != NULL);
663   fail_unless_equals_string (s, "AleÅ¡ Brichta");
664   g_free (s);
665
666   s = NULL;
667   fail_unless (gst_tag_list_get_string (tags, GST_TAG_ALBUM, &s));
668   fail_unless (s != NULL);
669   fail_unless_equals_string (s, "Best of (ProstÄ› ÃºÅ¾asný)");
670   g_free (s);
671
672   d = NULL;
673   fail_unless (gst_tag_list_get_date (tags, GST_TAG_DATE, &d));
674   fail_unless (d != NULL);
675   fail_unless_equals_int (g_date_get_year (d), 2000);
676   g_date_free (d);
677   d = NULL;
678
679   gst_tag_list_free (tags);
680
681   g_unsetenv ("GST_ID3V1_TAG_ENCODING");
682 }
683
684 GST_END_TEST;
685
686 GST_START_TEST (test_language_utils)
687 {
688   gchar **lang_codes, **c;
689
690 #define ASSERT_STRINGS_EQUAL fail_unless_equals_string
691
692   lang_codes = gst_tag_get_language_codes ();
693   fail_unless (lang_codes != NULL);
694   fail_unless (*lang_codes != NULL);
695
696   for (c = lang_codes; c != NULL && *c != NULL; ++c) {
697     const gchar *lang_name, *c1, *c2t, *c2b;
698
699     lang_name = gst_tag_get_language_name (*c);
700     fail_unless (lang_name != NULL);
701     fail_unless (g_utf8_validate (lang_name, -1, NULL));
702
703     c1 = gst_tag_get_language_code_iso_639_1 (*c);
704     fail_unless (c1 != NULL);
705     fail_unless (g_utf8_validate (c1, -1, NULL));
706
707     c2t = gst_tag_get_language_code_iso_639_2T (*c);
708     fail_unless (c2t != NULL);
709     fail_unless (g_utf8_validate (c2t, -1, NULL));
710
711     c2b = gst_tag_get_language_code_iso_639_2B (*c);
712     fail_unless (c2b != NULL);
713     fail_unless (g_utf8_validate (c2b, -1, NULL));
714
715     ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 (*c), *c);
716     ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 (c2t), *c);
717     ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 (c2b), *c);
718
719     GST_DEBUG ("[%s] %s %s %s : %s\n", *c, c1, c2t, c2b, lang_name);
720
721   }
722   g_strfreev (lang_codes);
723
724   fail_unless (gst_tag_get_language_name ("de") != NULL);
725   fail_unless (gst_tag_get_language_name ("deu") != NULL);
726   fail_unless (gst_tag_get_language_name ("ger") != NULL);
727   fail_unless_equals_string (gst_tag_get_language_name ("deu"),
728       gst_tag_get_language_name ("ger"));
729   fail_unless_equals_string (gst_tag_get_language_name ("de"),
730       gst_tag_get_language_name ("ger"));
731   fail_unless (gst_tag_get_language_name ("de") !=
732       gst_tag_get_language_name ("fr"));
733
734   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("deu"), "de");
735   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("de"), "de");
736   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code ("ger"), "de");
737
738   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("deu"), "de");
739   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("de"), "de");
740   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_1 ("ger"), "de");
741
742   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("de"), "deu");
743   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("deu"), "deu");
744   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2T ("ger"), "deu");
745
746   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("de"), "ger");
747   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("deu"), "ger");
748   ASSERT_STRINGS_EQUAL (gst_tag_get_language_code_iso_639_2B ("ger"), "ger");
749 }
750
751 GST_END_TEST;
752
753 GST_START_TEST (test_xmp_formatting)
754 {
755   GstTagList *list;
756   GstBuffer *buf;
757   const gchar *text;
758   guint len;
759
760   /* test data */
761   list = gst_tag_list_new_full (GST_TAG_TITLE, "test title",
762       GST_TAG_DESCRIPTION, "test decription",
763       GST_TAG_KEYWORDS, "keyword1", GST_TAG_KEYWORDS, "keyword2", NULL);
764
765   buf = gst_tag_list_to_xmp_buffer (list, FALSE);
766   fail_unless (buf != NULL);
767
768   text = (const gchar *) GST_BUFFER_DATA (buf);
769   len = GST_BUFFER_SIZE (buf);
770
771   /* check the content */
772   fail_unless (g_strrstr_len (text, len, "<?xpacket begin") == text);
773   fail_unless (g_strrstr_len (text, len, ">test title<") != NULL);
774   fail_unless (g_strrstr_len (text, len, ">test decription<") != NULL);
775   fail_unless (g_strrstr_len (text, len, ">keyword1<") != NULL);
776   fail_unless (g_strrstr_len (text, len, ">keyword2<") != NULL);
777   fail_unless (g_strrstr_len (text, len, "<?xpacket end") != NULL);
778
779   gst_buffer_unref (buf);
780   gst_tag_list_free (list);
781 }
782
783 GST_END_TEST;
784
785
786 GST_START_TEST (test_xmp_parsing)
787 {
788   GstTagList *list;
789   GstBuffer *buf;
790   guint i, result_size;
791   gchar *text;
792   const gchar *xmp_header =
793       "<?xpacket begin=\"\xEF\xBB\xBF\" id=\"W5M0MpCehiHzreSzNTczkc9d\"?>"
794       "<x:xmpmeta xmlns:x=\"adobe:ns:meta/\" x:xmptk=\"GStreamer\">"
795       "<rdf:RDF xmlns:rdf=\"http://www.w3.org/1999/02/22-rdf-syntax-ns#\" xmlns:dc=\"http://purl.org/dc/elements/1.1/\">";
796   const gchar *xmp_footer =
797       "</rdf:RDF>" "</x:xmpmeta>" "<?xpacket end=\"r\"?>\n";
798   struct
799   {
800     const gchar *xmp_data;
801     gint result_size;
802     gint result_test;
803   } test_data[] = {
804     {
805     "", -1, -1}, {
806     "<rdf:Description rdf:about=\"\" />", 0, -1}, {
807     "<rdf:Description rdf:about=\"\"></rdf:Description>", 0, -1}, {
808     "<rdf:Description    rdf:about=\"\"    ></rdf:Description>", 0, -1}, {
809     "<rdf:Description rdf:about=\"\"><dc:description>test</dc:description></rdf:Description>",
810           1, 0}, {
811     "<rdf:Description rdf:about=\"\" dc:description=\"test\"></rdf:Description>",
812           1, 0}, {
813     NULL, -1, -1}
814   };
815
816   /* test data */
817   buf = gst_buffer_new ();
818
819   i = 0;
820   while (test_data[i].xmp_data) {
821     GST_DEBUG ("trying test-data %u", i);
822
823     text = g_strconcat (xmp_header, test_data[i].xmp_data, xmp_footer, NULL);
824     GST_BUFFER_DATA (buf) = (guint8 *) text;
825     GST_BUFFER_SIZE (buf) = strlen (text) + 1;
826
827
828     list = gst_tag_list_from_xmp_buffer (buf);
829     if (test_data[i].result_size >= 0) {
830       fail_unless (list != NULL);
831
832       result_size = gst_structure_n_fields ((GstStructure *) list);
833       fail_unless (result_size == test_data[i].result_size);
834
835       /* check the taglist content */
836       switch (test_data[i].result_test) {
837         case 0:
838           ASSERT_TAG_LIST_HAS_STRING (list, "description", "test");
839           break;
840         default:
841           break;
842       }
843     }
844     if (list)
845       gst_tag_list_free (list);
846
847     g_free (text);
848     i++;
849   }
850
851   gst_buffer_unref (buf);
852 }
853
854 GST_END_TEST;
855
856 static void
857 tag_list_equals (GstTagList * taglist, GstTagList * taglist2)
858 {
859   const gchar *name_sent, *name_recv;
860   const GValue *value_sent, *value_recv;
861   gboolean found;
862   gint comparison;
863   gint n_recv;
864   gint n_sent;
865   gint i, j;
866
867   /* verify tags */
868   fail_unless (taglist2 != NULL);
869   n_recv = gst_structure_n_fields (taglist2);
870   n_sent = gst_structure_n_fields (taglist);
871   fail_unless (n_recv == n_sent);
872   fail_unless (n_sent > 0);
873
874   /* FIXME: compare taglist values */
875   for (i = 0; i < n_sent; i++) {
876     name_sent = gst_structure_nth_field_name (taglist, i);
877     value_sent = gst_structure_get_value (taglist, name_sent);
878     found = FALSE;
879     for (j = 0; j < n_recv; j++) {
880       name_recv = gst_structure_nth_field_name (taglist2, j);
881       if (!strcmp (name_sent, name_recv)) {
882         value_recv = gst_structure_get_value (taglist2, name_recv);
883         comparison = gst_value_compare (value_sent, value_recv);
884         if (comparison != GST_VALUE_EQUAL) {
885           gchar *vs = g_strdup_value_contents (value_sent);
886           gchar *vr = g_strdup_value_contents (value_recv);
887           GST_DEBUG ("sent = %s:'%s', recv = %s:'%s'",
888               G_VALUE_TYPE_NAME (value_sent), vs,
889               G_VALUE_TYPE_NAME (value_recv), vr);
890           g_free (vs);
891           g_free (vr);
892         }
893         if (comparison != GST_VALUE_EQUAL &&
894             G_VALUE_HOLDS (value_sent, G_TYPE_DOUBLE)) {
895           gdouble vs;
896           gdouble vr;
897
898           /* add some tolerance for doubles */
899           vs = g_value_get_double (value_sent);
900           vr = g_value_get_double (value_recv);
901           if (vr >= vs - 0.001 && vr <= vs + 0.001)
902             comparison = GST_VALUE_EQUAL;
903         }
904         fail_unless (comparison == GST_VALUE_EQUAL,
905             "tag item %s has been received with different type or value",
906             name_sent);
907         found = TRUE;
908         break;
909       }
910     }
911     fail_unless (found, "tag item %s is lost", name_sent);
912   }
913 }
914
915 static void
916 do_xmp_tag_serialization_deserialization (GstTagList * taglist)
917 {
918   GstTagList *taglist2;
919   GstBuffer *buf;
920
921   buf = gst_tag_list_to_xmp_buffer (taglist, TRUE);
922   taglist2 = gst_tag_list_from_xmp_buffer (buf);
923
924   tag_list_equals (taglist, taglist2);
925
926   gst_buffer_unref (buf);
927   gst_tag_list_free (taglist2);
928 }
929
930 static void
931 do_simple_xmp_tag_serialization_deserialization (const gchar * gsttag,
932     GValue * value)
933 {
934   GstTagList *taglist = gst_tag_list_new ();
935
936   gst_tag_list_add_value (taglist, GST_TAG_MERGE_REPLACE, gsttag, value);
937
938   do_xmp_tag_serialization_deserialization (taglist);
939   gst_tag_list_free (taglist);
940 }
941
942 GST_START_TEST (test_xmp_tags_serialization_deserialization)
943 {
944   GValue value = { 0 };
945   GDate *date;
946   GstDateTime *datetime;
947
948   gst_tag_register_musicbrainz_tags ();
949
950   g_value_init (&value, G_TYPE_STRING);
951   g_value_set_static_string (&value, "my string");
952   do_simple_xmp_tag_serialization_deserialization (GST_TAG_ARTIST, &value);
953   do_simple_xmp_tag_serialization_deserialization (GST_TAG_COPYRIGHT, &value);
954   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DESCRIPTION, &value);
955   do_simple_xmp_tag_serialization_deserialization (GST_TAG_KEYWORDS, &value);
956   do_simple_xmp_tag_serialization_deserialization (GST_TAG_TITLE, &value);
957   do_simple_xmp_tag_serialization_deserialization (GST_TAG_VIDEO_CODEC, &value);
958   do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_COUNTRY,
959       &value);
960   do_simple_xmp_tag_serialization_deserialization (GST_TAG_GEO_LOCATION_CITY,
961       &value);
962   do_simple_xmp_tag_serialization_deserialization
963       (GST_TAG_GEO_LOCATION_SUBLOCATION, &value);
964   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DEVICE_MANUFACTURER,
965       &value);
966   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DEVICE_MODEL,
967       &value);
968   do_simple_xmp_tag_serialization_deserialization (GST_TAG_APPLICATION_NAME,
969       &value);
970
971   g_value_set_static_string (&value, "rotate-0");
972   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
973       &value);
974   g_value_set_static_string (&value, "flip-rotate-0");
975   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
976       &value);
977   g_value_set_static_string (&value, "rotate-180");
978   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
979       &value);
980   g_value_set_static_string (&value, "flip-rotate-180");
981   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
982       &value);
983   g_value_set_static_string (&value, "flip-rotate-270");
984   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
985       &value);
986   g_value_set_static_string (&value, "rotate-90");
987   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
988       &value);
989   g_value_set_static_string (&value, "flip-rotate-90");
990   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
991       &value);
992   g_value_set_static_string (&value, "rotate-270");
993   do_simple_xmp_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
994       &value);
995
996   g_value_unset (&value);
997   g_value_init (&value, G_TYPE_DOUBLE);
998
999   g_value_set_double (&value, 0.0);
1000   do_simple_xmp_tag_serialization_deserialization
1001       (GST_TAG_GEO_LOCATION_LATITUDE, &value);
1002   do_simple_xmp_tag_serialization_deserialization
1003       (GST_TAG_GEO_LOCATION_LONGITUDE, &value);
1004   g_value_set_double (&value, 10.5);
1005   do_simple_xmp_tag_serialization_deserialization
1006       (GST_TAG_GEO_LOCATION_LATITUDE, &value);
1007   do_simple_xmp_tag_serialization_deserialization
1008       (GST_TAG_GEO_LOCATION_LONGITUDE, &value);
1009   g_value_set_double (&value, -32.375);
1010   do_simple_xmp_tag_serialization_deserialization
1011       (GST_TAG_GEO_LOCATION_LATITUDE, &value);
1012   do_simple_xmp_tag_serialization_deserialization
1013       (GST_TAG_GEO_LOCATION_LONGITUDE, &value);
1014
1015   g_value_set_double (&value, 0);
1016   do_simple_xmp_tag_serialization_deserialization
1017       (GST_TAG_GEO_LOCATION_ELEVATION, &value);
1018   g_value_set_double (&value, 100);
1019   do_simple_xmp_tag_serialization_deserialization
1020       (GST_TAG_GEO_LOCATION_ELEVATION, &value);
1021   g_value_set_double (&value, 500.25);
1022   do_simple_xmp_tag_serialization_deserialization
1023       (GST_TAG_GEO_LOCATION_ELEVATION, &value);
1024   g_value_set_double (&value, -12.75);
1025   do_simple_xmp_tag_serialization_deserialization
1026       (GST_TAG_GEO_LOCATION_ELEVATION, &value);
1027
1028   g_value_set_double (&value, 0.0);
1029   do_simple_xmp_tag_serialization_deserialization
1030       (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value);
1031   g_value_set_double (&value, 10.0);
1032   do_simple_xmp_tag_serialization_deserialization
1033       (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value);
1034   g_value_set_double (&value, 786.125);
1035   do_simple_xmp_tag_serialization_deserialization
1036       (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value);
1037   g_value_set_double (&value, -2.5);
1038   do_simple_xmp_tag_serialization_deserialization
1039       (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value);
1040
1041   g_value_set_double (&value, 0.0);
1042   do_simple_xmp_tag_serialization_deserialization
1043       (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value);
1044   g_value_set_double (&value, 180.0);
1045   do_simple_xmp_tag_serialization_deserialization
1046       (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value);
1047   g_value_set_double (&value, 359.99);
1048   do_simple_xmp_tag_serialization_deserialization
1049       (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value);
1050
1051   g_value_set_double (&value, 0.0);
1052   do_simple_xmp_tag_serialization_deserialization
1053       (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value);
1054   g_value_set_double (&value, 90.0);
1055   do_simple_xmp_tag_serialization_deserialization
1056       (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value);
1057   g_value_set_double (&value, 359.99);
1058   do_simple_xmp_tag_serialization_deserialization
1059       (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value);
1060
1061   g_value_set_double (&value, 0.0);
1062   do_simple_xmp_tag_serialization_deserialization
1063       (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, &value);
1064   g_value_set_double (&value, 1.0);
1065   do_simple_xmp_tag_serialization_deserialization
1066       (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, &value);
1067   g_value_set_double (&value, -2.5);
1068   do_simple_xmp_tag_serialization_deserialization
1069       (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, &value);
1070   g_value_unset (&value);
1071
1072   g_value_init (&value, GST_TYPE_DATE);
1073   date = g_date_new_dmy (22, 3, 2010);
1074   gst_value_set_date (&value, date);
1075   g_date_free (date);
1076   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE, &value);
1077   g_value_unset (&value);
1078
1079   g_value_init (&value, G_TYPE_UINT);
1080   g_value_set_uint (&value, 0);
1081   do_simple_xmp_tag_serialization_deserialization (GST_TAG_USER_RATING, &value);
1082   g_value_set_uint (&value, 100);
1083   do_simple_xmp_tag_serialization_deserialization (GST_TAG_USER_RATING, &value);
1084   g_value_set_uint (&value, 22);
1085   do_simple_xmp_tag_serialization_deserialization (GST_TAG_USER_RATING, &value);
1086   g_value_unset (&value);
1087
1088   g_value_init (&value, GST_TYPE_DATE_TIME);
1089   datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10);
1090   g_value_set_boxed (&value, datetime);
1091   gst_date_time_unref (datetime);
1092   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1093   datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10.000125);
1094   g_value_set_boxed (&value, datetime);
1095   gst_date_time_unref (datetime);
1096   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1097   datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10.000001);
1098   g_value_set_boxed (&value, datetime);
1099   gst_date_time_unref (datetime);
1100   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1101   datetime = gst_date_time_new (0, 2010, 6, 22, 12, 5, 10.123456);
1102   g_value_set_boxed (&value, datetime);
1103   gst_date_time_unref (datetime);
1104   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1105   datetime = gst_date_time_new (-3, 2010, 6, 22, 12, 5, 10.123456);
1106   g_value_set_boxed (&value, datetime);
1107   gst_date_time_unref (datetime);
1108   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1109   datetime = gst_date_time_new (5, 2010, 6, 22, 12, 5, 10.123456);
1110   g_value_set_boxed (&value, datetime);
1111   gst_date_time_unref (datetime);
1112   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1113   datetime = gst_date_time_new_local_time (2010, 12, 2, 12, 5, 10.000043);
1114   g_value_set_boxed (&value, datetime);
1115   gst_date_time_unref (datetime);
1116   do_simple_xmp_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1117   g_value_unset (&value);
1118 }
1119
1120 GST_END_TEST;
1121
1122
1123 GST_START_TEST (test_xmp_compound_tags)
1124 {
1125   GstTagList *taglist = gst_tag_list_new ();
1126
1127   gst_tag_list_add (taglist, GST_TAG_MERGE_APPEND, GST_TAG_KEYWORDS, "k1",
1128       GST_TAG_KEYWORDS, "k2", GST_TAG_TITLE, "title", GST_TAG_KEYWORDS, "k3",
1129       NULL);
1130
1131   do_xmp_tag_serialization_deserialization (taglist);
1132   gst_tag_list_free (taglist);
1133 }
1134
1135 GST_END_TEST;
1136
1137
1138 GST_START_TEST (test_exif_parsing)
1139 {
1140   GstTagList *taglist;
1141   GstBuffer *buf;
1142   GstByteWriter writer;
1143   const gchar *str;
1144
1145   gst_byte_writer_init (&writer);
1146
1147   /* write the IFD */
1148   /* 1 entry */
1149   gst_byte_writer_put_uint16_le (&writer, 1);
1150
1151   /* copyright tag */
1152   /* tag id */
1153   gst_byte_writer_put_uint16_le (&writer, 0x8298);
1154   /* tag type */
1155   gst_byte_writer_put_uint16_le (&writer, 0x2);
1156   /* count */
1157   gst_byte_writer_put_uint32_le (&writer, strlen ("my copyright") + 1);
1158   /* offset */
1159   gst_byte_writer_put_uint32_le (&writer, 8 + 14);
1160
1161   /* data */
1162   gst_byte_writer_put_string (&writer, "my copyright");
1163
1164   buf = gst_byte_writer_reset_and_get_buffer (&writer);
1165
1166   taglist = gst_tag_list_from_exif_buffer (buf, G_LITTLE_ENDIAN, 8);
1167
1168   fail_unless (gst_structure_n_fields (taglist) == 1);
1169   fail_unless (gst_structure_has_field_typed (taglist, GST_TAG_COPYRIGHT,
1170           G_TYPE_STRING));
1171   str = gst_structure_get_string (taglist, GST_TAG_COPYRIGHT);
1172   fail_unless (strcmp (str, "my copyright") == 0);
1173
1174   gst_tag_list_free (taglist);
1175   gst_buffer_unref (buf);
1176 }
1177
1178 GST_END_TEST;
1179
1180
1181 static void
1182 do_exif_tag_serialization_deserialization (GstTagList * taglist)
1183 {
1184   GstTagList *taglist2;
1185   GstBuffer *buf;
1186
1187   /* LE */
1188   buf = gst_tag_list_to_exif_buffer (taglist, G_LITTLE_ENDIAN, 0);
1189   taglist2 = gst_tag_list_from_exif_buffer (buf, G_LITTLE_ENDIAN, 0);
1190   gst_buffer_unref (buf);
1191
1192   tag_list_equals (taglist, taglist2);
1193   gst_tag_list_free (taglist2);
1194
1195   /* BE */
1196   buf = gst_tag_list_to_exif_buffer (taglist, G_BIG_ENDIAN, 0);
1197   taglist2 = gst_tag_list_from_exif_buffer (buf, G_BIG_ENDIAN, 0);
1198   gst_buffer_unref (buf);
1199
1200   tag_list_equals (taglist, taglist2);
1201   gst_tag_list_free (taglist2);
1202
1203   /* APP1 */
1204   buf = gst_tag_list_to_exif_buffer_with_tiff_header (taglist);
1205   taglist2 = gst_tag_list_from_exif_buffer_with_tiff_header (buf);
1206   gst_buffer_unref (buf);
1207
1208   tag_list_equals (taglist, taglist2);
1209   gst_tag_list_free (taglist2);
1210 }
1211
1212 static void
1213 do_simple_exif_tag_serialization_deserialization (const gchar * gsttag,
1214     GValue * value)
1215 {
1216   GstTagList *taglist = gst_tag_list_new ();
1217
1218   gst_tag_list_add_value (taglist, GST_TAG_MERGE_REPLACE, gsttag, value);
1219
1220   do_exif_tag_serialization_deserialization (taglist);
1221
1222   gst_tag_list_free (taglist);
1223 }
1224
1225 /*
1226  * Adds tags from multiple ifd tables and tries serializing them
1227  */
1228 GST_START_TEST (test_exif_multiple_tags)
1229 {
1230   GstTagList *taglist;
1231   GstDateTime *datetime;
1232   GValue value = { 0 };
1233
1234   gst_tag_register_musicbrainz_tags ();
1235
1236   taglist = gst_tag_list_new_full (GST_TAG_ARTIST, "artist",
1237       GST_TAG_DEVICE_MANUFACTURER, "make",
1238       GST_TAG_DEVICE_MODEL, "model", GST_TAG_GEO_LOCATION_LATITUDE, 45.5,
1239       GST_TAG_GEO_LOCATION_LONGITUDE, -10.25,
1240       GST_TAG_IMAGE_HORIZONTAL_PPI, 300.0,
1241       GST_TAG_IMAGE_VERTICAL_PPI, 300.0, NULL);
1242
1243   g_value_init (&value, GST_TYPE_DATE_TIME);
1244   datetime = gst_date_time_new_local_time (2010, 6, 22, 12, 5, 10);
1245   g_value_set_boxed (&value, datetime);
1246   gst_date_time_unref (datetime);
1247   gst_tag_list_add_value (taglist, GST_TAG_MERGE_APPEND, GST_TAG_DATE_TIME,
1248       &value);
1249   g_value_unset (&value);
1250
1251   do_exif_tag_serialization_deserialization (taglist);
1252
1253   gst_tag_list_free (taglist);
1254 }
1255
1256 GST_END_TEST;
1257
1258
1259 GST_START_TEST (test_exif_tags_serialization_deserialization)
1260 {
1261   GValue value = { 0 };
1262   GstDateTime *datetime = NULL;
1263   GstBuffer *buf = NULL;
1264   gint i;
1265   GstTagList *taglist;
1266
1267   gst_tag_register_musicbrainz_tags ();
1268
1269   g_value_init (&value, G_TYPE_STRING);
1270   g_value_set_static_string (&value, "my string");
1271   do_simple_exif_tag_serialization_deserialization (GST_TAG_COPYRIGHT, &value);
1272   g_value_set_static_string (&value, "ty");
1273   do_simple_exif_tag_serialization_deserialization (GST_TAG_ARTIST, &value);
1274   g_value_set_static_string (&value, "Company Software 1.2b (info)");
1275   do_simple_exif_tag_serialization_deserialization (GST_TAG_APPLICATION_NAME,
1276       &value);
1277
1278   /* image orientation tests */
1279   g_value_set_static_string (&value, "rotate-0");
1280   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1281       &value);
1282   g_value_set_static_string (&value, "flip-rotate-0");
1283   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1284       &value);
1285   g_value_set_static_string (&value, "rotate-180");
1286   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1287       &value);
1288   g_value_set_static_string (&value, "flip-rotate-180");
1289   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1290       &value);
1291   g_value_set_static_string (&value, "flip-rotate-270");
1292   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1293       &value);
1294   g_value_set_static_string (&value, "rotate-90");
1295   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1296       &value);
1297   g_value_set_static_string (&value, "flip-rotate-90");
1298   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1299       &value);
1300   g_value_set_static_string (&value, "rotate-270");
1301   do_simple_exif_tag_serialization_deserialization (GST_TAG_IMAGE_ORIENTATION,
1302       &value);
1303
1304   /* exposure program */
1305   g_value_set_static_string (&value, "undefined");
1306   do_simple_exif_tag_serialization_deserialization
1307       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1308   g_value_set_static_string (&value, "manual");
1309   do_simple_exif_tag_serialization_deserialization
1310       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1311   g_value_set_static_string (&value, "normal");
1312   do_simple_exif_tag_serialization_deserialization
1313       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1314   g_value_set_static_string (&value, "aperture-priority");
1315   do_simple_exif_tag_serialization_deserialization
1316       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1317   g_value_set_static_string (&value, "shutter-priority");
1318   do_simple_exif_tag_serialization_deserialization
1319       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1320   g_value_set_static_string (&value, "creative");
1321   do_simple_exif_tag_serialization_deserialization
1322       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1323   g_value_set_static_string (&value, "action");
1324   do_simple_exif_tag_serialization_deserialization
1325       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1326   g_value_set_static_string (&value, "portrait");
1327   do_simple_exif_tag_serialization_deserialization
1328       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1329   g_value_set_static_string (&value, "landscape");
1330   do_simple_exif_tag_serialization_deserialization
1331       (GST_TAG_CAPTURING_EXPOSURE_PROGRAM, &value);
1332
1333   /* exposure mode */
1334   g_value_set_static_string (&value, "auto-exposure");
1335   do_simple_exif_tag_serialization_deserialization
1336       (GST_TAG_CAPTURING_EXPOSURE_MODE, &value);
1337   g_value_set_static_string (&value, "manual-exposure");
1338   do_simple_exif_tag_serialization_deserialization
1339       (GST_TAG_CAPTURING_EXPOSURE_MODE, &value);
1340   g_value_set_static_string (&value, "auto-bracket");
1341   do_simple_exif_tag_serialization_deserialization
1342       (GST_TAG_CAPTURING_EXPOSURE_MODE, &value);
1343
1344   /* scene capture type */
1345   g_value_set_static_string (&value, "standard");
1346   do_simple_exif_tag_serialization_deserialization
1347       (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value);
1348   g_value_set_static_string (&value, "portrait");
1349   do_simple_exif_tag_serialization_deserialization
1350       (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value);
1351   g_value_set_static_string (&value, "landscape");
1352   do_simple_exif_tag_serialization_deserialization
1353       (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value);
1354   g_value_set_static_string (&value, "night-scene");
1355   do_simple_exif_tag_serialization_deserialization
1356       (GST_TAG_CAPTURING_SCENE_CAPTURE_TYPE, &value);
1357
1358   g_value_set_static_string (&value, "none");
1359   do_simple_exif_tag_serialization_deserialization
1360       (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value);
1361   g_value_set_static_string (&value, "high-gain-up");
1362   do_simple_exif_tag_serialization_deserialization
1363       (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value);
1364   g_value_set_static_string (&value, "low-gain-up");
1365   do_simple_exif_tag_serialization_deserialization
1366       (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value);
1367   g_value_set_static_string (&value, "high-gain-down");
1368   do_simple_exif_tag_serialization_deserialization
1369       (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value);
1370   g_value_set_static_string (&value, "low-gain-down");
1371   do_simple_exif_tag_serialization_deserialization
1372       (GST_TAG_CAPTURING_GAIN_ADJUSTMENT, &value);
1373
1374   g_value_set_static_string (&value, "auto");
1375   do_simple_exif_tag_serialization_deserialization
1376       (GST_TAG_CAPTURING_WHITE_BALANCE, &value);
1377   g_value_set_static_string (&value, "manual");
1378   do_simple_exif_tag_serialization_deserialization
1379       (GST_TAG_CAPTURING_WHITE_BALANCE, &value);
1380
1381   g_value_set_static_string (&value, "normal");
1382   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_CONTRAST,
1383       &value);
1384   g_value_set_static_string (&value, "hard");
1385   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_CONTRAST,
1386       &value);
1387   g_value_set_static_string (&value, "soft");
1388   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_CONTRAST,
1389       &value);
1390
1391   g_value_set_static_string (&value, "normal");
1392   do_simple_exif_tag_serialization_deserialization
1393       (GST_TAG_CAPTURING_SATURATION, &value);
1394   g_value_set_static_string (&value, "low-saturation");
1395   do_simple_exif_tag_serialization_deserialization
1396       (GST_TAG_CAPTURING_SATURATION, &value);
1397   g_value_set_static_string (&value, "high-saturation");
1398   do_simple_exif_tag_serialization_deserialization
1399       (GST_TAG_CAPTURING_SATURATION, &value);
1400
1401   g_value_set_static_string (&value, "normal");
1402   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHARPNESS,
1403       &value);
1404   g_value_set_static_string (&value, "hard");
1405   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHARPNESS,
1406       &value);
1407   g_value_set_static_string (&value, "soft");
1408   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SHARPNESS,
1409       &value);
1410
1411   g_value_set_static_string (&value, "unknown");
1412   do_simple_exif_tag_serialization_deserialization
1413       (GST_TAG_CAPTURING_METERING_MODE, &value);
1414   g_value_set_static_string (&value, "average");
1415   do_simple_exif_tag_serialization_deserialization
1416       (GST_TAG_CAPTURING_METERING_MODE, &value);
1417   g_value_set_static_string (&value, "center-weighted-average");
1418   do_simple_exif_tag_serialization_deserialization
1419       (GST_TAG_CAPTURING_METERING_MODE, &value);
1420   g_value_set_static_string (&value, "spot");
1421   do_simple_exif_tag_serialization_deserialization
1422       (GST_TAG_CAPTURING_METERING_MODE, &value);
1423   g_value_set_static_string (&value, "multi-spot");
1424   do_simple_exif_tag_serialization_deserialization
1425       (GST_TAG_CAPTURING_METERING_MODE, &value);
1426   g_value_set_static_string (&value, "pattern");
1427   do_simple_exif_tag_serialization_deserialization
1428       (GST_TAG_CAPTURING_METERING_MODE, &value);
1429   g_value_set_static_string (&value, "partial");
1430   do_simple_exif_tag_serialization_deserialization
1431       (GST_TAG_CAPTURING_METERING_MODE, &value);
1432   g_value_set_static_string (&value, "other");
1433   do_simple_exif_tag_serialization_deserialization
1434       (GST_TAG_CAPTURING_METERING_MODE, &value);
1435
1436   g_value_set_static_string (&value, "dsc");
1437   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE,
1438       &value);
1439   g_value_set_static_string (&value, "other");
1440   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE,
1441       &value);
1442   g_value_set_static_string (&value, "transparent-scanner");
1443   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE,
1444       &value);
1445   g_value_set_static_string (&value, "reflex-scanner");
1446   do_simple_exif_tag_serialization_deserialization (GST_TAG_CAPTURING_SOURCE,
1447       &value);
1448   g_value_unset (&value);
1449
1450   g_value_init (&value, G_TYPE_DOUBLE);
1451   g_value_set_double (&value, 30.5);
1452   do_simple_exif_tag_serialization_deserialization
1453       (GST_TAG_GEO_LOCATION_LATITUDE, &value);
1454   g_value_set_double (&value, -12.125);
1455   do_simple_exif_tag_serialization_deserialization
1456       (GST_TAG_GEO_LOCATION_LATITUDE, &value);
1457   g_value_set_double (&value, 0);
1458   do_simple_exif_tag_serialization_deserialization
1459       (GST_TAG_GEO_LOCATION_LONGITUDE, &value);
1460   g_value_set_double (&value, 65.0);
1461   do_simple_exif_tag_serialization_deserialization
1462       (GST_TAG_GEO_LOCATION_LONGITUDE, &value);
1463   g_value_set_double (&value, -0.75);
1464   do_simple_exif_tag_serialization_deserialization
1465       (GST_TAG_GEO_LOCATION_LONGITUDE, &value);
1466
1467   g_value_set_double (&value, 0.0);
1468   do_simple_exif_tag_serialization_deserialization
1469       (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value);
1470   g_value_set_double (&value, 180.5);
1471   do_simple_exif_tag_serialization_deserialization
1472       (GST_TAG_GEO_LOCATION_CAPTURE_DIRECTION, &value);
1473   g_value_set_double (&value, 0.12345);
1474   do_simple_exif_tag_serialization_deserialization
1475       (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value);
1476   g_value_set_double (&value, 359.9);
1477   do_simple_exif_tag_serialization_deserialization
1478       (GST_TAG_GEO_LOCATION_MOVEMENT_DIRECTION, &value);
1479
1480   g_value_set_double (&value, 0.0);
1481   do_simple_exif_tag_serialization_deserialization
1482       (GST_TAG_GEO_LOCATION_ELEVATION, &value);
1483   g_value_set_double (&value, 321.456);
1484   do_simple_exif_tag_serialization_deserialization
1485       (GST_TAG_GEO_LOCATION_ELEVATION, &value);
1486   g_value_set_double (&value, -12.56);
1487   do_simple_exif_tag_serialization_deserialization
1488       (GST_TAG_GEO_LOCATION_ELEVATION, &value);
1489
1490   g_value_set_double (&value, 0);
1491   do_simple_exif_tag_serialization_deserialization
1492       (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value);
1493   g_value_set_double (&value, 100 / 3.6);
1494   do_simple_exif_tag_serialization_deserialization
1495       (GST_TAG_GEO_LOCATION_MOVEMENT_SPEED, &value);
1496
1497   g_value_set_double (&value, 0);
1498   do_simple_exif_tag_serialization_deserialization
1499       (GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR, &value);
1500   g_value_set_double (&value, 50.25);
1501   do_simple_exif_tag_serialization_deserialization
1502       (GST_TAG_GEO_LOCATION_HORIZONTAL_ERROR, &value);
1503
1504   g_value_set_double (&value, 0);
1505   do_simple_exif_tag_serialization_deserialization
1506       (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, &value);
1507   g_value_set_double (&value, 2.5);
1508   do_simple_exif_tag_serialization_deserialization
1509       (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, &value);
1510   g_value_set_double (&value, 8.75);
1511   do_simple_exif_tag_serialization_deserialization
1512       (GST_TAG_CAPTURING_DIGITAL_ZOOM_RATIO, &value);
1513
1514   g_value_set_double (&value, 20.0);
1515   do_simple_exif_tag_serialization_deserialization
1516       (GST_TAG_CAPTURING_FOCAL_LENGTH, &value);
1517   g_value_set_double (&value, 5.5);
1518   do_simple_exif_tag_serialization_deserialization
1519       (GST_TAG_CAPTURING_FOCAL_LENGTH, &value);
1520
1521   g_value_set_double (&value, 16);
1522   do_simple_exif_tag_serialization_deserialization
1523       (GST_TAG_CAPTURING_FOCAL_RATIO, &value);
1524   g_value_set_double (&value, 2.7);
1525   do_simple_exif_tag_serialization_deserialization
1526       (GST_TAG_CAPTURING_FOCAL_LENGTH, &value);
1527
1528   g_value_set_double (&value, 96.0);
1529   do_simple_exif_tag_serialization_deserialization
1530       (GST_TAG_IMAGE_HORIZONTAL_PPI, &value);
1531   g_value_set_double (&value, 300.0);
1532   do_simple_exif_tag_serialization_deserialization
1533       (GST_TAG_IMAGE_HORIZONTAL_PPI, &value);
1534   g_value_set_double (&value, 87.5);
1535   do_simple_exif_tag_serialization_deserialization
1536       (GST_TAG_IMAGE_VERTICAL_PPI, &value);
1537   g_value_set_double (&value, 600.0);
1538   do_simple_exif_tag_serialization_deserialization
1539       (GST_TAG_IMAGE_VERTICAL_PPI, &value);
1540
1541   g_value_set_double (&value, 0.0);
1542   do_simple_exif_tag_serialization_deserialization
1543       (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, &value);
1544   g_value_set_double (&value, 1.0);
1545   do_simple_exif_tag_serialization_deserialization
1546       (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, &value);
1547   g_value_set_double (&value, -2.5);
1548   do_simple_exif_tag_serialization_deserialization
1549       (GST_TAG_CAPTURING_EXPOSURE_COMPENSATION, &value);
1550   g_value_unset (&value);
1551
1552   g_value_init (&value, G_TYPE_INT);
1553   g_value_set_int (&value, 400);
1554   do_simple_exif_tag_serialization_deserialization
1555       (GST_TAG_CAPTURING_ISO_SPEED, &value);
1556   g_value_set_int (&value, 1600);
1557   do_simple_exif_tag_serialization_deserialization
1558       (GST_TAG_CAPTURING_ISO_SPEED, &value);
1559   g_value_unset (&value);
1560
1561   g_value_init (&value, GST_TYPE_DATE_TIME);
1562   datetime = gst_date_time_new_local_time (2010, 6, 22, 12, 5, 10);
1563   g_value_set_boxed (&value, datetime);
1564   gst_date_time_unref (datetime);
1565   do_simple_exif_tag_serialization_deserialization (GST_TAG_DATE_TIME, &value);
1566   g_value_unset (&value);
1567
1568   g_value_init (&value, GST_TYPE_BUFFER);
1569   buf = gst_buffer_new_and_alloc (1024);
1570   for (i = 0; i < 1024; i++)
1571     GST_BUFFER_DATA (buf)[i] = i % 255;
1572   gst_value_set_buffer (&value, buf);
1573   gst_buffer_unref (buf);
1574   do_simple_exif_tag_serialization_deserialization (GST_TAG_APPLICATION_DATA,
1575       &value);
1576   g_value_unset (&value);
1577
1578   g_value_init (&value, GST_TYPE_FRACTION);
1579   gst_value_set_fraction (&value, 1, 1);
1580   do_simple_exif_tag_serialization_deserialization
1581       (GST_TAG_CAPTURING_SHUTTER_SPEED, &value);
1582   gst_value_set_fraction (&value, 1, 30);
1583   do_simple_exif_tag_serialization_deserialization
1584       (GST_TAG_CAPTURING_SHUTTER_SPEED, &value);
1585   gst_value_set_fraction (&value, 1, 200);
1586   do_simple_exif_tag_serialization_deserialization
1587       (GST_TAG_CAPTURING_SHUTTER_SPEED, &value);
1588   gst_value_set_fraction (&value, 1, 8000);
1589   do_simple_exif_tag_serialization_deserialization
1590       (GST_TAG_CAPTURING_SHUTTER_SPEED, &value);
1591   g_value_unset (&value);
1592
1593   /* flash is a little bit more tricky, because 2 tags are merged into 1 in
1594    * exif */
1595   taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, FALSE,
1596       GST_TAG_CAPTURING_FLASH_MODE, "auto", NULL);
1597   do_exif_tag_serialization_deserialization (taglist);
1598   gst_tag_list_free (taglist);
1599
1600   taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, TRUE,
1601       GST_TAG_CAPTURING_FLASH_MODE, "auto", NULL);
1602   do_exif_tag_serialization_deserialization (taglist);
1603   gst_tag_list_free (taglist);
1604
1605   taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, FALSE,
1606       GST_TAG_CAPTURING_FLASH_MODE, "never", NULL);
1607   do_exif_tag_serialization_deserialization (taglist);
1608   gst_tag_list_free (taglist);
1609
1610   taglist = gst_tag_list_new_full (GST_TAG_CAPTURING_FLASH_FIRED, TRUE,
1611       GST_TAG_CAPTURING_FLASH_MODE, "always", NULL);
1612   do_exif_tag_serialization_deserialization (taglist);
1613   gst_tag_list_free (taglist);
1614 }
1615
1616 GST_END_TEST;
1617
1618 static Suite *
1619 tag_suite (void)
1620 {
1621   Suite *s = suite_create ("tag support library");
1622   TCase *tc_chain = tcase_create ("general");
1623
1624   suite_add_tcase (s, tc_chain);
1625   tcase_add_test (tc_chain, test_musicbrainz_tag_registration);
1626   tcase_add_test (tc_chain, test_parse_extended_comment);
1627   tcase_add_test (tc_chain, test_vorbis_tags);
1628   tcase_add_test (tc_chain, test_id3_tags);
1629   tcase_add_test (tc_chain, test_id3v1_utf8_tag);
1630   tcase_add_test (tc_chain, test_language_utils);
1631   tcase_add_test (tc_chain, test_xmp_formatting);
1632   tcase_add_test (tc_chain, test_xmp_parsing);
1633   tcase_add_test (tc_chain, test_xmp_tags_serialization_deserialization);
1634   tcase_add_test (tc_chain, test_xmp_compound_tags);
1635   tcase_add_test (tc_chain, test_exif_parsing);
1636   tcase_add_test (tc_chain, test_exif_tags_serialization_deserialization);
1637   tcase_add_test (tc_chain, test_exif_multiple_tags);
1638   return s;
1639 }
1640
1641 int
1642 main (int argc, char **argv)
1643 {
1644   int nf;
1645
1646   Suite *s = tag_suite ();
1647   SRunner *sr = srunner_create (s);
1648
1649   gst_check_init (&argc, &argv);
1650
1651   srunner_run_all (sr, CK_NORMAL);
1652   nf = srunner_ntests_failed (sr);
1653   srunner_free (sr);
1654
1655   return nf;
1656 }