/
main.cpp
2956 lines (2593 loc) · 150 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//==================================================================//
/*
AtomicParsley - main.cpp
AtomicParsley is GPL software; you can freely distribute,
redistribute, modify & use under the terms of the GNU General
Public License; either version 2 or its successor.
AtomicParsley is distributed under the GPL "AS IS", without
any warranty; without the implied warranty of merchantability
or fitness for either an expressed or implied particular purpose.
Please see the included GNU General Public License (GPL) for
your rights and further details; see the file COPYING. If you
cannot, write to the Free Software Foundation, 59 Temple Place
Suite 330, Boston, MA 02111-1307, USA. Or www.fsf.org
Copyright ©2005-2007 puck_lock
with contributions from others; see the CREDITS file
----------------------
Code Contributions by:
* Mike Brancato - Debian patches & build support
* Brian Story - porting getopt & native Win32 patches
*/
//==================================================================//
#include "AtomicParsley.h"
// define one-letter cli options for
#define OPT_HELP 'h'
#define OPT_TEST 'T'
#define OPT_ShowTextData 't'
#define OPT_ExtractPix 'E'
#define OPT_ExtractPixToPath 'e'
#define Meta_artist 'a'
#define Meta_songtitle 's'
#define Meta_album 'b'
#define Meta_tracknum 'k'
#define Meta_disknum 'd'
#define Meta_genre 'g'
#define Meta_comment 'c'
#define Meta_year 'y'
#define Meta_lyrics 'l'
#define Meta_composer 'w'
#define Meta_copyright 'x'
#define Meta_grouping 'G'
#define Meta_album_artist 'A'
#define Meta_compilation 'C'
#define Meta_hdvideo 'O'
#define Meta_BPM 'B'
#define Meta_artwork 'r'
#define Meta_advisory 'V'
#define Meta_stik 'S'
#define Meta_description 'p'
#define Meta_Rating 0xCB
#define Meta_longdescription 'j'
#define Meta_TV_Network 'n'
#define Meta_TV_ShowName 'H'
#define Meta_TV_EpisodeNumber 'N'
#define Meta_TV_SeasonNumber 'U'
#define Meta_TV_Episode 'I'
#define Meta_podcastFlag 'f'
#define Meta_category 'q'
#define Meta_keyword 'K'
#define Meta_podcast_URL 'L'
#define Meta_podcast_GUID 'J'
#define Meta_PurchaseDate 'D'
#define Meta_apID 'Y'
#define Meta_cnID 0xC0
#define Meta_xID 0xC3
#define Meta_EncodingTool 0xB7
#define Meta_EncodedBy 0xC1
#define Meta_PlayGapless 0xBA
#define Meta_SortOrder 0xBF
#define Meta_ReverseDNS_Form 'M'
#define Meta_rDNS_rating 0xBB
#define Meta_StandardDate 'Z'
#define Meta_URL 'u'
#define Meta_Information 'i'
#define Meta_uuid 'z'
#define Opt_Extract_all_uuids 0xB8
#define Opt_Extract_a_uuid 0xB9
#define Opt_Ipod_AVC_uuid 0xBE
#define Metadata_Purge 'P'
#define UserData_Purge 'X'
#define foobar_purge '.'
#define Meta_dump 'Q'
#define Manual_atom_removal 'R'
#define Opt_FreeFree 'F'
#define OPT_OutputFile 'o'
#define OPT_NoOptimize 0xBD
#define OPT_OverWrite 'W'
#if defined (_WIN32)
#define OPT_PreserveTimeStamps 0xCA
#endif
#define ISO_Copyright 0xAA
#define _3GP_Title 0xAB
#define _3GP_Author 0xAC
#define _3GP_Performer 0xAD
#define _3GP_Genre 0xAE
#define _3GP_Description 0xAF
#define _3GP_Copyright 0xB0
#define _3GP_Album 0xB1
#define _3GP_Year 0xB2
#define _3GP_Rating 0xB3
#define _3GP_Classification 0xB4
#define _3GP_Keyword 0xB5
#define _3GP_Location 0xB6
#define Meta_ID3v2Tag 0xBC
char *output_file;
int total_args;
static void kill_signal ( int sig );
static void kill_signal (int sig) {
exit(0);
}
//less than 80 (max 78) char wide, giving a general (concise) overview
static const char* shortHelp_text =
"\n"
"AtomicParlsey sets metadata into MPEG-4 files & derivatives supporting 3 tag\n"
" schemes: iTunes-style, 3GPP assets & ISO defined copyright notifications.\n"
"\n"
"AtomicParlsey quick help for setting iTunes-style metadata into MPEG-4 files.\n"
"\n"
"General usage examples:\n"
" AtomicParsley /path/to.mp4 -T 1\n"
" AtomicParsley /path/to.mp4 -t +\n"
" AtomicParsley /path/to.mp4 --artist \"Me\" --artwork /path/to/art.jpg\n"
" Atomicparsley /path/to.mp4 --albumArtist \"You\" --podcastFlag true\n"
" Atomicparsley /path/to.mp4 --stik \"TV Show\" --advisory explicit\n"
"\n"
"Getting information about the file & tags:\n"
" -T --test Test file for mpeg4-ishness & print atom tree\n"
" -t --textdata Prints tags embedded within the file\n"
" -E --extractPix Extracts pix to the same folder as the mpeg-4 file\n"
"\n"
"Setting iTunes-style metadata tags\n"
" --artist (string) Set the artist tag\n"
" --title (string) Set the title tag\n"
" --album (string) Set the album tag\n"
" --genre (string) Genre tag (see --longhelp for more info)\n"
" --tracknum (num)[/tot] Track number (or track number/total tracks)\n"
" --disk (num)[/tot] Disk number (or disk number/total disks)\n"
" --comment (string) Set the comment tag\n"
" --year (num|UTC) Year tag (see --longhelp for \"Release Date\")\n"
" --lyrics (string) Set lyrics (not subject to 256 byte limit)\n"
" --composer (string) Set the composer tag\n"
" --copyright (string) Set the copyright tag\n"
" --grouping (string) Set the grouping tag\n"
" --artwork (/path) Set a piece of artwork (jpeg or png only)\n"
" --bpm (number) Set the tempo/bpm\n"
" --albumArtist (string) Set the album artist tag\n"
" --compilation (boolean) Set the compilation flag (true or false)\n"
" --hdvideo (boolean) Set the hdvideo flag (true or false)\n"
" --advisory (string*) Content advisory (*values: 'clean', 'explicit')\n"
" --stik (string*) Sets the iTunes \"stik\" atom (see --longhelp)\n"
" --description (string) Set the description tag\n"
" --longdesc (string) Set the long description tag\n"
" --TVNetwork (string) Set the TV Network name\n"
" --TVShowName (string) Set the TV Show name\n"
" --TVEpisode (string) Set the TV episode/production code\n"
" --TVSeasonNum (number) Set the TV Season number\n"
" --TVEpisodeNum (number) Set the TV Episode number\n"
" --podcastFlag (boolean) Set the podcast flag (true or false)\n"
" --category (string) Sets the podcast category\n"
" --keyword (string) Sets the podcast keyword\n"
" --podcastURL (URL) Set the podcast feed URL\n"
" --podcastGUID (URL) Set the episode's URL tag\n"
" --purchaseDate (UTC) Set time of purchase\n"
" --encodingTool (string) Set the name of the encoder\n"
" --encodedBy (string) Set the name of the Person/company who encoded the file\n"
" --apID (string) Set the Account Name\n"
" --cnID (number) Set the iTunes Catalog ID (see --longhelp)\n"
" --xid (string) Set the vendor-supplied iTunes xID (see --longhelp)\n"
" --gapless (boolean) Set the gapless playback flag\n"
" --contentRating (string*) Set tv/mpaa rating (see -rDNS-help)\n"
"\n"
"Deleting tags\n"
" Set the value to \"\": --artist \"\" --stik \"\" --bpm \"\"\n"
" To delete (all) artwork: --artwork REMOVE_ALL\n"
" manually removal: --manualAtomRemove \"moov.udta.meta.ilst.ATOM\"\n"
"\n"
"More detailed iTunes help is available with AtomicParsley --longhelp\n"
"Setting reverse DNS forms for iTunes files: see --reverseDNS-help\n"
"Setting 3gp assets into 3GPP & derivative files: see --3gp-help\n"
"Setting copyright notices for all files: see --ISO-help\n"
"For file-level options & padding info: see --file-help\n"
"Setting custom private tag extensions: see --uuid-help\n"
"Setting ID3 tags onto mpeg-4 files: see --ID3-help\n"
"\n"
"----------------------------------------------------------------------"
;
//an expansive, verbose, unconstrained (about 112 char wide) detailing of options
static const char* longHelp_text =
"AtomicParsley help page for setting iTunes-style metadata into MPEG-4 files. \n"
" (3gp help available with AtomicParsley --3gp-help)\n"
" (ISO copyright help available with AtomicParsley --ISO-help)\n"
" (reverse DNS form help available with AtomicParsley --reverseDNS-help)\n"
"Usage: AtomicParsley [mp4FILE]... [OPTION]... [ARGUMENT]... [ [OPTION2]...[ARGUMENT2]...] \n"
"\n"
"example: AtomicParsley /path/to.mp4 -e ~/Desktop/pix\n"
"example: AtomicParsley /path/to.mp4 --podcastURL \"http://www.url.net\" --tracknum 45/356\n"
"example: AtomicParsley /path/to.mp4 --copyright \"\342\204\227 \302\251 2006\"\n"
"example: AtomicParsley /path/to.mp4 --year \"2006-07-27T14:00:43Z\" --purchaseDate timestamp\n"
"example: AtomicParsley /path/to.mp4 --sortOrder artist \"Mighty Dub Cats, The\n"
"------------------------------------------------------------------------------------------------\n"
" Extract any pictures in user data \"covr\" atoms to separate files. \n"
" --extractPix , -E Extract to same folder (basename derived from file).\n"
" --extractPixToPath , -e (/path/basename) Extract to specific path (numbers added to basename).\n"
" example: --e ~/Desktop/SomeText\n"
" gives: SomeText_artwork_1.jpg SomeText_artwork_2.png\n"
" Note: extension comes from embedded image file format\n"
"------------------------------------------------------------------------------------------------\n"
" Tag setting options:\n"
"\n"
" --artist , -a (str) Set the artist tag: \"moov.udta.meta.ilst.\302©ART.data\"\n"
" --title , -s (str) Set the title tag: \"moov.udta.meta.ilst.\302©nam.data\"\n"
" --album , -b (str) Set the album tag: \"moov.udta.meta.ilst.\302©alb.data\"\n"
" --genre , -g (str) Set the genre tag: \"\302©gen\" (custom) or \"gnre\" (standard).\n"
" see the standard list with \"AtomicParsley --genre-list\"\n"
" --tracknum , -k (num)[/tot] Set the track number (or track number & total tracks).\n"
" --disk , -d (num)[/tot] Set the disk number (or disk number & total disks).\n"
" --comment , -c (str) Set the comment tag: \"moov.udta.meta.ilst.\302©cmt.data\"\n"
" --year , -y (num|UTC) Set the year tag: \"moov.udta.meta.ilst.\302©day.data\"\n"
" set with UTC \"2006-09-11T09:00:00Z\" for Release Date\n"
" --lyrics , -l (str) Set the lyrics tag: \"moov.udta.meta.ilst.\302©lyr.data\"\n"
" --composer , -w (str) Set the composer tag: \"moov.udta.meta.ilst.\302©wrt.data\"\n"
" --copyright , -x (str) Set the copyright tag: \"moov.udta.meta.ilst.cprt.data\"\n"
" --grouping , -G (str) Set the grouping tag: \"moov.udta.meta.ilst.\302©grp.data\"\n"
" --artwork , -A (/path) Set a piece of artwork (jpeg or png) on \"covr.data\"\n"
" Note: multiple pieces are allowed with more --artwork args\n"
" --bpm , -B (num) Set the tempo/bpm tag: \"moov.udta.meta.ilst.tmpo.data\"\n"
" --albumArtist , -A (str) Set the album artist tag: \"moov.udta.meta.ilst.aART.data\"\n"
" --compilation , -C (bool) Sets the \"cpil\" atom (true or false to delete the atom)\n"
" --hdvideo , -V (bool) Sets the \"hdvd\" atom (true or false to delete the atom)\n"
" --advisory , -y (1of3) Sets the iTunes lyrics advisory ('remove', 'clean', 'explicit') \n"
" --stik , -S (1of7) Sets the iTunes \"stik\" atom (--stik \"remove\" to delete) \n"
" \"Movie\", \"Normal\", \"TV Show\" .... others: \n"
" see the full list with \"AtomicParsley --stik-list\"\n"
" or set in an integer value with --stik value=(num)\n"
" Note: --stik Audiobook will change file extension to '.m4b'\n"
" --description , -p (str) Sets the description on the \"desc\" atom\n"
" --Rating , (str) Sets the Rating on the \"rate\" atom\n"
" --longdesc , -j (str) Sets the long description on the \"ldes\" atom\n"
" --TVNetwork , -n (str) Sets the TV Network name on the \"tvnn\" atom\n"
" --TVShowName , -H (str) Sets the TV Show name on the \"tvsh\" atom\n"
" --TVEpisode , -I (str) Sets the TV Episode on \"tven\":\"209\", but its a string: \"209 Part 1\"\n"
" --TVSeasonNum , -U (num) Sets the TV Season number on the \"tvsn\" atom\n"
" --TVEpisodeNum , -N (num) Sets the TV Episode number on the \"tves\" atom\n"
" --podcastFlag , -f (bool) Sets the podcast flag (values are \"true\" or \"false\")\n"
" --category , -q (str) Sets the podcast category; typically a duplicate of its genre\n"
" --keyword , -K (str) Sets the podcast keyword; invisible to MacOSX Spotlight\n"
" --podcastURL , -L (URL) Set the podcast feed URL on the \"purl\" atom\n"
" --podcastGUID , -J (URL) Set the episode's URL tag on the \"egid\" atom\n"
" --purchaseDate , -D (UTC) Set Universal Coordinated Time of purchase on a \"purd\" atom\n"
" (use \"timestamp\" to set UTC to now; can be akin to id3v2 TDTG tag)\n"
" --encodingTool , (str) Set the name of the encoder on the \"\302©too\" atom\n"
" --encodedBy , (str) Set the name of the Person/company who encoded the file on the \"\302©enc\" atom\n"
" --apID , -Y (str) Set the name of the Account Name on the \"apID\" atom\n"
" --cnID , (num) Set iTunes Catalog ID, used for combining SD and HD encodes in iTunes on the \"cnID\" atom\n"
" (To combine you must set \"hdvd\" atom on one file and must have same \"stik\" on both file)\n"
" (Must not use \"stik\" of value Movie(0), use Short Film(9))\n"
" (A bad idea for numbers is from http://www.imdb.com/ listings)\n"
" (A better idea for numbers is from the iTunes Store URL)\n"
" --xid , (str) Set iTunes vendor-supplied xID, used to allow iTunes LPs and iTunes Extras to interact \n"
" with other content in your iTunes Library\n"
" --gapless , (bool) Sets the gapless playback flag for a track in a gapless album\n"
" --sortOrder (type) (str) Sets the sort order string for that type of tag.\n"
" (available types are: \"name\", \"artist\", \"albumartist\",\n"
" \"album\", \"composer\", \"show\")\n"
"\n"
"NOTE: Except for artwork, only 1 of each tag is allowed; artwork allows multiple pieces.\n"
"NOTE: Tags that carry text(str) have a limit of 255 utf8 characters;\n"
"however lyrics and long descriptions have no limit.\n"
"------------------------------------------------------------------------------------------------\n"
" To delete a single atom, set the tag to null (except artwork):\n"
" --artist \"\" --lyrics \"\"\n"
" --artwork REMOVE_ALL \n"
" --metaEnema , -P Douches away every atom under \"moov.udta.meta.ilst\" \n"
" --foobar2000Enema , -2 Eliminates foobar2000's non-compliant so-out-o-spec tagging scheme\n"
" --manualAtomRemove \"some.atom.path\" where some.atom.path can be:\n"
" keys to using manualAtomRemove:\n"
" ilst.ATOM.data or ilst.ATOM target an iTunes-style metadata tag\n"
" ATOM:lang=foo target an atom with this language setting; like 3gp assets\n"
" ATOM.----.name:[foo] target a reverseDNS metadata tag; like iTunNORM\n"
" Note: these atoms show up with 'AP -t' as: Atom \"----\" [foo]\n"
" 'foo' is actually carried on the 'name' atom\n"
" ATOM[x] target an atom with an index other than 1; like trak[2]\n"
" ATOM.uuid=hex-hex-hex-hex targt a uuid atom with the uuid of hex string representation\n"
" examples:\n"
" moov.udta.meta.ilst.----.name:[iTunNORM] moov.trak[3].cprt:lang=urd\n"
" moov.trak[2].uuid=55534d54-21d2-4fce-bb88-695cfac9c740\n"
"------------------------------------------------------------------------------------------------\n"
#if defined (DARWIN_PLATFORM)
" Environmental Variables (affecting picture placement)\n"
"\n"
" set PIC_OPTIONS in your shell to set these flags; preferences are separated by colons (:)\n"
"\n"
" MaxDimensions=num (default: 0; unlimited); sets maximum pixel dimensions\n"
" DPI=num (default: 72); sets dpi\n"
" MaxKBytes=num (default: 0; unlimited); maximum kilobytes for file (jpeg only)\n"
" AddBothPix=bool (default: false); add original & converted pic (for archival purposes)\n"
" AllPixJPEG | AllPixPNG =bool (default: false); force conversion to a specific picture format\n"
" SquareUp (include to square images to largest dimension, allows an [ugly] 160x1200->1200x1200)\n"
" removeTempPix (include to delete temp pic files created when resizing images after tagging)\n"
" ForceHeight=num (must also specify width, below) force image pixel height\n"
" ForceWidth=num (must also specify height, above) force image pixel width\n"
"\n"
" Examples: (bash-style)\n"
" export PIC_OPTIONS=\"MaxDimensions=400:DPI=72:MaxKBytes=100:AddBothPix=true:AllPixJPEG=true\"\n"
" export PIC_OPTIONS=\"SquareUp:removeTempPix\"\n"
" export PIC_OPTIONS=\"ForceHeight=999:ForceWidth=333:removeTempPix\"\n"
"------------------------------------------------------------------------------------------------\n"
#endif
;
static const char* fileLevelHelp_text =
"AtomicParsley help page for general & file level options.\n"
#if defined (_WIN32)
" Note: you can change the input/output behavior to raw 8-bit utf8 if the program name\n"
" is appended with \"-utf8\". AtomicParsley-utf8.exe will have problems with files/\n"
" folders with unicode characters in given paths.\n"
"\n"
#endif
"------------------------------------------------------------------------------------------------\n"
" Atom reading services:\n"
"\n"
" --test , -T Tests file to see if its a valid MPEG-4 file.\n"
" Prints out the hierarchical atom tree.\n"
" -T 1 Supplemental track level info with \"-T 1\"\n"
" -T +dates Track level with creation/modified dates\n"
"\n"
" --textdata , -t print user data text metadata relevant to brand (inc. # of any pics).\n"
" -t + show supplemental info like free space, available padding, user data\n"
" length & media data length\n"
" -t 1 show all textual metadata (disregards brands, shows track copyright)\n"
"\n"
" --brands show the major & minor brands for the file & available tagging schemes\n"
"\n"
"------------------------------------------------------------------------------------------------\n"
" File services:\n"
"\n"
" --freefree [num] , Remove \"free\" atoms which only act as filler in the file\n"
" ?(num)? - optional integer argument to delete 'free's to desired level\n"
"\n"
" NOTE 1: levels begin at level 1 aka file level.\n"
" NOTE 2: Level 0 (which doesn't exist) deletes level 1 atoms that pre-\n"
" cede 'moov' & don't serve as padding. Typically, such atoms\n"
" are created by libmp4ff or libmp4v2 as a byproduct of tagging.\n"
" NOTE 3: When padding falls below MIN_PAD (typically zero), a default\n"
" amount of padding (typically 2048 bytes) will be added. To\n"
" achieve absolutely 0 bytes 'free' space with --freefree, set\n"
" DEFAULT_PAD to 0 via the AP_PADDING mechanism (see below).\n"
"\n"
" --preventOptimizing Prevents reorganizing the file to have file metadata before media data.\n"
" iTunes/Quicktime have so far *always* placed metadata first; many 3rd\n"
" party utilities do not (preventing streaming to the web, AirTunes, iTV).\n"
" Used in conjunction with --overWrite, files with metadata at the end\n"
" (most ffmpeg produced files) can have their tags rapidly updated without\n"
" requiring a full rewrite. Note: this does not un-optimize a file.\n"
" Note: this option will be canceled out if used with the --freefree option\n"
"\n"
" --metaDump Dumps out 'moov.udta' metadata out to a new file next to original\n"
" (for diagnostic purposes, please remove artwork before sending)\n"
" --output , -o (/path) Specify the filename of tempfile (voids overWrite)\n"
" --overWrite , -W Writes to temp file; deletes original, renames temp to original\n"
" If possible, padding will be used to update without a full rewrite.\n"
"\n"
#if defined (_WIN32)
" --preserveTime Will overwrite the original file in place (--overWrite forced),\n"
" but will also keep the original file's timestamps intact.\n"
"\n"
#endif
" --DeepScan Parse areas of the file that are normally skipped (must be the 3rd arg)\n"
" --iPod-uuid (num) Place the ipod-required uuid for higher resolution avc video files\n"
" Currently, the only number used is 1200 - the maximum number of macro-\n"
" blocks allowed by the higher resolution iPod setting.\n"
" NOTE: this requires the \"--DeepScan\" option as the 3rd cli argument\n"
" NOTE2: only works on the first avc video track, not all avc tracks\n"
"\n"
"Examples: \n"
" --freefree 0 (deletes all top-level non-padding atoms preceding 'mooov') \n"
" --freefree 1 (deletes all non-padding atoms at the top most level) \n"
" --output ~/Desktop/newfile.mp4\n"
" AP /path/to/file.m4v --DeepScan --iPod-uuid 1200\n"
"------------------------------------------------------------------------------------------------\n"
" Padding & 'free' atoms:\n"
"\n"
" A special type of atom called a 'free' atom is used for padding (all 'free' atoms contain NULL space).\n"
" When changes need to occur, these 'free' atom are used. They grows or shink, but the relative locations\n"
" of certain other atoms (stco/mdat) remain the same. If there is no 'free' space, a full rewrite will occur.\n"
" The locations of 'free' atom(s) that AP can use as padding must be follow 'moov.udta' & come before 'mdat'.\n"
" A 'free' preceding 'moov' or following 'mdat' won't be used as padding for example. \n"
"\n"
" Set the shell variable AP_PADDING with these values, separated by colons to alter padding behavior:\n"
"\n"
" DEFAULT_PADDING= - the amount of padding added if the minimum padding is non-existant in the file\n"
" default = 2048\n"
" MIN_PAD= - the minimum padding present before more padding will be added\n"
" default = 0\n"
" MAX_PAD= - the maximum allowable padding; excess padding will be eliminated\n"
" default = 5000\n"
"\n"
" If you use --freefree to eliminate 'free' atoms from the file, the DEFAULT_PADDING amount will still be\n"
" added to any newly written files. Set DEFAULT_PADDING=0 to prevent any 'free' padding added at rewrite.\n"
" You can set MIN_PAD to be assured that at least that amount of padding will be present - similarly,\n"
" MAX_PAD limits any excessive amount of padding. All 3 options will in all likelyhood produce a full\n"
" rewrite of the original file. Another case where a full rewrite will occur is when the original file\n"
" is not optimized and has 'mdat' preceding 'moov'.\n"
"\n"
#if defined (_WIN32)
"Examples:\n"
" c:> SET AP_PADDING=\"DEFAULT_PAD=0\" or c:> SET AP_PADDING=\"DEFAULT_PAD=3128\"\n"
" c:> SET AP_PADDING=\"DEFAULT_PAD=5128:MIN_PAD=200:MAX_PAD=6049\"\n"
#else
"Examples (bash style):\n"
" $ export AP_PADDING=\"DEFAULT_PAD=0\" or $ export AP_PADDING=\"DEFAULT_PAD=3128\"\n"
" $ export AP_PADDING=\"DEFAULT_PAD=5128:MIN_PAD=200:MAX_PAD=6049\"\n"
#endif
"\n"
"Note: while AtomicParsley is still in the beta stage, the original file will always remain untouched - \n"
" unless given the --overWrite flag when if possible, utilizing available padding to update tags\n"
" will be tried (falling back to a full rewrite if changes are greater than the found padding).\n"
"----------------------------------------------------------------------------------------------------\n"
" iTunes 7 & Gapless playback:\n"
"\n"
" iTunes 7 adds NULL space at the ends of files (filled with zeroes). It is possble this is how iTunes\n"
" implements gapless playback - perhaps not. In any event, with AtomicParsley you can choose to preserve\n"
" that NULL space, or you can eliminate its presence (typically around 2,000 bytes). The default behavior\n"
" is to preserve it - if it is present at all. You can choose to eliminate it by setting the environ-\n"
" mental preference for AP_PADDING to have DEFAULT_PAD=0\n"
"\n"
#if defined (_WIN32)
"Example:\n"
" c:> SET AP_PADDING=\"DEFAULT_PAD=0\"\n"
#else
"Example (bash style):\n"
" $ export AP_PADDING=\"DEFAULT_PAD=0\"\n"
#endif
"----------------------------------------------------------------------------------------------------\n"
;
//detailed options for 3gp branded files
static const char* _3gpHelp_text =
"AtomicParsley 3gp help page for setting 3GPP-style metadata.\n"
"----------------------------------------------------------------------------------------------------\n"
" 3GPP text tags can be encoded in either UTF-8 (default input encoding) or UTF-16 (converted from UTF-8)\n"
" Many 3GPP text tags can be set for a desired language by a 3-letter-lowercase code (default is \"eng\").\n"
" For tags that support the language attribute (all except year), more than one tag of the same name\n"
" (3 titles for example) differing in the language code is supported.\n"
"\n"
" iTunes-style metadata is not supported by the 3GPP TS 26.244 version 6.4.0 Release 6 specification.\n"
" 3GPP asset tags can be set at movie level or track level & are set in a different hierarchy: moov.udta \n"
" if at movie level (versus iTunes moov.udta.meta.ilst). Other 3rd party utilities may allow setting\n"
" iTunes-style metadata in 3gp files. When a 3gp file is detected (file extension doesn't matter), only\n"
" 3gp spec-compliant metadata will be read & written.\n"
"\n"
" Note1: there are a number of different 'brands' that 3GPP files come marked as. Some will not be \n"
" supported by AtomicParsley due simply to them being unknown and untested. You can compile your\n"
" own AtomicParsley to evaluate it by adding the hex code into the source of APar_IdentifyBrand.\n"
"\n"
" Note2: There are slight accuracy discrepancies in location's fixed point decimals set and retrieved.\n"
"\n"
" Note3: QuickTime Player can see a limited subset of these tags, but only in 1 language & there seems to\n"
" be an issue with not all unicode text displaying properly. This is an issue withing QuickTime -\n"
" the exact same text (in utf8) displays properly in an MPEG-4 file. Some languages can also display\n"
" more glyphs than others.\n"
"\n"
"----------------------------------------------------------------------------------------------------\n"
" Tag setting options (default user data area is movie level; default lang is 'eng'; default encoding is UTF8):\n"
" required arguments are in (parentheses); optional arguments are in [brackets]\n"
"\n"
" --3gp-title (str) [lang=3str] [UTF16] [area] ......... Set a 3gp media title tag\n"
" --3gp-author (str) [lang=3str] [UTF16] [area] ......... Set a 3gp author of the media tag\n"
" --3gp-performer (str) [lang=3str] [UTF16] [area] ......... Set a 3gp performer or artist tag\n"
" --3gp-genre (str) [lang=3str] [UTF16] [area] ......... Set a 3gp genre asset tag\n"
" --3gp-description (str) [lang=3str] [UTF16] [area] ......... Set a 3gp description or caption tag\n"
" --3gp-copyright (str) [lang=3str] [UTF16] [area] ......... Set a 3gp copyright notice tag*\n"
"\n"
" --3gp-album (str) [lang=3str] [UTF16] [trknum=int] [area] Set a 3gp album tag (& opt. tracknum)\n"
" --3gp-year (int) [area] ........................... Set a 3gp recording year tag (4 digit only)\n"
"\n"
" --3gp-rating (str) [entity=4str] [criteria=4str] [lang=3str] [UTF16] [area] Rating tag\n"
" --3gp-classification (str) [entity=4str] [index=int] [lang=3str] [UTF16] [area] Classification\n"
"\n"
" --3gp-keyword (str) [lang=3str] [UTF16] [area] Format of str: 'keywords=word1,word2,word3,word4'\n"
"\n"
" --3gp-location (str) [lang=3str] [UTF16] [area] Set a 3gp location tag (default: Central Park)\n"
" [longitude=fxd.pt] [latitude=fxd.pt] [altitude=fxd.pt]\n"
" [role=str] [body=str] [notes=str]\n"
" fxd.pt values are decimal coordinates (55.01209, 179.25W, 63)\n"
" 'role=' values: 'shooting location', 'real location', 'fictional location'\n"
" a negative value in coordinates will be seen as a cli flag\n"
" append 'S', 'W' or 'B': lat=55S, long=90.23W, alt=90.25B\n"
"\n"
" [area] can be \"movie\", \"track\" or \"track=num\" where 'num' is the number of the track. If not specificied,\n"
" assets will be placed at movie level. The \"track\" option sets the asset across all available tracks\n"
"\n"
"Note1: '4str' = a 4 letter string like \"PG13\"; 3str is a 3 letter string like \"eng\"; int is an integer\n"
"Note2: List all languages for '3str' with \"AtomicParsley --language-list (unknown languages become \"und\")\n"
"*Note3: The 3gp copyright asset can potentially be altered by using the --ISO-copyright setting.\n"
"----------------------------------------------------------------------------------------------------\n"
"Usage: AtomicParsley [3gpFILE] --option [argument] [optional_arguments] [ --option2 [argument2]...] \n"
"\n"
"example: AtomicParsley /path/to.3gp -t \n"
"example: AtomicParsley /path/to.3gp -T 1 \n"
"example: Atomicparsley /path/to.3gp --3gp-performer \"Enjoy Yourself\" lang=pol UTF16\n"
"example: Atomicparsley /path/to.3gp --3gp-year 2006 --3gp-album \"White Label\" track=8 lang=fra\n"
"example: Atomicparsley /path/to.3gp --3gp-album \"Cow Cod Soup For Everyone\" track=10 lang=car\n"
"\n"
"example: Atomicparsley /path/to.3gp --3gp-classification \"Poor Sport\" entity=\"PTA \" index=12 UTF16\n"
"example: Atomicparsley /path/to.3gp --3gp-keyword keywords=\"foo1,foo2,foo 3\" UTF16 --3gp-keyword \"\"\n"
"example: Atomicparsley /path/to.3gp --3gp-location 'Bethesda Terrace' latitude=40.77 longitude=73.98W \n"
" altitude=4.3B role='real' body=Earth notes='Underground'\n"
"\n"
"example: Atomicparsley /path/to.3gp --3gp-title \"I see London.\" --3gp-title \"Veo Madrid.\" lang=spa \n"
" --3gp-title \"Widze Warsawa.\" lang=pol\n"
"\n"
;
static const char* ISOHelp_text =
"AtomicParsley help page for setting ISO copyright notices at movie & track level.\n"
"----------------------------------------------------------------------------------------------------\n"
" The ISO specification allows for setting copyright in a number of places. This copyright atom is\n"
" independant of the iTunes-style --copyright tag that can be set. This ISO tag is identical to the\n"
" 3GP-style copyright. In fact, using --ISO-copyright can potentially overwrite the 3gp copyright\n"
" asset if set at movie level & given the same language to set the copyright on. This copyright\n"
" notice is the only metadata tag defined by the reference ISO 14496-12 specification.\n"
"\n"
" ISO copyright notices can be set at movie level, track level for a single track, or for all tracks.\n"
" Multiple copyright notices are allowed, but they must differ in the language setting. To see avail-\n"
" able languages use \"AtomicParsley --language-list\". Notices can be set in utf8 or utf16.\n"
"\n"
" --ISO-copyright (str) [movie|track|track=#] [lang=3str] [UTF16] Set a copyright notice\n"
" # in 'track=#' denotes the target track\n"
" 3str is the 3 letter ISO-639-2 language.\n"
" Brackets [] show optional parameters.\n"
" Defaults are: movie level, 'eng' in utf8.\n"
"\n"
"example: AtomicParsley /path/file.mp4 -t 1 Note: the only way to see all contents is with -t 1 \n"
"example: AtomicParsley /path/file.mp4 --ISO-copyright \"Sample\"\n"
"example: AtomicParsley /path/file.mp4 --ISO-copyright \"Sample\" movie\n"
"example: AtomicParsley /path/file.mp4 --ISO-copyright \"Sample\" track=2 lang=urd\n"
"example: AtomicParsley /path/file.mp4 --ISO-copyright \"Sample\" track UTF16\n"
"example: AP --ISO-copyright \"Example\" track --ISO-copyright \"Por Exemplo\" track=2 lang=spa UTF16\n"
"\n"
"Note: to remove the copyright, set the string to \"\" - the track and language must match the target.\n"
"example: --ISO-copyright \"\" track --ISO-copyright \"\" track=2 lang=spa\n"
"\n"
"Note: (foo) denotes required arguments; [foo] denotes optional parameters & may have defaults.\n"
;
static const char* uuidHelp_text =
"AtomicParsley help page for setting uuid user extension metadata tags.\n"
"----------------------------------------------------------------------------------------------------\n"
" Setting a user-defined 'uuid' private extention tags will appear in \"moov.udta.meta\"). These will\n"
" only be read by AtomicParsley & can be set irrespective of file branding. The form of uuid that AP\n"
" is a v5 uuid generated from a sha1 hash of an atom name in an 'AtomicParsley.sf.net' namespace.\n"
"\n"
" The uuid form is in some Sony & Compressor files, but of version 4 (random/pseudo-random). An example\n"
" uuid of 'cprt' in the 'AtomicParsley.sf.net' namespace is: \"4bd39a57-e2c8-5655-a4fb-7a19620ef151\".\n"
" 'cprt' in the same namespace will always create that uuid; uuid atoms will only print out if the\n"
" uuid generated is the same as discovered. Sony uuids don't for example show up with AP -t.\n"
"\n"
" --information , -i (str) Set an information tag on uuid atom name\"©inf\"\n"
" --url , -u (URL) Set a URL tag on uuid atom name \"\302©url\"\n"
" --tagtime , timestamp Set the Coordinated Univeral Time of tagging on \"tdtg\"\n"
"\n"
" Define & set an arbitrary atom with a text data or embed a file:\n"
" --meta-uuid There are two forms: 1 for text & 1 for file operations\n"
" setting text form:\n"
" --meta-uuid (atom) \"text\" (str) \"atom\" = 4 character atom name of your choice\n"
" str is whatever text you want to set\n"
" file embedding form:\n"
" --meta-uuid (atom) \"file\" (/path) [description=\"foo\"] [mime-type=\"foo/moof\"]\n"
" \"atom\" = 4 character atom name of your choice\n"
" /path = path to the file that will be embedded*\n"
" description = optional description of the file\n"
" default is \"[none]\"\n"
" mime-type = optional mime type for the file\n"
" default is \"none\"\n"
" Note: no auto-disocevery of mime type\n"
" if you know/want it: supply it.\n"
" *Note: a file extension (/path/file.ext) is required\n"
"\n"
"Note: (foo) denotes required arguments; [foo] denotes optional arguments & may have defaults.\n"
"\n"
"Examples: \n"
" --tagtime timestamp --information \"[psst]I see metadata\" --url http://www.bumperdumper.com\n"
" --meta-uuid tagr text \"Johnny Appleseed\" --meta-uuid \302\251sft text \"OpenShiiva encoded.\"\n"
" --meta-uuid scan file /usr/pix/scans.zip\n"
" --meta-uuid 1040 file ../../2006_taxes.pdf description=\"Fooled 'The Man' yet again.\"\n"
"can be removed with:\n"
" --tagtime \"\" --information \"\" --url \" \" --meta-uuid scan file ""\n"
" --manualAtomRemove \"moov.udta.meta.uuid=672c98cd-f11f-51fd-adec-b0ee7b4d215f\" \\\n"
" --manualAtomRemove \"moov.udta.meta.uuid=1fed6656-d911-5385-9cb2-cb2c100f06e7\"\n"
"Remove the Sony uuid atoms with:\n"
" --manualAtomRemove moov.trak[1].uuid=55534d54-21d2-4fce-bb88-695cfac9c740 \\\n"
" --manualAtomRemove moov.trak[2].uuid=55534d54-21d2-4fce-bb88-695cfac9c740 \\\n"
" --manualAtomRemove uuid=50524f46-21d2-4fce-bb88-695cfac9c740\n"
"\n"
"Viewing the contents of uuid atoms:\n"
" -t or --textdata Shows the uuid atoms (both text & file) that AP sets:\n"
" Example output:\n"
" Atom uuid=ec0f...d7 (AP uuid for \"scan\") contains: FILE.zip; description=[none]\n"
" Atom uuid=672c...5f (AP uuid for \"tagr\") contains: Johnny Appleseed\n"
"\n"
"Extracting an embedded file in a uuid atom:\n"
" --extract1uuid (atom) Extract file embedded within uuid=atom into same folder\n"
" (file will be named with suffix shown in --textdata)\n"
" --extract-uuids [/path] Extract all files in uuid atoms under the moov.udta.meta\n"
" hierarchy. If no /path is given, files will be extracted\n"
" to the same folder as the originating file.\n"
"\n"
" Examples:\n"
" --extract1uuid scan\n"
" ... Extracted uuid=scan attachment to file: /some/path/FILE_scan_uuid.zip\n"
" --extract-uuids ~/Desktop/plops\n"
" ... Extracted uuid=pass attachment to file: /Users/me/Desktop/plops_pass_uuid.pdf\n"
" ... Extracted uuid=site attachment to file: /Users/me/Desktop/plops_site_uuid.html\n"
"\n"
"------------------------------------------------------------------------------------------------\n"
;
static const char* rDNSHelp_text =
"AtomicParsley help page for setting reverse domain '----' metadata atoms.\n"
"----------------------------------------------------------------------------------------------------\n"
" Please note that the reverse DNS format supported here is not feature complete.\n"
"\n"
" Another style of metadata that iTunes uses is called the reverse DNS format. For all known tags,\n"
" iTunes offers no user-accessible exposure to these tags or their contents. This reverse DNS form has\n"
" a differnt form than other iTunes tags that have a atom name that describes the content of 'data'\n"
" atom it contains. In the reverseDNS format, the parent to the structure called the '----' atom, with\n"
" children atoms that describe & contain the metadata carried. The 'mean' child contains the reverse\n"
" domain itself ('com.apple.iTunes') & the 'name' child contains the descriptor ('iTunNORM'). A 'data'\n"
" atom follows that actually contains the contents of the tag.\n"
"\n"
" --contentRating (rating) Set the US TV/motion picture media content rating\n"
" for available ratings use \"AtomicParsley --ratings-list\n"
" --rDNSatom (str) name=(name_str) domain=(reverse_domain) Manually set a reverseDNS atom.\n"
"\n"
" To set the form manually, 3 things are required: a domain, a name, and the desired text.\n"
" Note: multiple 'data' atoms are supported, but not in the com.apple.iTunes domain\n"
" Examples:\n"
" --contentRating \"NC-17\" --contentRating \"TV-Y7\"\n"
" --rDNSatom \"mpaa|PG-13|300|\" name=iTunEXTC domain=com.apple.iTunes\n"
" --contentRating \"\"\n"
" --rDNSatom \"\" name=iTunEXTC domain=com.apple.iTunes\n"
" --rDNSatom \"try1\" name=EVAL domain=org.fsf --rDNSatom \"try 2\" name=EVAL domain=org.fsf\n"
" --rDNSatom \"\" name=EVAL domain=org.fsf\n"
"----------------------------------------------------------------------------------------------------\n"
;
static const char* ID3Help_text =
"AtomicParsley help page for ID32 atoms with ID3 tags.\n"
"----------------------------------------------------------------------------------------------------\n"
" ** Please note: ID3 tag support is not feature complete & is in an alpha state. **\n"
"----------------------------------------------------------------------------------------------------\n"
" ID3 tags are the tagging scheme used by mp3 files (where they are found typically at the start of the\n"
" file). In mpeg-4 files, ID3 version 2 tags are located in specific hierarchies at certain levels, at\n"
" file/movie/track level. The way that ID3 tags are carried on mpeg-4 files (carried by 'ID32' atoms)\n"
" was added in early 2006, but the ID3 tagging 'informal standard' was last updated (to v2.4) in 2000.\n"
" With few exceptions, ID3 tags in mpeg-4 files exist identically to their mp3 counterparts.\n"
"\n"
" The ID3 parlance, a frame contains an piece of metadata. A frame (like COMM for comment, or TIT1 for\n"
" title) contains the information, while the tag contains all the frames collectively. The 'informal\n"
" standard' for ID3 allows multiple langauges for frames like COMM (comment) & USLT (lyrics). In mpeg-4\n"
" this language setting is removed from the ID3 domain and exists in the mpeg-4 domain. That means that\n"
" when an english and a spanish comment are set, 2 separate ID32 atoms are created, each with a tag & 1\n"
" frame as in this example:\n"
" --ID3Tag COMM \"Primary\" --desc=AAA --ID3Tag COMM \"El Segundo\" UTF16LE lang=spa --desc=AAA\n"
" See available frames with \"AtomicParsley --ID3frames-list\"\n"
" See avilable imagetypes with \"AtomicParsley --imagetype-list\"\n"
"\n"
" AtomicParsley writes ID3 version 2.4.0 tags *only*. There is no up-converting from older versions.\n"
" Defaults are:\n"
" default to movie level (moov.meta.ID32); other options are [ \"root\", \"track=(num)\" ] (see WARNING)\n"
" UTF-8 text encoding when optional; other options are [ \"LATIN1\", \"UTF16BE\", \"UTF16LE\" ]\n"
" frames that require descriptions have a default of \"\"\n"
" for frames requiring a language setting, the ID32 language is used (currently defaulting to 'eng')\n"
" frames that require descriptions have a default of \"\"\n"
" image type defaults to 0x00 or Other; for image type 0x01, 32x32 png is enforced (switching to 0x02)\n"
" setting the image mimetype is generally not required as the file is tested, but can be overridden\n"
" zlib compression off\n"
"\n"
" WARNING:\n"
" Quicktime Player (up to v7.1.3 at least) will freeze opeing a file with ID32 tags at movie level.\n"
" Specifically, the parent atom, 'meta' is the source of the issue. You can set the tags at file or\n"
" track level which avoids the problem, but the default is movie level. iTunes is unaffected.\n"
"----------------------------------------------------------------------------------------------------\n"
" Current limitations:\n"
" - syncsafe integers are used as indicated by the id3 \"informal standard\". usage/reading of\n"
" nonstandard ordinary unsigned integers (uint32_t) is not/will not be implemented.\n"
" - externally referenced images (using mimetype '-->') are prohibited by the ID32 specification.\n"
" - the ID32 atom is only supported in a non-referenced context\n"
" - probably a raft of other limitations that my brain lost along the way...\n"
"----------------------------------------------------------------------------------------------------\n"
" Usage:\n"
" --ID3Tag (frameID or alias) (str) [desc=(str)] [mimetype=(str)] [imagetype=(str or hex)] [...]\n"
"\n"
" ... represents other arguments:\n"
" [compressed] zlib compress the frame\n"
" [UTF16BE, UTF16LE, LATIN1] alternative text encodings for frames that support different encodings\n"
"\n"
"Note: (foo) denotes required arguments; [foo] denotes optional parameters\n"
"\n"
" Examples:\n"
" --ID3Tag APIC /path/to/img.ext\n"
" --ID3Tag APIC /path/to/img.ext desc=\"something to say\" imagetype=0x08 UTF16LE compressed\n"
" --ID3Tag composer \"I, Claudius\" --ID3Tag TPUB \"Seneca the Roman\" --ID3Tag TMOO Imperial\n"
" --ID3Tag UFID look@me.org uniqueID=randomUUIDstamp\n"
"\n"
" Extracting embedded images in APIC frames:\n"
" --ID3Tag APIC extract\n"
" images are extracted into the same directory as the source mpeg-4 file\n"
"\n"
#if defined (DARWIN_PLATFORM)
" Setting MCDI (Music CD Identifier):\n"
" --ID3Tag MCDI disk4\n"
" Information to create this frame is taken directly off an Audio CD's TOC. If the target\n"
" disk is not found or is not an audio CD, a scan of all devices will occur. If an Audio CD\n"
" is present, the scan should yield what should be entered after 'MCDI':\n"
" % AP file --ID3Tag MCDI disk3\n"
" % No cd present in drive at disk3\n"
" % Device 'disk4' contains cd media\n"
" % Good news, device 'disk4' is an Audio CD and can be used for 'MCDI' setting\n"
#elif defined (HAVE_LINUX_CDROM_H)
" Setting MCDI (Music CD Identifier):\n"
" --ID3Tag MCDI /dev/hdc\n"
" Information to create this frame is taken directly off an Audio CD's TOC. An Audio CD\n"
" must be mounted & present.\n"
#elif defined (_WIN32)
" Setting MCDI (Music CD Identifier):\n"
" --ID3Tag MCDI D\n"
" Information to create this frame is taken directly off an Audio CD's TOC. The letter after\n"
" \"MCDI\" is the letter of the drive where the CD is present.\n"
#endif
;
void ExtractPaddingPrefs(char* env_padding_prefs) {
pad_prefs.default_padding_size = DEFAULT_PADDING_LENGTH;
pad_prefs.minimum_required_padding_size = MINIMUM_REQUIRED_PADDING_LENGTH;
pad_prefs.maximum_present_padding_size = MAXIMUM_REQUIRED_PADDING_LENGTH;
if (env_padding_prefs != NULL) {
if (env_padding_prefs[0] == 0x22 || env_padding_prefs[0] == 0x27) env_padding_prefs++;
}
char* env_pad_prefs_ptr = env_padding_prefs;
while (env_pad_prefs_ptr != NULL) {
env_pad_prefs_ptr = strsep(&env_padding_prefs,":");
if (env_pad_prefs_ptr == NULL) break;
if (strncmp(env_pad_prefs_ptr, "DEFAULT_PAD=", 12) == 0) {
strsep(&env_pad_prefs_ptr,"=");
sscanf(env_pad_prefs_ptr, "%u", &pad_prefs.default_padding_size);
}
if (strncmp(env_pad_prefs_ptr, "MIN_PAD=", 8) == 0) {
strsep(&env_pad_prefs_ptr,"=");
sscanf(env_pad_prefs_ptr, "%u", &pad_prefs.minimum_required_padding_size);
}
if (strncmp(env_pad_prefs_ptr, "MAX_PAD=", 8) == 0) {
strsep(&env_pad_prefs_ptr,"=");
sscanf(env_pad_prefs_ptr, "%u", &pad_prefs.maximum_present_padding_size);
}
}
//fprintf(stdout, "Def %u; Min %u; Max %u\n", pad_prefs.default_padding_size, pad_prefs.minimum_required_padding_size, pad_prefs.maximum_present_padding_size);
return;
}
void GetBasePath(const char *filepath, char* &basepath) {
//with a myriad of m4a, m4p, mp4, whatever else comes up... it might just be easiest to strip off the end.
int split_here = 0;
for (int i=strlen(filepath); i >= 0; i--) {
const char* this_char=&filepath[i];
if ( *this_char == '.' ) {
split_here = i;
break;
}
}
memcpy(basepath, filepath, (size_t)split_here);
return;
}
void find_optional_args(char *argv[], int start_optindargs, uint16_t &packed_lang, bool &asUTF16, uint8_t &udta_container, uint8_t &trk_idx, int max_optargs) {
asUTF16 = false;
packed_lang = 5575; //und = 0x55C4 = 21956, but QTPlayer doesn't like und //eng = 0x15C7 = 5575
for (int i= 0; i <= max_optargs-1; i++) {
if ( argv[start_optindargs + i] && start_optindargs + i <= total_args ) {
if ( strncmp(argv[start_optindargs + i], "lang=", 5) == 0 ) {
if (!MatchLanguageCode(argv[start_optindargs +i]+5) ) {
packed_lang = PackLanguage("und", 0);
} else {
packed_lang = PackLanguage(argv[start_optindargs +i], 5);
}
} else if ( strcmp(argv[start_optindargs + i], "UTF16") == 0 ) {
asUTF16 = true;
} else if ( strcmp(argv[optind + i], "movie") == 0 ) {
udta_container = MOVIE_LEVEL_ATOM;
} else if ( strncmp(argv[optind + i], "track=", 6) == 0 ) {
char* track_index_str = argv[optind + i];
strsep(&track_index_str, "=");
sscanf(track_index_str, "%" PRIu8 "", &trk_idx);
udta_container = SINGLE_TRACK_ATOM;
} else if ( strcmp(argv[optind + i], "track") == 0 ) {
udta_container = ALL_TRACKS_ATOM;
}
if (*argv[start_optindargs + i] == '-') {
break; //we've hit another cli argument
}
}
}
return;
}
void scan_ID3_optargs(char *argv[], int start_optargs, const char* &target_lang, uint16_t &packed_lang, uint8_t &char_encoding, char* meta_container, bool &multistring) {
packed_lang = 5575; //default ID32 lang is 'eng'
uint16_t i = 0;
while (argv[start_optargs + i] != NULL) {
if ( argv[start_optargs + i] && start_optargs + i <= total_args ) {
if ( strncmp(argv[start_optargs + i], "lang=", 5) == 0 ) {
if (!MatchLanguageCode(argv[start_optargs +i]+5) ) {
packed_lang = PackLanguage("und", 0);
target_lang = "und";
} else {
packed_lang = PackLanguage(argv[start_optargs +i], 5);
target_lang = argv[start_optargs + i] + 5;
}
} else if ( strcmp(argv[start_optargs + i], "UTF16LE") == 0 ) {
char_encoding = TE_UTF16LE_WITH_BOM;
} else if ( strcmp(argv[start_optargs + i], "UTF16BE") == 0 ) {
char_encoding = TE_UTF16BE_NO_BOM;
} else if ( strcmp(argv[start_optargs + i], "LATIN1") == 0 ) {
char_encoding = TE_LATIN1;
} else if ( strcmp(argv[optind + i], "root") == 0 ) {
*meta_container = 0-FILE_LEVEL_ATOM;
} else if ( strncmp(argv[optind + i], "track=", 6) == 0 ) {
char* track_index_str = argv[optind + i];
strsep(&track_index_str, "=");
sscanf(track_index_str, "%hhu", meta_container);
}
}
if (*argv[start_optargs + i] == '-') {
break; //we've hit another cli argument or deleting some frame
}
i++;
}
return;
}
const char* find_ID3_optarg(char *argv[], int start_optargs, const char* arg_string) {
const char* ret_val = "";
uint16_t i = 0;
uint8_t arg_prefix_len = strlen(arg_string);
while (argv[start_optargs + i] != NULL) {
if ( argv[start_optargs + i] && start_optargs + i <= total_args ) {
if (strcmp(arg_string, "compressed") == 0 && strcmp(argv[start_optargs + i], "compressed") == 0) {
return "1";
}
//if (strcmp(arg_string, "text++") == 0 && strcmp(argv[start_optargs + i], "text++") == 0) {
// return "1";
//}
if (strncmp(argv[start_optargs + i], arg_string, arg_prefix_len) == 0) {
ret_val = argv[start_optargs + i] + arg_prefix_len;
break;
}
}
if (*argv[start_optargs + i] == '-') {
break; //we've hit another cli argument or deleting some frame
}
i++;
}
return ret_val;
}
//***********************************************
static void show_short_help(void)
{
printf("%s\n", shortHelp_text);
ShowVersionInfo();
printf("\nReport issues at %s\n", PACKAGE_BUGREPORT);
}
int real_main(int argc, char *argv[])
{
if (argc == 1) {
show_short_help();
exit(0);
} else if (argc == 2 && (
(strcmp(argv[1],"-v") == 0) ||
(strcmp(argv[1],"-version") == 0) ||
(strcmp(argv[1],"--version") == 0)) ) {
ShowVersionInfo();
exit(0);
} else if (argc == 2) {
if ((strcmp(argv[1],"-help") == 0) ||
(strcmp(argv[1],"--help") == 0) ||
(strcmp(argv[1],"-h") == 0 ) ) {
show_short_help();
exit(0);
} else if ( (strcmp(argv[1],"--longhelp") == 0) || (strcmp(argv[1],"-longhelp") == 0) || (strcmp(argv[1],"-Lh") == 0) ) {
#if defined (_WIN32)
if (UnicodeOutputStatus == WIN32_UTF16) { //convert the helptext to utf16 to preserve © characters
int help_len = strlen(longHelp_text)+1;
wchar_t* Lhelp_text = (wchar_t *)malloc(sizeof(wchar_t)*help_len);
wmemset(Lhelp_text, 0, help_len);
UTF8ToUTF16LE((unsigned char*)Lhelp_text, 2*help_len, (unsigned char*)longHelp_text, help_len);
APar_unicode_win32Printout(Lhelp_text, (char *) longHelp_text);
free(Lhelp_text);
} else
#endif
{
fprintf(stdout, "%s", longHelp_text);
}
exit(0);
} else if ( (strcmp(argv[1],"--3gp-help") == 0) || (strcmp(argv[1],"-3gp-help") == 0) || (strcmp(argv[1],"--3gp-h") == 0) ) {
fprintf(stdout, "%s\n", _3gpHelp_text); exit(0);
} else if ( (strcmp(argv[1],"--ISO-help") == 0) || (strcmp(argv[1],"--iso-help") == 0) || (strcmp(argv[1],"-Ih") == 0) ) {
fprintf(stdout, "%s\n", ISOHelp_text); exit(0);
} else if ( (strcmp(argv[1],"--file-help") == 0) || (strcmp(argv[1],"-file-help") == 0) || (strcmp(argv[1],"-fh") == 0) ) {
fprintf(stdout, "%s\n", fileLevelHelp_text); exit(0);
} else if ( (strcmp(argv[1],"--uuid-help") == 0) || (strcmp(argv[1],"-uuid-help") == 0) || (strcmp(argv[1],"-uh") == 0) ) {
fprintf(stdout, "%s\n", uuidHelp_text); exit(0);
} else if ( (strcmp(argv[1],"--reverseDNS-help") == 0) || (strcmp(argv[1],"-rDNS-help") == 0) || (strcmp(argv[1],"-rh") == 0) ) {
fprintf(stdout, "%s\n", rDNSHelp_text); exit(0);
} else if ( (strcmp(argv[1],"--ID3-help") == 0) || (strcmp(argv[1],"-ID3-help") == 0) || (strcmp(argv[1],"-ID3h") == 0) ) {
fprintf(stdout, "%s\n", ID3Help_text); exit(0);
} else if ( strcmp(argv[1], "--genre-list") == 0 ) {
ListGenresValues(); exit(0);
} else if ( strcmp(argv[1], "--stik-list") == 0 ) {
ListStikValues(); exit(0);
} else if ( strcmp(argv[1], "--language-list") == 0 ||
strcmp(argv[1], "--languages-list") == 0 ||
strcmp(argv[1], "--list-language") == 0 ||
strcmp(argv[1], "--list-languages") == 0 ||
strcmp(argv[1], "-ll") == 0) {
ListLanguageCodes(); exit(0);
} else if (strcmp(argv[1], "--ratings-list") == 0) {
ListMediaRatings(); exit(0);
} else if (strcmp(argv[1], "--ID3frames-list") == 0) {
ListID3FrameIDstrings(); exit(0);
} else if (strcmp(argv[1], "--imagetype-list") == 0) {
List_imagtype_strings(); exit(0);
}
}
if ( argc == 3 && (strcmp(argv[2], "--brands") == 0 || strcmp(argv[2], "-brands") == 0) ) {
APar_ExtractBrands(argv[1]); exit(0);
}
int extr = 99;
total_args = argc;
char* ISObasemediafile = argv[1];
TestFileExistence(ISObasemediafile, true);