1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 //  The contents of this file are subject to the Mozilla Public License
4 //  Version 1.1 (the "License"); you may not use this file except in
5 //  compliance with the License. You may obtain a copy of the License at
6 //  http://www.mozilla.org/MPL/
7 //
8 //  Software distributed under the License is distributed on an "AS IS"
9 //  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
10 //  License for the specific language governing rights and limitations
11 //  under the License.
12 //
13 //  The Original Code is MP4v2.
14 //
15 //  The Initial Developer of the Original Code is Kona Blend.
16 //  Portions created by Kona Blend are Copyright (C) 2008.
17 //  All Rights Reserved.
18 //
19 //  Contributors:
20 //      Kona Blend, kona8lend@@gmail.com
21 //      Rouven Wessling, mp4v2@rouvenwessling.de
22 //
23 ///////////////////////////////////////////////////////////////////////////////
24 
25 #include "impl.h"
26 
27 namespace mp4v2 { namespace impl {
28 
29 ///////////////////////////////////////////////////////////////////////////////
30 
31 template <>
32 const itmf::EnumBasicType::Entry itmf::EnumBasicType::data[] = {
33     { mp4v2::impl::itmf::BT_IMPLICIT,  "implicit",  "implicit" },
34     { mp4v2::impl::itmf::BT_UTF8,      "utf8",      "UTF-8" },
35     { mp4v2::impl::itmf::BT_UTF16,     "utf16",     "UTF-16" },
36     { mp4v2::impl::itmf::BT_SJIS,      "sjis",      "S/JIS" },
37     { mp4v2::impl::itmf::BT_HTML,      "html",      "HTML" },
38     { mp4v2::impl::itmf::BT_XML,       "xml",       "XML" },
39     { mp4v2::impl::itmf::BT_UUID,      "uuid",      "UUID" },
40     { mp4v2::impl::itmf::BT_ISRC,      "isrc",      "ISRC" },
41     { mp4v2::impl::itmf::BT_MI3P,      "mi3p",      "MI3P" },
42     { mp4v2::impl::itmf::BT_GIF,       "gif",       "GIF" },
43     { mp4v2::impl::itmf::BT_JPEG,      "jpeg",      "JPEG" },
44     { mp4v2::impl::itmf::BT_PNG,       "png",       "PNG" },
45     { mp4v2::impl::itmf::BT_URL,       "url",       "URL" },
46     { mp4v2::impl::itmf::BT_DURATION,  "duration",  "duration" },
47     { mp4v2::impl::itmf::BT_DATETIME,  "datetime",  "date/time" },
48     { mp4v2::impl::itmf::BT_GENRES,    "genres",    "genres" },
49     { mp4v2::impl::itmf::BT_INTEGER,   "integer",   "integer" },
50     { mp4v2::impl::itmf::BT_RIAA_PA,   "riaapa",    "RIAA-PA" },
51     { mp4v2::impl::itmf::BT_UPC,       "upc",       "UPC" },
52     { mp4v2::impl::itmf::BT_BMP,       "bmp",       "BMP" },
53 
54     { mp4v2::impl::itmf::BT_UNDEFINED } // must be last
55 };
56 
57 ///////////////////////////////////////////////////////////////////////////////
58 
59 template <>
60 const itmf::EnumGenreType::Entry itmf::EnumGenreType::data[] = {
61     { mp4v2::impl::itmf::GENRE_BLUES,             "blues",             "Blues" },
62     { mp4v2::impl::itmf::GENRE_CLASSIC_ROCK,      "classicrock",       "Classic Rock" },
63     { mp4v2::impl::itmf::GENRE_COUNTRY,           "country",           "Country" },
64     { mp4v2::impl::itmf::GENRE_DANCE,             "dance",             "Dance" },
65     { mp4v2::impl::itmf::GENRE_DISCO,             "disco",             "Disco" },
66     { mp4v2::impl::itmf::GENRE_FUNK,              "funk",              "Funk" },
67     { mp4v2::impl::itmf::GENRE_GRUNGE,            "grunge",            "Grunge" },
68     { mp4v2::impl::itmf::GENRE_HIP_HOP,           "hiphop",            "Hop-Hop" },
69     { mp4v2::impl::itmf::GENRE_JAZZ,              "jazz",              "Jazz" },
70     { mp4v2::impl::itmf::GENRE_METAL,             "metal",             "Metal" },
71     { mp4v2::impl::itmf::GENRE_NEW_AGE,           "newage",            "New Age" },
72     { mp4v2::impl::itmf::GENRE_OLDIES,            "oldies",            "Oldies" },
73     { mp4v2::impl::itmf::GENRE_OTHER,             "other",             "Other" },
74     { mp4v2::impl::itmf::GENRE_POP,               "pop",               "Pop" },
75     { mp4v2::impl::itmf::GENRE_R_AND_B,           "rand_b",            "R&B" },
76     { mp4v2::impl::itmf::GENRE_RAP,               "rap",               "Rap" },
77     { mp4v2::impl::itmf::GENRE_REGGAE,            "reggae",            "Reggae" },
78     { mp4v2::impl::itmf::GENRE_ROCK,              "rock",              "Rock" },
79     { mp4v2::impl::itmf::GENRE_TECHNO,            "techno",            "Techno" },
80     { mp4v2::impl::itmf::GENRE_INDUSTRIAL,        "industrial",        "Industrial" },
81     { mp4v2::impl::itmf::GENRE_ALTERNATIVE,       "alternative",       "Alternative" },
82     { mp4v2::impl::itmf::GENRE_SKA,               "ska",               "Ska" },
83     { mp4v2::impl::itmf::GENRE_DEATH_METAL,       "deathmetal",        "Death Metal" },
84     { mp4v2::impl::itmf::GENRE_PRANKS,            "pranks",            "Pranks" },
85     { mp4v2::impl::itmf::GENRE_SOUNDTRACK,        "soundtrack",        "Soundtrack" },
86     { mp4v2::impl::itmf::GENRE_EURO_TECHNO,       "eurotechno",        "Euro-Techno" },
87     { mp4v2::impl::itmf::GENRE_AMBIENT,           "ambient",           "Ambient" },
88     { mp4v2::impl::itmf::GENRE_TRIP_HOP,          "triphop",           "Trip-Hop" },
89     { mp4v2::impl::itmf::GENRE_VOCAL,             "vocal",             "Vocal" },
90     { mp4v2::impl::itmf::GENRE_JAZZ_FUNK,         "jazzfunk",          "Jazz+Funk" },
91     { mp4v2::impl::itmf::GENRE_FUSION,            "fusion",            "Fusion" },
92     { mp4v2::impl::itmf::GENRE_TRANCE,            "trance",            "Trance" },
93     { mp4v2::impl::itmf::GENRE_CLASSICAL,         "classical",         "Classical" },
94     { mp4v2::impl::itmf::GENRE_INSTRUMENTAL,      "instrumental",      "Instrumental" },
95     { mp4v2::impl::itmf::GENRE_ACID,              "acid",              "Acid" },
96     { mp4v2::impl::itmf::GENRE_HOUSE,             "house",             "House" },
97     { mp4v2::impl::itmf::GENRE_GAME,              "game",              "Game" },
98     { mp4v2::impl::itmf::GENRE_SOUND_CLIP,        "soundclip",         "Sound Clip" },
99     { mp4v2::impl::itmf::GENRE_GOSPEL,            "gospel",            "Gospel" },
100     { mp4v2::impl::itmf::GENRE_NOISE,             "noise",             "Noise" },
101     { mp4v2::impl::itmf::GENRE_ALTERNROCK,        "alternrock",        "AlternRock" },
102     { mp4v2::impl::itmf::GENRE_BASS,              "bass",              "Bass" },
103     { mp4v2::impl::itmf::GENRE_SOUL,              "soul",              "Soul" },
104     { mp4v2::impl::itmf::GENRE_PUNK,              "punk",              "Punk" },
105     { mp4v2::impl::itmf::GENRE_SPACE,             "space",             "Space" },
106     { mp4v2::impl::itmf::GENRE_MEDITATIVE,        "meditative",        "Meditative" },
107     { mp4v2::impl::itmf::GENRE_INSTRUMENTAL_POP,  "instrumentalpop",   "Instrumental Pop" },
108     { mp4v2::impl::itmf::GENRE_INSTRUMENTAL_ROCK, "instrumentalrock",  "Instrumental Rock" },
109     { mp4v2::impl::itmf::GENRE_ETHNIC,            "ethnic",            "Ethnic" },
110     { mp4v2::impl::itmf::GENRE_GOTHIC,            "gothic",            "Gothic" },
111     { mp4v2::impl::itmf::GENRE_DARKWAVE,          "darkwave",          "Darkwave" },
112     { mp4v2::impl::itmf::GENRE_TECHNO_INDUSTRIAL, "technoindustrial",  "Techno-Industrial" },
113     { mp4v2::impl::itmf::GENRE_ELECTRONIC,        "electronic",        "Electronic" },
114     { mp4v2::impl::itmf::GENRE_POP_FOLK,          "popfolk",           "Pop-Folk" },
115     { mp4v2::impl::itmf::GENRE_EURODANCE,         "eurodance",         "Eurodance" },
116     { mp4v2::impl::itmf::GENRE_DREAM,             "dream",             "Dream" },
117     { mp4v2::impl::itmf::GENRE_SOUTHERN_ROCK,     "southernrock",      "Southern Rock" },
118     { mp4v2::impl::itmf::GENRE_COMEDY,            "comedy",            "Comedy" },
119     { mp4v2::impl::itmf::GENRE_CULT,              "cult",              "Cult" },
120     { mp4v2::impl::itmf::GENRE_GANGSTA,           "gangsta",           "Gangsta" },
121     { mp4v2::impl::itmf::GENRE_TOP_40,            "top40",             "Top 40" },
122     { mp4v2::impl::itmf::GENRE_CHRISTIAN_RAP,     "christianrap",      "Christian Rap" },
123     { mp4v2::impl::itmf::GENRE_POP_FUNK,          "popfunk",           "Pop/Funk" },
124     { mp4v2::impl::itmf::GENRE_JUNGLE,            "jungle",            "Jungle" },
125     { mp4v2::impl::itmf::GENRE_NATIVE_AMERICAN,   "nativeamerican",    "Native American" },
126     { mp4v2::impl::itmf::GENRE_CABARET,           "cabaret",           "Cabaret" },
127     { mp4v2::impl::itmf::GENRE_NEW_WAVE,          "newwave",           "New Wave" },
128     { mp4v2::impl::itmf::GENRE_PSYCHEDELIC,       "psychedelic",       "Psychedelic" },
129     { mp4v2::impl::itmf::GENRE_RAVE,              "rave",              "Rave" },
130     { mp4v2::impl::itmf::GENRE_SHOWTUNES,         "showtunes",         "Showtunes" },
131     { mp4v2::impl::itmf::GENRE_TRAILER,           "trailer",           "Trailer" },
132     { mp4v2::impl::itmf::GENRE_LO_FI,             "lofi",              "Lo-Fi" },
133     { mp4v2::impl::itmf::GENRE_TRIBAL,            "tribal",            "Tribal" },
134     { mp4v2::impl::itmf::GENRE_ACID_PUNK,         "acidpunk",          "Acid Punk" },
135     { mp4v2::impl::itmf::GENRE_ACID_JAZZ,         "acidjazz",          "Acid Jazz" },
136     { mp4v2::impl::itmf::GENRE_POLKA,             "polka",             "Polka" },
137     { mp4v2::impl::itmf::GENRE_RETRO,             "retro",             "Retro" },
138     { mp4v2::impl::itmf::GENRE_MUSICAL,           "musical",           "Musical" },
139     { mp4v2::impl::itmf::GENRE_ROCK_AND_ROLL,     "rockand_roll",      "Rock & Roll" },
140 
141     { mp4v2::impl::itmf::GENRE_HARD_ROCK,         "hardrock",          "Hard Rock" },
142     { mp4v2::impl::itmf::GENRE_FOLK,              "folk",              "Folk" },
143     { mp4v2::impl::itmf::GENRE_FOLK_ROCK,         "folkrock",          "Folk-Rock" },
144     { mp4v2::impl::itmf::GENRE_NATIONAL_FOLK,     "nationalfolk",      "National Folk" },
145     { mp4v2::impl::itmf::GENRE_SWING,             "swing",             "Swing" },
146     { mp4v2::impl::itmf::GENRE_FAST_FUSION,       "fastfusion",        "Fast Fusion" },
147     { mp4v2::impl::itmf::GENRE_BEBOB,             "bebob",             "Bebob" },
148     { mp4v2::impl::itmf::GENRE_LATIN,             "latin",             "Latin" },
149     { mp4v2::impl::itmf::GENRE_REVIVAL,           "revival",           "Revival" },
150     { mp4v2::impl::itmf::GENRE_CELTIC,            "celtic",            "Celtic" },
151     { mp4v2::impl::itmf::GENRE_BLUEGRASS,         "bluegrass",         "Bluegrass" },
152     { mp4v2::impl::itmf::GENRE_AVANTGARDE,        "avantgarde",        "Avantgarde" },
153     { mp4v2::impl::itmf::GENRE_GOTHIC_ROCK,       "gothicrock",        "Gothic Rock" },
154     { mp4v2::impl::itmf::GENRE_PROGRESSIVE_ROCK,  "progressiverock",   "Progresive Rock" },
155     { mp4v2::impl::itmf::GENRE_PSYCHEDELIC_ROCK,  "psychedelicrock",   "Psychedelic Rock" },
156     { mp4v2::impl::itmf::GENRE_SYMPHONIC_ROCK,    "symphonicrock",     "SYMPHONIC_ROCK" },
157     { mp4v2::impl::itmf::GENRE_SLOW_ROCK,         "slowrock",          "Slow Rock" },
158     { mp4v2::impl::itmf::GENRE_BIG_BAND,          "bigband",           "Big Band" },
159     { mp4v2::impl::itmf::GENRE_CHORUS,            "chorus",            "Chorus" },
160     { mp4v2::impl::itmf::GENRE_EASY_LISTENING,    "easylistening",     "Easy Listening" },
161     { mp4v2::impl::itmf::GENRE_ACOUSTIC,          "acoustic",          "Acoustic" },
162     { mp4v2::impl::itmf::GENRE_HUMOUR,            "humour",            "Humor" },
163     { mp4v2::impl::itmf::GENRE_SPEECH,            "speech",            "Speech" },
164     { mp4v2::impl::itmf::GENRE_CHANSON,           "chanson",           "Chason" },
165     { mp4v2::impl::itmf::GENRE_OPERA,             "opera",             "Opera" },
166     { mp4v2::impl::itmf::GENRE_CHAMBER_MUSIC,     "chambermusic",      "Chamber Music" },
167     { mp4v2::impl::itmf::GENRE_SONATA,            "sonata",            "Sonata" },
168     { mp4v2::impl::itmf::GENRE_SYMPHONY,          "symphony",          "Symphony" },
169     { mp4v2::impl::itmf::GENRE_BOOTY_BASS,        "bootybass",         "Booty Bass" },
170     { mp4v2::impl::itmf::GENRE_PRIMUS,            "primus",            "Primus" },
171     { mp4v2::impl::itmf::GENRE_PORN_GROOVE,       "porngroove",        "Porn Groove" },
172     { mp4v2::impl::itmf::GENRE_SATIRE,            "satire",            "Satire" },
173     { mp4v2::impl::itmf::GENRE_SLOW_JAM,          "slowjam",           "Slow Jam" },
174     { mp4v2::impl::itmf::GENRE_CLUB,              "club",              "Club" },
175     { mp4v2::impl::itmf::GENRE_TANGO,             "tango",             "Tango" },
176     { mp4v2::impl::itmf::GENRE_SAMBA,             "samba",             "Samba" },
177     { mp4v2::impl::itmf::GENRE_FOLKLORE,          "folklore",          "Folklore" },
178     { mp4v2::impl::itmf::GENRE_BALLAD,            "ballad",            "Ballad" },
179     { mp4v2::impl::itmf::GENRE_POWER_BALLAD,      "powerballad",       "Power Ballad" },
180     { mp4v2::impl::itmf::GENRE_RHYTHMIC_SOUL,     "rhythmicsoul",      "Rhythmic Soul" },
181     { mp4v2::impl::itmf::GENRE_FREESTYLE,         "freestyle",         "Freestyle" },
182     { mp4v2::impl::itmf::GENRE_DUET,              "duet",              "Duet" },
183     { mp4v2::impl::itmf::GENRE_PUNK_ROCK,         "punkrock",          "Punk Rock" },
184     { mp4v2::impl::itmf::GENRE_DRUM_SOLO,         "drumsolo",          "Drum Solo" },
185     { mp4v2::impl::itmf::GENRE_A_CAPELLA,         "acapella",          "A capella" },
186     { mp4v2::impl::itmf::GENRE_EURO_HOUSE,        "eurohouse",         "Euro-House" },
187     { mp4v2::impl::itmf::GENRE_DANCE_HALL,        "dancehall",         "Dance Hall" },
188     { mp4v2::impl::itmf::GENRE_NONE,              "none",              "none" },
189 
190     { mp4v2::impl::itmf::GENRE_UNDEFINED } // must be last
191 };
192 
193 ///////////////////////////////////////////////////////////////////////////////
194 
195 template <>
196 const itmf::EnumStikType::Entry itmf::EnumStikType::data[] = {
197     { mp4v2::impl::itmf::STIK_OLD_MOVIE,    "oldmovie",    "Movie" },
198     { mp4v2::impl::itmf::STIK_NORMAL,       "normal",      "Normal" },
199     { mp4v2::impl::itmf::STIK_AUDIOBOOK,    "audiobook",   "Audio Book" },
200     { mp4v2::impl::itmf::STIK_MUSIC_VIDEO,  "musicvideo",  "Music Video" },
201     { mp4v2::impl::itmf::STIK_MOVIE,        "movie",       "Movie" },
202     { mp4v2::impl::itmf::STIK_TV_SHOW,      "tvshow",      "TV Show" },
203     { mp4v2::impl::itmf::STIK_BOOKLET,      "booklet",     "Booklet" },
204     { mp4v2::impl::itmf::STIK_RINGTONE,     "ringtone",    "Ringtone" },
205 
206     { mp4v2::impl::itmf::STIK_UNDEFINED } // must be last
207 };
208 
209 ///////////////////////////////////////////////////////////////////////////////
210 
211 template <>
212 const itmf::EnumAccountType::Entry itmf::EnumAccountType::data[] = {
213     { mp4v2::impl::itmf::AT_ITUNES,  "itunes",   "iTunes" },
214     { mp4v2::impl::itmf::AT_AOL,     "aol",      "AOL" },
215 
216     { mp4v2::impl::itmf::AT_UNDEFINED } // must be last
217 };
218 
219 ///////////////////////////////////////////////////////////////////////////////
220 
221 template <>
222 const itmf::EnumCountryCode::Entry itmf::EnumCountryCode::data[] = {
223     { mp4v2::impl::itmf::CC_USA,  "usa",   "United States" },
224     { mp4v2::impl::itmf::CC_USA,  "fra",   "France" },
225     { mp4v2::impl::itmf::CC_DEU,  "ger",   "Germany" },
226     { mp4v2::impl::itmf::CC_GBR,  "gbr",   "United Kingdom" },
227     { mp4v2::impl::itmf::CC_AUT,  "aut",   "Austria" },
228     { mp4v2::impl::itmf::CC_BEL,  "bel",   "Belgium" },
229     { mp4v2::impl::itmf::CC_FIN,  "fin",   "Finland" },
230     { mp4v2::impl::itmf::CC_GRC,  "grc",   "Greece" },
231     { mp4v2::impl::itmf::CC_IRL,  "irl",   "Ireland" },
232     { mp4v2::impl::itmf::CC_ITA,  "ita",   "Italy" },
233     { mp4v2::impl::itmf::CC_LUX,  "lux",   "Luxembourg" },
234     { mp4v2::impl::itmf::CC_NLD,  "nld",   "Netherlands" },
235     { mp4v2::impl::itmf::CC_PRT,  "prt",   "Portugal" },
236     { mp4v2::impl::itmf::CC_ESP,  "esp",   "Spain" },
237     { mp4v2::impl::itmf::CC_CAN,  "can",   "Canada" },
238     { mp4v2::impl::itmf::CC_SWE,  "swe",   "Sweden" },
239     { mp4v2::impl::itmf::CC_NOR,  "nor",   "Norway" },
240     { mp4v2::impl::itmf::CC_DNK,  "dnk",   "Denmark" },
241     { mp4v2::impl::itmf::CC_CHE,  "che",   "Switzerland" },
242     { mp4v2::impl::itmf::CC_AUS,  "aus",   "Australia" },
243     { mp4v2::impl::itmf::CC_NZL,  "nzl",   "New Zealand" },
244     { mp4v2::impl::itmf::CC_JPN,  "jpn",   "Japan" },
245 
246     { mp4v2::impl::itmf::CC_UNDEFINED } // must be last
247 };
248 
249 ///////////////////////////////////////////////////////////////////////////////
250 
251 template <>
252 const itmf::EnumContentRating::Entry itmf::EnumContentRating::data[] = {
253     { mp4v2::impl::itmf::CR_NONE,      "none",       "None" },
254     { mp4v2::impl::itmf::CR_CLEAN,     "clean",      "Clean" },
255     { mp4v2::impl::itmf::CR_EXPLICIT,  "explicit",   "Explicit" },
256 
257     { mp4v2::impl::itmf::CR_UNDEFINED } // must be last
258 };
259 
260 ///////////////////////////////////////////////////////////////////////////////
261 
262 namespace itmf {
263 
264 ///////////////////////////////////////////////////////////////////////////////
265 
266 // must come after static data init
267 const EnumBasicType enumBasicType;
268 const EnumGenreType enumGenreType;
269 const EnumStikType enumStikType;
270 const EnumAccountType enumAccountType;
271 const EnumCountryCode enumCountryCode;
272 const EnumContentRating enumContentRating;
273 
274 ///////////////////////////////////////////////////////////////////////////////
275 
276 namespace {
277     struct ImageHeader {
278         BasicType type;
279         string    data;
280     };
281 
282     // POD static init does not need singletons
283     static ImageHeader IMAGE_HEADERS[] = {
284         { BT_BMP,  "\x42\x4d" },
285         { BT_GIF,  "GIF87a" },
286         { BT_GIF,  "GIF89a" },
287         { BT_JPEG, "\xff\xd8\xff\xe0" },
288         { BT_PNG,  "\x89\x50\x4e\x47\x0d\x0a\x1a\x0a" },
289         { BT_UNDEFINED } // must be last
290     };
291 }
292 
293 BasicType
computeBasicType(const void * buffer,uint32_t size)294 computeBasicType( const void* buffer, uint32_t size )
295 {
296     ImageHeader* found = NULL;
297     for( ImageHeader* p = IMAGE_HEADERS; p->type != BT_UNDEFINED; p++ ) {
298         ImageHeader& h = *p;
299 
300         if( size < h.data.size() )
301             continue;
302 
303         if( memcmp(h.data.data(), buffer, h.data.size()) == 0 ) {
304             found = &h;
305             break;
306         }
307     }
308 
309     return found ? found->type : BT_IMPLICIT;
310 }
311 
312 ///////////////////////////////////////////////////////////////////////////////
313 
314 }}} // namespace mp4v2::impl::itmf
315