1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2012-2014 L-SMASH project
6 * Authors: Yusuke Nakamura <muken.the.vfrmaniac@gmail.com>
8 * Permission to use, copy, modify, and/or distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *****************************************************************************/
21 /* This file is available under an ISC license. */
23 #include "common/internal.h" /* must be placed first */
30 static isom_data_t
*isom_add_metadata( lsmash_file_t
*file
,
31 lsmash_itunes_metadata_item item
,
32 char *meaning_string
, char *name_string
)
34 assert( file
&& file
->moov
);
35 if( ((item
== ITUNES_METADATA_ITEM_CUSTOM
) && (!meaning_string
|| !meaning_string
[0]) )
36 || (!file
->moov
->udta
&& !isom_add_udta( file
->moov
))
37 || (!file
->moov
->udta
->meta
&& !isom_add_meta( file
->moov
->udta
))
38 || (!file
->moov
->udta
->meta
->ilst
&& !isom_add_ilst( file
->moov
->udta
->meta
)) )
40 if( !file
->moov
->udta
->meta
->hdlr
)
42 if( !isom_add_hdlr( file
->moov
->udta
->meta
)
43 || isom_setup_handler_reference( file
->moov
->udta
->meta
->hdlr
, ISOM_META_HANDLER_TYPE_ITUNES_METADATA
) < 0 )
46 isom_ilst_t
*ilst
= file
->moov
->udta
->meta
->ilst
;
47 if( !isom_add_metaitem( ilst
, item
) )
49 isom_metaitem_t
*metaitem
= (isom_metaitem_t
*)ilst
->metaitem_list
.tail
->data
;
50 if( item
== ITUNES_METADATA_ITEM_CUSTOM
)
52 if( !isom_add_mean( metaitem
) )
54 isom_mean_t
*mean
= metaitem
->mean
;
55 mean
->meaning_string_length
= strlen( meaning_string
); /* No null terminator */
56 mean
->meaning_string
= lsmash_memdup( meaning_string
, mean
->meaning_string_length
);
57 if( !mean
->meaning_string
)
59 if( name_string
&& name_string
[0] )
61 if( !isom_add_name( metaitem
) )
63 isom_name_t
*name
= metaitem
->name
;
64 name
->name_length
= strlen( name_string
); /* No null terminator */
65 name
->name
= lsmash_memdup( name_string
, name
->name_length
);
70 if( !isom_add_data( metaitem
) )
72 return metaitem
->data
;
74 isom_remove_box_by_itself( metaitem
);
78 static int isom_set_itunes_metadata_string( lsmash_file_t
*file
,
79 lsmash_itunes_metadata_item item
,
80 lsmash_itunes_metadata_value_t value
, char *meaning
, char *name
)
82 uint32_t value_length
= strlen( value
.string
);
83 if( item
== ITUNES_METADATA_ITEM_DESCRIPTION
&& value_length
> 255 )
84 item
= ITUNES_METADATA_ITEM_LONG_DESCRIPTION
;
85 isom_data_t
*data
= isom_add_metadata( file
, item
, meaning
, name
);
87 return LSMASH_ERR_NAMELESS
;
88 data
->type_code
= ITUNES_METADATA_SUBTYPE_UTF8
;
89 data
->value_length
= value_length
; /* No null terminator */
90 data
->value
= lsmash_memdup( value
.string
, data
->value_length
);
93 isom_ilst_t
*ilst
= file
->moov
->udta
->meta
->ilst
;
94 isom_remove_box_by_itself( ilst
->metaitem_list
.tail
->data
);
95 return LSMASH_ERR_MEMORY_ALLOC
;
100 static int isom_set_itunes_metadata_integer( lsmash_file_t
*file
,
101 lsmash_itunes_metadata_item item
,
102 lsmash_itunes_metadata_value_t value
, char *meaning
, char *name
)
106 lsmash_itunes_metadata_item item
;
108 } metadata_code_type_table
[] =
110 { ITUNES_METADATA_ITEM_EPISODE_GLOBAL_ID
, 1 },
111 { ITUNES_METADATA_ITEM_PREDEFINED_GENRE
, 2 },
112 { ITUNES_METADATA_ITEM_CONTENT_RATING
, 1 },
113 { ITUNES_METADATA_ITEM_MEDIA_TYPE
, 1 },
114 { ITUNES_METADATA_ITEM_BEATS_PER_MINUTE
, 2 },
115 { ITUNES_METADATA_ITEM_TV_EPISODE
, 4 },
116 { ITUNES_METADATA_ITEM_TV_SEASON
, 4 },
117 { ITUNES_METADATA_ITEM_ITUNES_ACCOUNT_TYPE
, 1 },
118 { ITUNES_METADATA_ITEM_ITUNES_ARTIST_ID
, 4 },
119 { ITUNES_METADATA_ITEM_ITUNES_COMPOSER_ID
, 4 },
120 { ITUNES_METADATA_ITEM_ITUNES_CATALOG_ID
, 4 },
121 { ITUNES_METADATA_ITEM_ITUNES_TV_GENRE_ID
, 4 },
122 { ITUNES_METADATA_ITEM_ITUNES_PLAYLIST_ID
, 8 },
123 { ITUNES_METADATA_ITEM_ITUNES_COUNTRY_CODE
, 4 },
124 { ITUNES_METADATA_ITEM_CUSTOM
, 8 },
128 for( i
= 0; metadata_code_type_table
[i
].item
; i
++ )
129 if( item
== metadata_code_type_table
[i
].item
)
131 if( metadata_code_type_table
[i
].length
== 0 )
132 return LSMASH_ERR_NAMELESS
;
133 isom_data_t
*data
= isom_add_metadata( file
, item
, meaning
, name
);
135 return LSMASH_ERR_NAMELESS
;
136 if( item
== ITUNES_METADATA_ITEM_PREDEFINED_GENRE
)
137 data
->type_code
= ITUNES_METADATA_SUBTYPE_IMPLICIT
;
139 data
->type_code
= ITUNES_METADATA_SUBTYPE_INTEGER
;
140 data
->value_length
= metadata_code_type_table
[i
].length
;
142 for( i
= 0; i
< data
->value_length
; i
++ )
144 int shift
= (data
->value_length
- i
- 1) * 8;
145 temp
[i
] = (value
.integer
>> shift
) & 0xff;
147 data
->value
= lsmash_memdup( temp
, data
->value_length
);
150 isom_ilst_t
*ilst
= file
->moov
->udta
->meta
->ilst
;
151 isom_remove_box_by_itself( ilst
->metaitem_list
.tail
->data
);
152 return LSMASH_ERR_MEMORY_ALLOC
;
157 static int isom_set_itunes_metadata_boolean( lsmash_file_t
*file
,
158 lsmash_itunes_metadata_item item
,
159 lsmash_itunes_metadata_value_t value
, char *meaning
, char *name
)
161 isom_data_t
*data
= isom_add_metadata( file
, item
, meaning
, name
);
163 return LSMASH_ERR_NAMELESS
;
164 data
->type_code
= ITUNES_METADATA_SUBTYPE_INTEGER
;
165 data
->value_length
= 1;
166 uint8_t temp
= (uint8_t)value
.boolean
;
167 data
->value
= lsmash_memdup( &temp
, 1 );
170 isom_ilst_t
*ilst
= file
->moov
->udta
->meta
->ilst
;
171 isom_remove_box_by_itself( ilst
->metaitem_list
.tail
->data
);
172 return LSMASH_ERR_MEMORY_ALLOC
;
177 static int isom_set_itunes_metadata_binary( lsmash_file_t
*file
,
178 lsmash_itunes_metadata_item item
,
179 lsmash_itunes_metadata_value_t value
, char *meaning
, char *name
)
181 isom_data_t
*data
= isom_add_metadata( file
, item
, meaning
, name
);
183 return LSMASH_ERR_NAMELESS
;
186 case ITUNES_METADATA_ITEM_COVER_ART
:
187 if( value
.binary
.subtype
!= ITUNES_METADATA_SUBTYPE_JPEG
188 && value
.binary
.subtype
!= ITUNES_METADATA_SUBTYPE_PNG
189 && value
.binary
.subtype
!= ITUNES_METADATA_SUBTYPE_BMP
)
190 return LSMASH_ERR_FUNCTION_PARAM
;
192 case ITUNES_METADATA_ITEM_DISC_NUMBER
:
193 case ITUNES_METADATA_ITEM_TRACK_NUMBER
:
194 value
.binary
.subtype
= ITUNES_METADATA_SUBTYPE_IMPLICIT
;
199 switch( value
.binary
.subtype
)
201 case ITUNES_METADATA_SUBTYPE_UUID
:
202 if( value
.binary
.size
!= 16 )
203 return LSMASH_ERR_FUNCTION_PARAM
;
205 case ITUNES_METADATA_SUBTYPE_DURATION
:
206 if( value
.binary
.size
!= 4 )
207 return LSMASH_ERR_FUNCTION_PARAM
;
209 case ITUNES_METADATA_SUBTYPE_TIME
:
210 if( value
.binary
.size
!= 4 && value
.binary
.size
!= 8 )
211 return LSMASH_ERR_FUNCTION_PARAM
;
213 case ITUNES_METADATA_SUBTYPE_INTEGER
:
214 if( value
.binary
.size
!= 1 && value
.binary
.size
!= 2
215 && value
.binary
.size
!= 3 && value
.binary
.size
!= 4
216 && value
.binary
.size
!= 8 )
217 return LSMASH_ERR_FUNCTION_PARAM
;
219 case ITUNES_METADATA_SUBTYPE_RIAAPA
:
220 if( value
.binary
.size
!= 1 )
221 return LSMASH_ERR_FUNCTION_PARAM
;
226 data
->type_code
= value
.binary
.subtype
;
227 data
->value_length
= value
.binary
.size
;
228 data
->value
= lsmash_memdup( value
.binary
.data
, value
.binary
.size
);
231 isom_ilst_t
*ilst
= file
->moov
->udta
->meta
->ilst
;
232 isom_remove_box_by_itself( ilst
->metaitem_list
.tail
->data
);
233 return LSMASH_ERR_MEMORY_ALLOC
;
238 int lsmash_set_itunes_metadata( lsmash_root_t
*root
, lsmash_itunes_metadata_t metadata
)
240 if( isom_check_initializer_present( root
) < 0 )
241 return LSMASH_ERR_FUNCTION_PARAM
;
244 lsmash_itunes_metadata_item item
;
245 int (*func_set_itunes_metadata
)( lsmash_file_t
*, lsmash_itunes_metadata_item
, lsmash_itunes_metadata_value_t
, char *, char * );
246 } itunes_metadata_function_mapping
[] =
248 { ITUNES_METADATA_ITEM_ALBUM_NAME
, isom_set_itunes_metadata_string
},
249 { ITUNES_METADATA_ITEM_ARTIST
, isom_set_itunes_metadata_string
},
250 { ITUNES_METADATA_ITEM_USER_COMMENT
, isom_set_itunes_metadata_string
},
251 { ITUNES_METADATA_ITEM_RELEASE_DATE
, isom_set_itunes_metadata_string
},
252 { ITUNES_METADATA_ITEM_ENCODED_BY
, isom_set_itunes_metadata_string
},
253 { ITUNES_METADATA_ITEM_USER_GENRE
, isom_set_itunes_metadata_string
},
254 { ITUNES_METADATA_ITEM_GROUPING
, isom_set_itunes_metadata_string
},
255 { ITUNES_METADATA_ITEM_LYRICS
, isom_set_itunes_metadata_string
},
256 { ITUNES_METADATA_ITEM_TITLE
, isom_set_itunes_metadata_string
},
257 { ITUNES_METADATA_ITEM_TRACK_SUBTITLE
, isom_set_itunes_metadata_string
},
258 { ITUNES_METADATA_ITEM_ENCODING_TOOL
, isom_set_itunes_metadata_string
},
259 { ITUNES_METADATA_ITEM_COMPOSER
, isom_set_itunes_metadata_string
},
260 { ITUNES_METADATA_ITEM_ALBUM_ARTIST
, isom_set_itunes_metadata_string
},
261 { ITUNES_METADATA_ITEM_PODCAST_CATEGORY
, isom_set_itunes_metadata_string
},
262 { ITUNES_METADATA_ITEM_COPYRIGHT
, isom_set_itunes_metadata_string
},
263 { ITUNES_METADATA_ITEM_DESCRIPTION
, isom_set_itunes_metadata_string
},
264 { ITUNES_METADATA_ITEM_GROUPING_DRAFT
, isom_set_itunes_metadata_string
},
265 { ITUNES_METADATA_ITEM_PODCAST_KEYWORD
, isom_set_itunes_metadata_string
},
266 { ITUNES_METADATA_ITEM_LONG_DESCRIPTION
, isom_set_itunes_metadata_string
},
267 { ITUNES_METADATA_ITEM_PURCHASE_DATE
, isom_set_itunes_metadata_string
},
268 { ITUNES_METADATA_ITEM_TV_EPISODE_ID
, isom_set_itunes_metadata_string
},
269 { ITUNES_METADATA_ITEM_TV_NETWORK
, isom_set_itunes_metadata_string
},
270 { ITUNES_METADATA_ITEM_TV_SHOW_NAME
, isom_set_itunes_metadata_string
},
271 { ITUNES_METADATA_ITEM_ITUNES_PURCHASE_ACCOUNT_ID
, isom_set_itunes_metadata_string
},
272 { ITUNES_METADATA_ITEM_ITUNES_SORT_ALBUM
, isom_set_itunes_metadata_string
},
273 { ITUNES_METADATA_ITEM_ITUNES_SORT_ARTIST
, isom_set_itunes_metadata_string
},
274 { ITUNES_METADATA_ITEM_ITUNES_SORT_ALBUM_ARTIST
, isom_set_itunes_metadata_string
},
275 { ITUNES_METADATA_ITEM_ITUNES_SORT_COMPOSER
, isom_set_itunes_metadata_string
},
276 { ITUNES_METADATA_ITEM_ITUNES_SORT_NAME
, isom_set_itunes_metadata_string
},
277 { ITUNES_METADATA_ITEM_ITUNES_SORT_SHOW
, isom_set_itunes_metadata_string
},
278 { ITUNES_METADATA_ITEM_EPISODE_GLOBAL_ID
, isom_set_itunes_metadata_integer
},
279 { ITUNES_METADATA_ITEM_PREDEFINED_GENRE
, isom_set_itunes_metadata_integer
},
280 { ITUNES_METADATA_ITEM_CONTENT_RATING
, isom_set_itunes_metadata_integer
},
281 { ITUNES_METADATA_ITEM_MEDIA_TYPE
, isom_set_itunes_metadata_integer
},
282 { ITUNES_METADATA_ITEM_BEATS_PER_MINUTE
, isom_set_itunes_metadata_integer
},
283 { ITUNES_METADATA_ITEM_TV_EPISODE
, isom_set_itunes_metadata_integer
},
284 { ITUNES_METADATA_ITEM_TV_SEASON
, isom_set_itunes_metadata_integer
},
285 { ITUNES_METADATA_ITEM_ITUNES_ACCOUNT_TYPE
, isom_set_itunes_metadata_integer
},
286 { ITUNES_METADATA_ITEM_ITUNES_ARTIST_ID
, isom_set_itunes_metadata_integer
},
287 { ITUNES_METADATA_ITEM_ITUNES_COMPOSER_ID
, isom_set_itunes_metadata_integer
},
288 { ITUNES_METADATA_ITEM_ITUNES_CATALOG_ID
, isom_set_itunes_metadata_integer
},
289 { ITUNES_METADATA_ITEM_ITUNES_TV_GENRE_ID
, isom_set_itunes_metadata_integer
},
290 { ITUNES_METADATA_ITEM_ITUNES_PLAYLIST_ID
, isom_set_itunes_metadata_integer
},
291 { ITUNES_METADATA_ITEM_ITUNES_COUNTRY_CODE
, isom_set_itunes_metadata_integer
},
292 { ITUNES_METADATA_ITEM_DISC_COMPILATION
, isom_set_itunes_metadata_boolean
},
293 { ITUNES_METADATA_ITEM_HIGH_DEFINITION_VIDEO
, isom_set_itunes_metadata_boolean
},
294 { ITUNES_METADATA_ITEM_PODCAST
, isom_set_itunes_metadata_boolean
},
295 { ITUNES_METADATA_ITEM_GAPLESS_PLAYBACK
, isom_set_itunes_metadata_boolean
},
296 { ITUNES_METADATA_ITEM_COVER_ART
, isom_set_itunes_metadata_binary
},
297 { ITUNES_METADATA_ITEM_DISC_NUMBER
, isom_set_itunes_metadata_binary
},
298 { ITUNES_METADATA_ITEM_TRACK_NUMBER
, isom_set_itunes_metadata_binary
},
301 lsmash_file_t
*file
= root
->file
;
302 for( int i
= 0; itunes_metadata_function_mapping
[i
].func_set_itunes_metadata
; i
++ )
303 if( metadata
.item
== itunes_metadata_function_mapping
[i
].item
)
304 return itunes_metadata_function_mapping
[i
].func_set_itunes_metadata( file
, metadata
.item
, metadata
.value
, metadata
.meaning
, metadata
.name
);
305 if( metadata
.item
== ITUNES_METADATA_ITEM_CUSTOM
)
306 switch( metadata
.type
)
308 case ITUNES_METADATA_TYPE_STRING
:
309 return isom_set_itunes_metadata_string( file
, metadata
.item
, metadata
.value
, metadata
.meaning
, metadata
.name
);
310 case ITUNES_METADATA_TYPE_INTEGER
:
311 return isom_set_itunes_metadata_integer( file
, metadata
.item
, metadata
.value
, metadata
.meaning
, metadata
.name
);
312 case ITUNES_METADATA_TYPE_BOOLEAN
:
313 return isom_set_itunes_metadata_boolean( file
, metadata
.item
, metadata
.value
, metadata
.meaning
, metadata
.name
);
314 case ITUNES_METADATA_TYPE_BINARY
:
315 return isom_set_itunes_metadata_binary( file
, metadata
.item
, metadata
.value
, metadata
.meaning
, metadata
.name
);
319 return LSMASH_ERR_FUNCTION_PARAM
;
322 static lsmash_itunes_metadata_type
isom_get_itunes_metadata_type( lsmash_itunes_metadata_item item
)
326 lsmash_itunes_metadata_item item
;
327 lsmash_itunes_metadata_type type
;
328 } itunes_metadata_item_type_mapping
[] =
330 { ITUNES_METADATA_ITEM_ALBUM_NAME
, ITUNES_METADATA_TYPE_STRING
},
331 { ITUNES_METADATA_ITEM_ARTIST
, ITUNES_METADATA_TYPE_STRING
},
332 { ITUNES_METADATA_ITEM_USER_COMMENT
, ITUNES_METADATA_TYPE_STRING
},
333 { ITUNES_METADATA_ITEM_RELEASE_DATE
, ITUNES_METADATA_TYPE_STRING
},
334 { ITUNES_METADATA_ITEM_ENCODED_BY
, ITUNES_METADATA_TYPE_STRING
},
335 { ITUNES_METADATA_ITEM_USER_GENRE
, ITUNES_METADATA_TYPE_STRING
},
336 { ITUNES_METADATA_ITEM_GROUPING
, ITUNES_METADATA_TYPE_STRING
},
337 { ITUNES_METADATA_ITEM_LYRICS
, ITUNES_METADATA_TYPE_STRING
},
338 { ITUNES_METADATA_ITEM_TITLE
, ITUNES_METADATA_TYPE_STRING
},
339 { ITUNES_METADATA_ITEM_TRACK_SUBTITLE
, ITUNES_METADATA_TYPE_STRING
},
340 { ITUNES_METADATA_ITEM_ENCODING_TOOL
, ITUNES_METADATA_TYPE_STRING
},
341 { ITUNES_METADATA_ITEM_COMPOSER
, ITUNES_METADATA_TYPE_STRING
},
342 { ITUNES_METADATA_ITEM_ALBUM_ARTIST
, ITUNES_METADATA_TYPE_STRING
},
343 { ITUNES_METADATA_ITEM_PODCAST_CATEGORY
, ITUNES_METADATA_TYPE_STRING
},
344 { ITUNES_METADATA_ITEM_COPYRIGHT
, ITUNES_METADATA_TYPE_STRING
},
345 { ITUNES_METADATA_ITEM_DESCRIPTION
, ITUNES_METADATA_TYPE_STRING
},
346 { ITUNES_METADATA_ITEM_GROUPING_DRAFT
, ITUNES_METADATA_TYPE_STRING
},
347 { ITUNES_METADATA_ITEM_PODCAST_KEYWORD
, ITUNES_METADATA_TYPE_STRING
},
348 { ITUNES_METADATA_ITEM_LONG_DESCRIPTION
, ITUNES_METADATA_TYPE_STRING
},
349 { ITUNES_METADATA_ITEM_PURCHASE_DATE
, ITUNES_METADATA_TYPE_STRING
},
350 { ITUNES_METADATA_ITEM_TV_EPISODE_ID
, ITUNES_METADATA_TYPE_STRING
},
351 { ITUNES_METADATA_ITEM_TV_NETWORK
, ITUNES_METADATA_TYPE_STRING
},
352 { ITUNES_METADATA_ITEM_TV_SHOW_NAME
, ITUNES_METADATA_TYPE_STRING
},
353 { ITUNES_METADATA_ITEM_ITUNES_PURCHASE_ACCOUNT_ID
, ITUNES_METADATA_TYPE_STRING
},
354 { ITUNES_METADATA_ITEM_ITUNES_SORT_ALBUM
, ITUNES_METADATA_TYPE_STRING
},
355 { ITUNES_METADATA_ITEM_ITUNES_SORT_ARTIST
, ITUNES_METADATA_TYPE_STRING
},
356 { ITUNES_METADATA_ITEM_ITUNES_SORT_ALBUM_ARTIST
, ITUNES_METADATA_TYPE_STRING
},
357 { ITUNES_METADATA_ITEM_ITUNES_SORT_COMPOSER
, ITUNES_METADATA_TYPE_STRING
},
358 { ITUNES_METADATA_ITEM_ITUNES_SORT_NAME
, ITUNES_METADATA_TYPE_STRING
},
359 { ITUNES_METADATA_ITEM_ITUNES_SORT_SHOW
, ITUNES_METADATA_TYPE_STRING
},
360 { ITUNES_METADATA_ITEM_EPISODE_GLOBAL_ID
, ITUNES_METADATA_TYPE_INTEGER
},
361 { ITUNES_METADATA_ITEM_PREDEFINED_GENRE
, ITUNES_METADATA_TYPE_INTEGER
},
362 { ITUNES_METADATA_ITEM_CONTENT_RATING
, ITUNES_METADATA_TYPE_INTEGER
},
363 { ITUNES_METADATA_ITEM_MEDIA_TYPE
, ITUNES_METADATA_TYPE_INTEGER
},
364 { ITUNES_METADATA_ITEM_BEATS_PER_MINUTE
, ITUNES_METADATA_TYPE_INTEGER
},
365 { ITUNES_METADATA_ITEM_TV_EPISODE
, ITUNES_METADATA_TYPE_INTEGER
},
366 { ITUNES_METADATA_ITEM_TV_SEASON
, ITUNES_METADATA_TYPE_INTEGER
},
367 { ITUNES_METADATA_ITEM_ITUNES_ACCOUNT_TYPE
, ITUNES_METADATA_TYPE_INTEGER
},
368 { ITUNES_METADATA_ITEM_ITUNES_ARTIST_ID
, ITUNES_METADATA_TYPE_INTEGER
},
369 { ITUNES_METADATA_ITEM_ITUNES_COMPOSER_ID
, ITUNES_METADATA_TYPE_INTEGER
},
370 { ITUNES_METADATA_ITEM_ITUNES_CATALOG_ID
, ITUNES_METADATA_TYPE_INTEGER
},
371 { ITUNES_METADATA_ITEM_ITUNES_TV_GENRE_ID
, ITUNES_METADATA_TYPE_INTEGER
},
372 { ITUNES_METADATA_ITEM_ITUNES_PLAYLIST_ID
, ITUNES_METADATA_TYPE_INTEGER
},
373 { ITUNES_METADATA_ITEM_ITUNES_COUNTRY_CODE
, ITUNES_METADATA_TYPE_INTEGER
},
374 { ITUNES_METADATA_ITEM_DISC_COMPILATION
, ITUNES_METADATA_TYPE_BOOLEAN
},
375 { ITUNES_METADATA_ITEM_HIGH_DEFINITION_VIDEO
, ITUNES_METADATA_TYPE_BOOLEAN
},
376 { ITUNES_METADATA_ITEM_PODCAST
, ITUNES_METADATA_TYPE_BOOLEAN
},
377 { ITUNES_METADATA_ITEM_GAPLESS_PLAYBACK
, ITUNES_METADATA_TYPE_BOOLEAN
},
378 { ITUNES_METADATA_ITEM_COVER_ART
, ITUNES_METADATA_TYPE_BINARY
},
379 { ITUNES_METADATA_ITEM_DISC_NUMBER
, ITUNES_METADATA_TYPE_BINARY
},
380 { ITUNES_METADATA_ITEM_TRACK_NUMBER
, ITUNES_METADATA_TYPE_BINARY
},
381 { 0, ITUNES_METADATA_TYPE_NONE
}
383 for( int i
= 0; itunes_metadata_item_type_mapping
[i
].type
!= ITUNES_METADATA_TYPE_NONE
; i
++ )
384 if( item
== itunes_metadata_item_type_mapping
[i
].item
)
385 return itunes_metadata_item_type_mapping
[i
].type
;
386 return ITUNES_METADATA_TYPE_NONE
;
389 int lsmash_get_itunes_metadata( lsmash_root_t
*root
, uint32_t metadata_number
, lsmash_itunes_metadata_t
*metadata
)
391 if( isom_check_initializer_present( root
) < 0 || !metadata
)
392 return LSMASH_ERR_FUNCTION_PARAM
;
393 lsmash_file_t
*file
= root
->file
->initializer
;
396 || !file
->moov
->udta
->meta
397 || !file
->moov
->udta
->meta
->ilst
)
398 return LSMASH_ERR_NAMELESS
;
399 isom_ilst_t
*ilst
= file
->moov
->udta
->meta
->ilst
;
400 isom_metaitem_t
*metaitem
= (isom_metaitem_t
*)lsmash_get_entry_data( &ilst
->metaitem_list
, metadata_number
);
401 if( !metaitem
|| !metaitem
->data
|| !metaitem
->data
->value
|| metaitem
->data
->value_length
== 0 )
402 return LSMASH_ERR_NAMELESS
;
404 metadata
->item
= metaitem
->type
.fourcc
;
406 metadata
->type
= isom_get_itunes_metadata_type( metadata
->item
);
408 int err
= LSMASH_ERR_MEMORY_ALLOC
;
409 isom_mean_t
*mean
= metaitem
->mean
;
412 uint8_t *temp
= lsmash_malloc( mean
->meaning_string_length
+ 1 );
415 memcpy( temp
, mean
->meaning_string
, mean
->meaning_string_length
);
416 temp
[ mean
->meaning_string_length
] = 0;
417 metadata
->meaning
= (char *)temp
;
420 metadata
->meaning
= NULL
;
422 isom_name_t
*name
= metaitem
->name
;
425 uint8_t *temp
= lsmash_malloc( name
->name_length
+ 1 );
428 memcpy( temp
, name
->name
, name
->name_length
);
429 temp
[ name
->name_length
] = 0;
430 metadata
->name
= (char *)temp
;
433 metadata
->name
= NULL
;
435 isom_data_t
*data
= metaitem
->data
;
436 switch( metadata
->type
)
438 case ITUNES_METADATA_TYPE_STRING
:
440 uint8_t *temp
= lsmash_malloc( data
->value_length
+ 1 );
443 memcpy( temp
, data
->value
, data
->value_length
);
444 temp
[ data
->value_length
] = 0;
445 metadata
->value
.string
= (char *)temp
;
448 case ITUNES_METADATA_TYPE_INTEGER
:
449 if( data
->value_length
> 8 )
451 err
= LSMASH_ERR_INVALID_DATA
;
454 metadata
->value
.integer
= 0;
455 for( uint32_t i
= 0; i
< data
->value_length
; i
++ )
457 int shift
= (data
->value_length
- i
- 1) * 8;
458 metadata
->value
.integer
|= (uint64_t)data
->value
[i
] << shift
;
461 case ITUNES_METADATA_TYPE_BOOLEAN
:
462 metadata
->value
.boolean
= !!data
->value
[0];
465 metadata
->type
= ITUNES_METADATA_TYPE_BINARY
;
466 metadata
->value
.binary
.subtype
= data
->type_code
;
467 metadata
->value
.binary
.size
= data
->value_length
;
468 metadata
->value
.binary
.data
= lsmash_memdup( data
->value
, data
->value_length
);
469 if( !metadata
->value
.binary
.data
)
475 lsmash_freep( &metadata
->meaning
);
476 lsmash_freep( &metadata
->name
);
480 uint32_t lsmash_count_itunes_metadata( lsmash_root_t
*root
)
482 if( isom_check_initializer_present( root
) < 0
483 || !root
->file
->initializer
->moov
484 || !root
->file
->initializer
->moov
->udta
485 || !root
->file
->initializer
->moov
->udta
->meta
486 || !root
->file
->initializer
->moov
->udta
->meta
->ilst
)
488 return root
->file
->initializer
->moov
->udta
->meta
->ilst
->metaitem_list
.entry_count
;
491 void lsmash_cleanup_itunes_metadata( lsmash_itunes_metadata_t
*metadata
)
495 lsmash_freep( &metadata
->meaning
);
496 lsmash_freep( &metadata
->name
);
497 if( metadata
->type
== ITUNES_METADATA_TYPE_STRING
)
498 lsmash_freep( &metadata
->value
.string
);
499 else if( metadata
->type
== ITUNES_METADATA_TYPE_BINARY
)
500 lsmash_freep( &metadata
->value
.binary
.data
);