521 Commits
v1.5 ... v1.8

Author SHA1 Message Date
Lukáš Lalinský
aa34afda79 Merge remote-tracking branch 'TsudaKageyu/substr-bug' 2012-09-06 20:03:15 +02:00
Lukáš Lalinský
942ec58de5 Add tests for String::substr 2012-09-06 20:03:08 +02:00
Lukáš Lalinský
082a36147b Add change log, update SOVERSION 2012-09-06 19:57:10 +02:00
Lukáš Lalinský
f11b206fe8 Do not delete the IOStream object in TagLib::File 2012-09-06 19:43:52 +02:00
Lukáš Lalinský
e37f6ed752 Update CMakeLists.txt 2012-09-06 19:30:45 +02:00
Lukáš Lalinský
d2f20e8d2a Merge branch 'master' of https://github.com/moeeka/taglib 2012-09-06 19:24:22 +02:00
Rupert Daniel
f194a55c0f Updated OWNE implementaion with minor changes after pull review 2012-09-06 12:11:20 +01:00
Rupert Daniel
719187794e Implementation of the ID3v2.4 OWNE frame. 2012-09-05 16:37:46 +01:00
Tsuda Kageyu
74b94613a0 Bug fix in String::substr() 2012-09-05 19:46:52 +09:00
Lukáš Lalinský
33d0be110b Fix ambiguous reference to uint in tests 2012-09-03 19:55:55 +02:00
Tsuda Kageyu
df12b4ffc6 Refectored the FileStream constructor. 2012-09-03 01:45:28 +09:00
Tsuda Kageyu
d16c24ae21 Merge branch 'master' of https://github.com/taglib/taglib into security-warnings 2012-09-02 23:40:11 +09:00
Lukáš Lalinský
1c35918834 Merge remote-tracking branch 'TsudaKageyu/warnings' 2012-09-02 15:25:41 +02:00
Tsuda Kageyu
d163f36d35 Fix Visual C++ specific warnings about security 2012-08-23 21:57:12 +09:00
Tsuda Kageyu
590cd4c9f6 Fix warnings with VS2010 2012-08-23 20:54:18 +09:00
Tsuda Kageyu
6c0227ee13 Fix compilation errors with Visual Studio 2010 2012-08-23 19:58:21 +09:00
Lukáš Lalinský
9bb57fe0a7 Merge remote-tracking branch 'TsudaKageyu/id3v2-comment-update' 2012-08-23 11:00:32 +02:00
tsuda.kageyu@gmail.com
3fecdbf428 Comment update for ID3v2::Tag::setLatin1StringHandler() 2012-08-23 17:57:00 +09:00
Lukáš Lalinský
356c7a5d6e Merge remote-tracking branch 'TsudaKageyu/cross-border-delete' 2012-08-23 10:51:47 +02:00
tsuda.kageyu@gmail.com
4b4f70253b Comment update for ID3v1::Tag::setStringHandler() 2012-08-23 17:45:25 +09:00
Lukáš Lalinský
8b61a06fda Merge remote-tracking branch 'TsudaKageyu/id3v2-brokenlatin1-patch' 2012-08-23 10:22:43 +02:00
Lukáš Lalinský
6801ac2515 Merge remote-tracking branch 'poiru/master' 2012-08-23 10:19:08 +02:00
Lukáš Lalinský
29d17bb8e9 Merge remote-tracking branch 'supermihi/master' 2012-08-23 10:17:05 +02:00
tsuda.kageyu@gmail.com
fe8053c7d5 Support broken Latin-1 encodings in ID3V2 2012-08-23 12:19:51 +09:00
tsuda.kageyu@gmail.com
eb63ee8ec6 Remove possible cross binary boundary delete 2012-08-23 11:09:22 +09:00
Lukáš Lalinský
e86e5f906b ID3 frame IDs with 0 should be recognized as valid
http://article.gmane.org/gmane.comp.kde.devel.taglib/2275
2012-08-17 07:50:48 +02:00
Lukáš Lalinský
60e82e6694 Ignore additional files 2012-08-17 07:34:44 +02:00
Birunthan Mohanathas
fc6e02da35 Update header comments to reflect c4163a2 2012-08-02 17:25:20 +03:00
Michael Helmling
4140c5f2eb Check PropertyMap keys format-specifically instead of globally.
Instead of statically forbidding certain keys in PropertyMap, now the
setProperties() implementations of the different formats check if the
keys are valid for that particular specification and include them in
the returned PropertyMap otherwise.
This should remove an unneccessary complification for programmers since
now there's only one step, namely calling setProperties(), where
problems might occur.
Also the previous implementation leads to problems with invalid keys:
because taglib doesn't use exceptions, something like

  map.insert("FORBIDDEN KEY", "some value");

would lead to the value being inserted under String::null, which
smells like the source of strange bugs.
2012-07-30 20:52:30 +02:00
Michael Helmling
fc3fc10f60 add id3v2 frame delete test 2012-07-23 20:53:25 +02:00
BSDKaffee
3bc123aed6 - Disambiguate uint and ushort references 2012-07-15 01:57:53 -04:00
Lukáš Lalinský
3b392f2402 Changelog for 1.8 beta 2012-07-14 21:53:09 +02:00
Lukáš Lalinský
8ff0feb28e Cast to long 2012-07-14 21:21:03 +02:00
Lukáš Lalinský
61ed295af8 Merge remote-tracking branch 'poiru/master' 2012-07-14 21:09:54 +02:00
Lukáš Lalinský
09af2a7b57 Merge remote-tracking branch 'robinst/mpeg-file-id3vxtag-docs-inexistent-tags' 2012-07-14 21:08:59 +02:00
Lukáš Lalinský
050ff3835d Revert "Install examples if built."
This reverts commit 52e96e48c5.
2012-07-14 21:06:53 +02:00
Lukáš Lalinský
674ae0fa6d Merge remote-tracking branch 'kensington/master' 2012-07-14 21:06:08 +02:00
Lukáš Lalinský
411d318f34 Merge remote-tracking branch 'robinst/dont-copy-from-id3v1-when-only-saving-id3v2' 2012-07-14 21:03:16 +02:00
Lukáš Lalinský
fbb1c7e554 Merge branch 'mpc_sv8' 2012-07-11 14:15:37 +02:00
Lukáš Lalinský
fd818857e0 More Musepack tests 2012-07-11 14:15:12 +02:00
Lukáš Lalinský
930168f990 Refactoring of the Musepack SV8 properties code 2012-07-11 14:13:41 +02:00
Alex Novichkov
291d925fc1 MPC v8 audio properties 2012-07-11 13:08:10 +02:00
Scott Wheeler
7c4c455a40 Use '0' here instead of 'NULL'
0 is used throughout the rest of the TagLib source, and generally
preferred in C++:

http://www2.research.att.com/~bs/bs_faq2.html#null
2012-07-03 12:26:20 +02:00
Stephen F. Booth
f429d6f406 Merge pull request #41 from EliaCereda/master
Properly initialize frame
2012-06-30 07:33:25 -07:00
Elia Cereda
c68fe9ad7b Fixed error "Branch condition evaluates to a garbage value" (from Xcode 4.3.3 Static Analyzer, mpeg/id3v2/id3v2tag.cpp:377)
This error occurs when the frame variable is left uninitialized because its id doesn't match any of the ids in the if and else-id cases. Initializing it on declaration fixes this issue.
2012-06-30 16:25:33 +02:00
Stephen F. Booth
81aac3a590 Merge pull request #39 from robinst/install-build-tests-option
Mention -DBUILD_TESTS=on in "Unit Tests" of INSTALL
2012-06-11 04:57:04 -07:00
Robin Stocker
7279b4fb7b Don't duplicate from ID3v1 to ID3v2 when saving only ID3v2
When saving only v2 with stripOthers (which means stripping v1), the
data from v1 would still be duplicated to v2. Likewise for the other way
around.

This is not the expected outcome when e.g. a frame was removed in v2,
because it would be added again on save from the v1 data. The test shows
that.

This changes save to only duplicate the data when the other tag type
will not be stripped.
2012-06-10 18:53:25 +02:00
Robin Stocker
b0ac79c60e Mention -DBUILD_TESTS=on in "Unit Tests" of INSTALL 2012-06-10 18:26:06 +02:00
Robin Stocker
382aec46f7 Fix docs of MPEG::File::ID3v(1|2)Tag for inexistent tag
Since 37e2d629, the ID3v1 and ID3v2 tags are always created at the end
of MPEG::File::read. So contrary to what the documentation said, a null
pointer is never returned.

To check if a tag contains data, refer to isEmpty() in the
documentation.
2012-06-10 15:27:54 +02:00
Michael Palimaka
b5ad68d64b Add custom 'check' target that depends on the test_runner target for backwards compatibility. 2012-05-17 03:42:36 +10:00
Michael Palimaka
52e96e48c5 Install examples if built. 2012-05-16 04:37:25 +10:00
Michael Palimaka
5bcfecb6cc Use ctest instead of custom target. 2012-05-16 04:00:22 +10:00
Lukáš Lalinský
2c2a486313 Merge branch 'stable'
Conflicts:
	CMakeLists.txt
	NEWS
2012-04-20 18:30:07 +02:00
Lukáš Lalinský
059f2243b3 Prepare 1.7.2 release 2012-04-20 17:57:13 +02:00
Lukáš Lalinský
cce6ad46c9 Reverse the version check, similarly to what mp4v2 does 2012-04-20 17:52:12 +02:00
Birunthan Mohanathas
06597123b8 Remove trailing whitespace 2012-04-19 13:09:45 +03:00
Birunthan Mohanathas
e5ede410bc Tabs to spaces 2012-04-19 13:04:42 +03:00
Vinnie Falco
dafb3af742 Remove 'using namespace std' in tmap.h 2012-04-17 22:05:09 -07:00
Lukáš Lalinský
089643f115 Merge remote-tracking branch 'vinniefalco/rename_enums' 2012-04-17 08:49:02 +02:00
Vinnie Falco
26f458b87f Resolve scope resolution for APE::Footer definitions in apefooter.cpp 2012-04-15 07:58:50 -07:00
Vinnie Falco
c22791318c Resolve ambiguous File symbol in apetag.cpp 2012-04-15 07:57:02 -07:00
Vinnie Falco
5081e3cf4f Rename anonymous enumeration symbols to be unique trueaudiofile.cpp 2012-04-15 02:41:27 -07:00
Vinnie Falco
1bde4cea09 Rename anonymous enumeration symbols to be unique in wavpackfile.cpp 2012-04-15 02:40:46 -07:00
Vinnie Falco
0907e86a94 Rename anonymous enumeration symbols to be unique in apefile.cpp 2012-04-15 02:40:23 -07:00
Vinnie Falco
742a3a1dbb Rename anonymous enumeration symbols to be unique in mpcfile.cpp 2012-04-15 02:39:19 -07:00
Vinnie Falco
04a4a6b8d4 Rename anonymous enumeration symbols to be unique in flacfile.cpp 2012-04-15 02:38:15 -07:00
Jeff Mitchell
b216b448c5 Fix compilation 2012-04-12 18:41:40 -04:00
Stephen F. Booth
4f8a6fdfaf Verify that an APE text item isn't empty before use 2012-04-12 10:53:32 -04:00
Stephen F. Booth
32a4ac6599 Preserve source code backward compatibility 2012-04-10 18:06:58 -04:00
Stephen F. Booth
ca26a9ad3e Added support for APE tag binary items 2012-04-10 07:24:12 -04:00
Stephen F. Booth
bd03e352cc Allow tag items to be replaced 2012-04-07 08:54:22 -04:00
Stephen F. Booth
69ac59f5f0 Added sampleFrames() to audio properties 2012-04-06 18:30:13 -04:00
Stephen F. Booth
2297a6d531 Added missing tmap.h 2012-04-06 18:29:56 -04:00
Lukáš Lalinský
2a4850f211 Merge branch 'stable'
Conflicts:
	CMakeLists.txt
2012-03-18 09:22:53 +01:00
scottmc
288c6e4a3f Include <iostream> instead of <ostream> to fix compilation on Haiku 2012-03-18 09:20:26 +01:00
Lukáš Lalinský
606edf8171 Increment the version number 2012-03-17 11:02:24 +01:00
Lukáš Lalinský
3c7b05a900 Merge branch 'stable'
Conflicts:
	NEWS
2012-03-17 10:59:34 +01:00
Lukáš Lalinský
009c43952f Changelog 2012-03-17 10:58:22 +01:00
Birunthan Mohnathas
9c1668f28b Fixed (huge) memory leak with ASF. 2012-03-17 10:48:57 +01:00
Lukáš Lalinský
8e67b40bdc Fix compilation errors 2012-03-17 10:45:52 +01:00
Lukáš Lalinský
76222cb1eb Merge branch 'master' of https://github.com/supermihi/taglib 2012-03-17 10:41:02 +01:00
Birunthan Mohnathas
138dfca682 Additional change to previous fix. 2012-03-12 22:13:58 +02:00
Birunthan Mohnathas
c4163a26e8 Fixed memory leak of FrameFactory singleton. 2012-03-12 18:56:08 +02:00
Birunthan Mohnathas
4496efe33b Fixed (huge) memory leak with ASF. 2012-03-12 18:44:08 +02:00
Lukáš Lalinský
3a760b060c Merge branch 'stable'
Conflicts:
	taglib/riff/aiff/aiffproperties.cpp
	taglib/trueaudio/trueaudioproperties.cpp
	tests/test_wav.cpp
2012-03-10 09:16:37 +01:00
Lukáš Lalinský
110cac8429 Avoid uint overflow in case the length + index is over UINT_MAX 2012-03-10 09:13:04 +01:00
Lukáš Lalinský
258ae751b5 Don't store the output of ByteVector::toUInt() in int, use uint instead 2012-03-10 09:12:32 +01:00
Lukáš Lalinský
df1d3e028e Make sure to not try dividing by zero 2012-03-10 09:12:19 +01:00
Stephen F. Booth
23c86cf27d Check if the header is TTA1 before parsing 2012-03-10 09:11:51 +01:00
Lukáš Lalinský
f59c3b67aa Detect RIFF files with invalid chunk sizes
The bug report has a WAVE file with zero-sized 'data' chunk, which causes
TagLib to iterate over the file, 8 bytes in each iteration. The new code
adds a check for the chunk name, which forces it to mark the file as
invalid if the chunk name doesn't contain ASCII characters.

https://bugs.kde.org/show_bug.cgi?id=283412
2012-03-10 09:06:55 +01:00
Stephen F. Booth
294cb22241 Don't crash when wav files have a 0 for bit per channel (sampleWidth)
I've seen this in a wav that has an audio format of MP3 (0x55)
2012-03-10 08:58:45 +01:00
Frank Lai
b7ec0d26ab Be more careful when parsing Vorbis Comments 2012-03-10 08:52:59 +01:00
Scott Wheeler
934ce51790 Don't lead the scanned blocks on save 2012-03-10 08:52:17 +01:00
Lukáš Lalinský
dcdf4fd954 Avoid uint overflow in case the length + index is over UINT_MAX 2012-03-10 08:46:20 +01:00
Lukáš Lalinský
ab8a0ee893 Don't store the output of ByteVector::toUInt() in int, use uint instead 2012-03-04 12:01:21 +01:00
Lukáš Lalinský
77d61c6eca Make sure to not try dividing by zero 2012-03-04 11:51:05 +01:00
Michael Helmling
f5a2518273 Fixed handling of UnknownFrames in ID3v2.
- If an unknown frame with id "XXXX" occurs, an entry
"UNKNOWN/XXXX" is added to unsupportedData().
The removeUnsupportedProperties() method in turn
removes all unknown frames with id "XXXX" if it
encounters a string "UNKNOWN/XXXX" in the given list.

- Implemented findByDescription() to UnsynchronizedLyricsFrame
in order to support removal of lyrics frames with unsupported
keys.

- Adapted id3v2 test case to new QuodLibet policy.
2012-02-26 19:21:57 +01:00
Michael Helmling
6e6d823992 Removed quodlibet special case handling 2012-02-26 18:38:03 +01:00
Michael Helmling
f859fcf82a Add support for Unknown TXXX frames. 2012-02-26 18:07:02 +01:00
Michael Helmling
37c87e0317 Fixed identation 2012-02-26 10:56:18 +01:00
Michael Helmling
0a3b998ca5 Fix USLT frame creation in Frame::createTextualFrame() 2012-02-26 10:43:08 +01:00
Michael Helmling
fa0656e3c6 remove Tests/Examples build from CMakeLists 2012-02-26 10:37:59 +01:00
Michael Helmling
b05c3161c7 Added ID3v2 PropertyMap interface documentation. 2012-02-25 19:11:31 +01:00
Michael Helmling
79670beca1 some cosmetic changes 2012-02-25 18:59:53 +01:00
Michael Helmling
9fd22023cd Merge remote-tracking branch 'official/master' 2012-02-25 18:51:30 +01:00
Michael Helmling
b8d5246f88 Moved APE test to correct place; added MOD tag test. 2012-02-25 18:46:19 +01:00
Michael Helmling
05b5e06928 added APE tag PropertyMap test 2012-02-25 18:32:00 +01:00
Michael Helmling
d28cc83fb4 Added another test for ID3v2 PropertyMap interface; fixed various bugs 2012-02-25 18:22:17 +01:00
Michael Helmling
495a028da3 removed debug messages 2012-02-19 15:15:25 +01:00
Michael Helmling
23d303a896 fixed bugs preventing tests from running 2012-02-19 15:13:31 +01:00
Michael Helmling
6c054af3ed Added some functions, started to fix bugs. 2012-02-19 12:15:28 +01:00
Michael Helmling
70c3264279 fixed tests 2012-02-15 22:09:28 +01:00
Michael Helmling
cfa5ac6569 Fixed id3v2 test 2012-02-15 21:56:02 +01:00
Michael Helmling
de51307de7 Added lots of missing includes 2012-02-15 21:54:19 +01:00
Michael Helmling
140f4a57e2 fixed lots of bugs found by 'make' 2012-02-14 22:11:30 +01:00
Michael Helmling
8a8e9b702c Ported xm. 2012-02-14 21:35:50 +01:00
Michael Helmling
d6215365a1 Ported wavpack. 2012-02-14 21:34:43 +01:00
Michael Helmling
2185d52f56 Ported trueaudio. 2012-02-14 21:32:36 +01:00
Michael Helmling
48aaaf8dc4 Ported s3m; removed old id3v2dicttools. 2012-02-14 21:29:30 +01:00
Michael Helmling
d2c43d7174 ID3 interface complete; vorbis done; wav done 2012-02-14 21:27:14 +01:00
Lukáš Lalinský
cdfb447042 Add explicitly declared default constructor to StringHandler 2012-02-04 21:22:52 +01:00
Lukáš Lalinský
2d00b690de Merge branch 'master' of https://github.com/poiru/taglib 2012-02-04 20:38:14 +01:00
Stephen F. Booth
51675f3399 Added sampleFrames to FLACProperties 2012-02-04 11:34:40 -05:00
Stephen F. Booth
fa662a23db Check if the header is TTA1 before parsing 2012-02-04 08:39:45 -05:00
Stephen F. Booth
dc628204c0 Added sampleFrames() for TTA files 2012-02-04 08:30:34 -05:00
Birunthan Mohanathas
9564956a7f Removed space. 2012-02-02 18:12:37 +02:00
Birunthan Mohnathas
1f2248d24b Additional change to previous fix. 2012-02-02 17:50:58 +02:00
Birunthan Mohnathas
06424598bb Fixed memory leak. 2012-02-02 15:03:41 +02:00
Stephen F. Booth
7b3f279294 Correctly handle non-integral bit depths 2012-01-30 22:31:15 -05:00
Michael Helmling
a8632f710f More progress in ID3 ... setProperties() will get messy :( 2012-01-22 22:06:24 +01:00
Michael Helmling
0c8e5bbec8 Implemented asProperties() in all relevant textual frames. 2012-01-22 17:08:02 +01:00
Michael Helmling
a5e45f196b Started to work on ID3v2. 2012-01-21 23:05:59 +01:00
Michael Helmling
e4d955d6ef Migration to new PropertyMap ... done ape to mod. 2012-01-21 14:52:24 +01:00
Michael Helmling
18ae797df4 Add unsupportedData() to PropertyMap, simplified [] behavior. 2012-01-17 18:09:30 +01:00
Michael Helmling
d11189b975 Basic implementation of a PropertyMap.
Implemented key/valuelist property map with
case-insensitive ASCII keys and StringList values.

Todo:
- subclass StringList to add flags indicating whether a value could
be written to the specific file format
- add member attribute indicating list of frames that could not be
parsed into the PropertyMap representation.
2012-01-16 22:37:30 +01:00
Michael Helmling
67d896e6a7 Implemented the most easy comments on the pull request. 2012-01-14 22:02:17 +01:00
Michael Helmling
ea41cd8903 Merge remote-tracking branch 'official/master' 2012-01-14 20:57:15 +01:00
Lukáš Lalinský
d904281c6b Make it possible to generate an XML report 2012-01-14 10:16:54 +01:00
Lukáš Lalinský
40bf52e70f Reverse the version check, similarly to what mp4v2 does 2012-01-10 17:18:20 +01:00
Lukáš Lalinský
b981b6dde7 Check also for the deprecated GIF type 2012-01-08 15:54:15 +01:00
Lukáš Lalinský
c237998983 Support non-UTF8 free-form atoms 2012-01-08 13:17:42 +01:00
Urs Fleisch
5ff810e98d Support for ID3v2.2 frames used by iTunes (TCP, TS2, TSA, TSC, TSP, TST)
https://bugs.kde.org/show_bug.cgi?id=290330
2012-01-05 16:33:29 +01:00
Michael Helmling
7875d02a8f Merge remote-tracking branch 'official/master' 2012-01-04 19:49:50 +01:00
Scott Wheeler
baafb3e290 Funny that there managed to be no operator!= for String for so long. 2012-01-01 16:01:18 +01:00
Michael Helmling
c4cef55158 Added tests and information about ignored id3 frames.
The ID3v2::toDict() function now has an optional
StringList* argument which will contain information
about frames that could not be converted to the dict
interface.
There are some dict tests for APE and FLAC now, and the
ID3v2 test was enlarged.
2012-01-01 14:42:48 +01:00
Michael Helmling
0eaf3a3fbd Implemented dict interface for more formats.
Now supported: MOD files (IT, MOD, S3M, XM), RIFF files
(AIFF, WAV), TrueAudio, WavPack.
2011-11-02 21:02:35 +01:00
Michael Helmling
292a377d1e Merge remote-tracking branch 'official/master' 2011-10-30 18:28:52 +01:00
Lukáš Lalinský
6ea8599313 Detect RIFF files with invalid chunk sizes
The bug report has a WAVE file with zero-sized 'data' chunk, which causes
TagLib to iterate over the file, 8 bytes in each iteration. The new code
adds a check for the chunk name, which forces it to mark the file as
invalid if the chunk name doesn't contain ASCII characters.

https://bugs.kde.org/show_bug.cgi?id=283412
2011-10-08 18:41:15 +02:00
Michael Helmling
772bc9f7c4 Further cleanup and simplification in id3v2dicttools 2011-09-12 21:52:11 +02:00
Michael Helmling
0c2ca20ec2 Restructured and simplified ID3v2Tag::fromDict(). 2011-09-11 22:07:49 +02:00
Michael Helmling
2d31075047 Splitted ID3v2Tag::toDict() into several functions.
This should simplify future transition to virtual functions.
2011-09-11 18:22:15 +02:00
Graham Perks
837c9ef288 Add cmake option for visibility=hidden 2011-09-09 10:17:54 -05:00
Michael Helmling
0356249368 Merge remote-tracking branch 'official/master' 2011-09-01 16:33:39 +02:00
Michael Helmling
5647b2e293 Made im/export functions nonvirtual. Added similar functions to File and
its subclasses. TagLib::File contains a bunch of dynamic_casts to call
the correct specializations.
2011-08-28 22:58:40 +02:00
Lukáš Lalinský
686bcf55a9 Add support for iPhone ringtones 2011-08-28 11:02:34 +02:00
Michael Helmling
fa8159a9d0 Added toDict and fromDict methods for APE tags. 2011-08-27 22:30:20 +02:00
Michael Helmling
58db919e43 More support for the unified dictionary interface.
Addded fromDict() function to ID3v2Tag. Added fromDict() and
toDict() functions to the TagUnion class (uses the first non-empty tag).
Added fromDict() and toDict() functions for the generic Tag class, only
handling common tags without duplicates. Addded preliminary mp3 test
case. Python3 bindings now available on my github site.
2011-08-27 01:18:21 +02:00
Michael Helmling
b262180857 Some preliminary work for unified dictionary tag interface support.
- toDict() and fromDict() for XiphComments
- toDict() for ID3v2 Tags
2011-08-26 21:48:40 +02:00
Tim De Baets
bec3875b94 Added removePicture() to FLAC::File 2011-08-16 01:57:01 +02:00
Urs Fleisch
ce53d13af1 Add suport for more MP4 metadata atoms
https://bugs.kde.org/show_bug.cgi?id=275784
2011-08-13 17:07:41 +02:00
Mathias Panzenböck
4868bb5690 ByteVector::replace: test shrinking 2011-08-06 19:43:17 +02:00
Jonathan Liu
7cc36db760 Use the default frame factory when it's necessary to parse ID3v2 tags in APE files
https://bugs.kde.org/show_bug.cgi?id=278773
2011-08-06 11:05:20 +02:00
Lukáš Lalinský
028f831417 Basic tests for ByteVector::replace() 2011-08-05 18:47:53 +02:00
Lukáš Lalinský
303af305db Merge remote branch 'panzi/master' 2011-08-05 18:35:24 +02:00
Johannes Pfau
22b57f4463 Add taglib_free function to C binding 2011-08-05 13:17:42 +02:00
Mathias Panzenböck
11c993e9f0 use DATA() macro 2011-08-01 15:33:27 +02:00
Mathias Panzenböck
3b14dc3e94 ByteVector::replace: forgot detach() and opt. when pattern not found 2011-08-01 15:14:58 +02:00
Mathias Panzenböck
ad7645f8e9 ByteVector::replace performance improvements 2011-08-01 04:13:55 +02:00
Lukáš Lalinský
fb2decb7de Reformatting 2011-07-28 19:16:32 +02:00
Lukáš Lalinský
3a837e7fc7 Reformatting 2011-07-28 19:06:35 +02:00
Lukáš Lalinský
0730076a0f Merge remote-tracking branch 'gperks/master'
Conflicts:
	taglib/asf/asfpicture.cpp
	taglib/it/itproperties.h
2011-07-28 19:03:46 +02:00
Lukáš Lalinský
364a840d83 Merge remote-tracking branch 'setosha/ASFPicture_warning_fix' 2011-07-28 18:53:57 +02:00
Scott Wheeler
e9cd383139 Merge pull request #14 from sbooth/master
Some non-PCM wave files can cause SIG_ARITHMETIC
2011-07-28 05:45:11 -07:00
Stephen F. Booth
a41b32bbb2 Don't crash when wav files have a 0 for bit per channel (sampleWidth)
I've seen this in a wav that has an audio format of MP3 (0x55)
2011-07-28 08:36:14 -04:00
Scott Wheeler
98d6b97798 Fix warning 2011-07-27 23:22:23 +02:00
Scott Wheeler
019fe4843f ByteVector works on chars, not unsigned chars, so there needs to be a cast before the comparison 2011-07-27 23:14:54 +02:00
Scott Wheeler
bb25953767 These methods can't be protected since they're called from IT::File
In general this code could use a fair bit of tidying up both stylistically and semantically.
2011-07-27 23:07:38 +02:00
Scott Wheeler
4795831b4a Fix spelling / formatting in comments. 2011-07-27 23:06:06 +02:00
Graham Perks
19484c059d Document ENABLE_STATIC_RUNTIME 2011-07-27 14:35:24 -05:00
Graham Perks
10ea76ff11 Add build option for Visual Studio to link with the static runtime (/MT vs /MD), pass -DENABLE_STATIC_RUNTIME=ON to cmake 2011-07-27 14:25:26 -05:00
Graham Perks
5f84bbf61a Correction to OS X build; include basic Windows build instructions 2011-07-27 10:54:33 -05:00
Graham Perks
8b647e5fa7 Fix for VS2010 which had been throwing out "cannot access protected member declared in class 'TagLib::Mod::Properties'" errors. 2011-07-26 21:45:32 -05:00
Graham Perks
0341079b92 Misc typo corrections 2011-07-26 21:45:28 -05:00
Graham Perks
1a53bfd71a Example cmake for OS X to build a static library 2011-07-26 11:12:27 -05:00
Graham Perks
6aa41d8180 Updated OS X build instructions 2011-07-25 17:56:42 -05:00
Scott Wheeler
101a624c46 Merge branch 'master' of github.com:taglib/taglib 2011-07-21 00:06:50 +02:00
Lukáš Lalinský
3b4e4357e6 Only include config.h if HAVE_CONFIG_H is defined 2011-07-20 22:06:28 +02:00
Scott Wheeler
3baf0a413d Missing const 2011-07-18 21:27:59 +02:00
Anton Sergunov
68c6a7da7a ASFPicture fix warning
class/struct thing

Signed-off-by: Anton Sergunov <setosha@gmail.com>
2011-07-01 16:12:04 +07:00
Mathias Panzenböck
2fd10b5fd5 corrected comments 2011-06-28 02:55:03 +02:00
Mathias Panzenböck
a50886c3c7 Merge branch 'master' of https://github.com/taglib/taglib 2011-06-28 01:37:48 +02:00
Mathias Panzenböck
2119494cd1 added uninstall target 2011-06-26 21:58:51 +02:00
Scott Wheeler
843070ba18 Tabs be gone 2011-06-26 21:37:01 +02:00
Mathias Panzenböck
57bf96d169 Merge branch 'master' of https://github.com/taglib/taglib 2011-06-26 20:58:32 +02:00
Lukáš Lalinský
937d69f91d Fix indentation 2011-06-25 12:17:31 +02:00
Mathias Panzenböck
f3447ae38d style fixes for enum value names 2011-06-25 01:54:22 +02:00
Mathias Panzenböck
89861cf77a style fixes: { on same line with if/else/for 2011-06-25 01:10:19 +02:00
Mathias Panzenböck
a04d7d0bbc Merge branch 'master' of https://github.com/taglib/taglib
Conflicts:
	taglib/CMakeLists.txt
	tests/CMakeLists.txt
2011-06-24 23:59:11 +02:00
Stephen F. Booth
39e8cbbefb Added sampleFrames() to AIFFProperties and WAVProperties 2011-06-24 10:43:13 -04:00
Lukáš Lalinský
6b063862c3 Remove the old qmake project file, you can use CMake to build a framework now 2011-06-24 09:00:23 +02:00
Lukáš Lalinský
aec8880592 Update INSTALL to not mention the optional file formats and add info about building a framework 2011-06-24 08:59:38 +02:00
Lukáš Lalinský
dd846904cb Remove the options to disable MP4/ASF support 2011-06-24 08:49:50 +02:00
Mathias Panzenböck
c7fd4cd2fc IT: the max. 8000 bytes msg. length have to include the NUL 2011-06-24 01:53:20 +02:00
Mathias Panzenböck
57526c6c37 IT: add term. NUL to messages 2011-06-24 01:50:43 +02:00
Mathias Panzenböck
af92db9dc0 IT: unit tests 2011-06-24 01:31:15 +02:00
Mathias Panzenböck
2d6274a36a Test FLAC: cleanup copied file 2011-06-24 01:21:17 +02:00
Mathias Panzenböck
9c27c45eb8 IT: strings require term. NUL. mod files: tableLength -> lengthInPatterns
Also added enums for S3M/IT/XM flags.
2011-06-24 01:11:10 +02:00
Mathias Panzenböck
e71806b6df IT: volume is only a byte in size 2011-06-23 20:48:04 +02:00
Lukáš Lalinský
0b34d4f8ee Enable MP4/ASF by default 2011-06-23 20:18:38 +02:00
Mathias Panzenböck
26613473cf forgot to remove debug code 2011-06-23 20:17:54 +02:00
Mathias Panzenböck
561cfdb0ec S3M: unit tests and bug fixes (NUL char. is not optional in S3M strings) 2011-06-23 20:08:05 +02:00
Mathias Panzenböck
e810f2f61f Merge branch 'master' of https://github.com/taglib/taglib 2011-06-23 17:40:36 +02:00
Mathias Panzenböck
7236ef4d0f S3M+IT: fix reading, IT: untested support for message writing
IT: reading was off starting with global volume because of wrong read size.
S3M+IT: correctly read the number of used patterns.
IT: fixed reading of message tag and implemented writing of message tag
(not tested yet).

I also added S3M+IT test files. TODO: Unit tests using them.
2011-06-23 05:41:23 +02:00
Anton Sergunov
b2517aa4a0 default constructor MP4::Tag::Tag() 2011-06-21 00:54:39 +07:00
Mathias Panzenböck
e202c658f0 Merge branch 'master' of https://github.com/taglib/taglib 2011-06-20 14:31:09 +02:00
Wolfgang Plaschg
7448bb353b Include of "tag_c.h" after system libraries. 2011-06-20 03:08:24 +02:00
Mathias Panzenböck
aeb528ade2 XM: forgot smaple count 2011-06-20 02:31:17 +02:00
Mathias Panzenböck
d1cb8ae09d IT: support channels property 2011-06-20 02:19:16 +02:00
Mathias Panzenböck
4b44f25048 comments++ 2011-06-20 01:05:12 +02:00
Mathias Panzenböck
4b754b1bc6 more correct IT parsing and property naming 2011-06-20 00:43:42 +02:00
Mathias Panzenböck
b3d44394bf more correct S3M parsing and property naming 2011-06-19 22:46:33 +02:00
Mathias Panzenböck
5477ede3ea updated comments 2011-06-19 19:37:45 +02:00
Mathias Panzenböck
03534170fa comments++ 2011-06-19 19:35:27 +02:00
Mathias Panzenböck
b30b8c4ab5 IT: no longer allow wrong sample/instrument magic 2011-06-19 06:03:09 +02:00
Mathias Panzenböck
e09c2c5a19 untested(!) comment write support for s3m and it files 2011-06-19 05:42:16 +02:00
Mathias Panzenböck
6afb7c04b3 comment writing support and more tests for mod and xm 2011-06-19 04:27:51 +02:00
Mathias Panzenböck
0143c3ee63 comments++ 2011-06-18 04:28:48 +02:00
Mathias Panzenböck
a31b0bcf8c xm: no \n too much in comment if there are no samples 2011-06-18 03:38:18 +02:00
Mathias Panzenböck
5ad69f6f2a fixed mod property names and added unit test for xm 2011-06-18 03:31:49 +02:00
Lukáš Lalinský
b63508ec3e We still need these includes 2011-06-17 15:09:37 +04:00
Mathias Panzenböck
fe356c31b4 added unit test for one flavour of .mod files 2011-06-17 05:18:49 +02:00
Mathias Panzenböck
eec5e33e0d added check for readOnly in save methods 2011-06-14 15:34:16 +02:00
Mathias Panzenböck
868ce3dd21 added myself to AUTHORS 2011-06-14 15:23:11 +02:00
Mathias Panzenböck
1e6d645ce9 fixed a comment 2011-06-14 03:56:32 +02:00
Mathias Panzenböck
65fb9733b9 added mod (+aliases) to defaultFileExtensions 2011-06-14 03:49:33 +02:00
Mathias Panzenböck
f75f5ac9bb added .mod file support 2011-06-14 03:47:08 +02:00
Mathias Panzenböck
812826fe3a Mod::File -> Mod::FileBase 2011-06-14 01:47:07 +02:00
Mathias Panzenböck
3192334006 more indentation fixes 2011-06-14 01:30:54 +02:00
Mathias Panzenböck
9b2bb4af34 code formatting fixes 2011-06-14 01:18:38 +02:00
Mathias Panzenböck
54e9656474 converted tabs to spaces 2011-06-14 01:09:55 +02:00
Mathias Panzenböck
f6dbd32ed3 refactored for ABI compat and write support of some tags of s3m/it/xm files
tags that can be written:
 * s3m: title
 * it: title
 * xm: title, trackerName
2011-06-14 00:46:23 +02:00
Mathias Panzenböck
5332fb5cf8 added read-only support for s3m, it and xm 2011-06-13 03:19:21 +02:00
Lukáš Lalinský
c3c88b4f55 Merge remote branch 'lalinsky/abstract-io' 2011-06-09 18:58:45 +02:00
Lukáš Lalinský
8eb32577bd Merge branch 'abstract-io' 2011-06-09 18:58:05 +02:00
Lukáš Lalinský
0ed2477dfa Add an empty default implementation of IOStream::clear() 2011-06-09 18:52:48 +02:00
Frank Lai
b3646a0734 Be more careful when parsing Vorbis Comments 2011-06-09 18:44:54 +02:00
Frank Lai
8ed9b0da2c Support for reading ALAC audio properties 2011-06-09 18:41:43 +02:00
Frank Lai
93564a2daa ALAC file encoded by iTunes 2011-06-09 18:40:22 +02:00
Lukáš Lalinský
0a790f0017 Add a (failing) test for reading ALAC audio properties 2011-06-08 19:03:43 +02:00
Lukáš Lalinský
a224e7cd6d Install the new headers 2011-05-28 22:06:41 +02:00
Lukáš Lalinský
088dbfa832 Merge remote branch 'taglib/master' into abstract-io 2011-05-28 22:04:07 +02:00
Stephen F. Booth
a04da3f159 Added read-only support to FileStream 2011-05-28 13:29:06 -04:00
Lukáš Lalinský
dc062a0844 Make RefCounter compile on OS X with the 10.4 SDK
The 10.4 SDK defines OSAtomic functions as int32_t, while 10.5 and newer SDKs
define them as volatile int32_t. This caused a compilation error when
compiling against the 10.4 SDK.

I'd have prefered a preprocessor-based solution, but I couldn't find any
macro that says the SDK version, so I copied this cast solution from
Apple's WebKit. I assume then know what they are doing if they have to
workaround their own API. :)
2011-05-15 00:07:29 +02:00
Scott Wheeler
efeccbf726 Don't lead the scanned blocks on save 2011-05-09 19:06:08 +02:00
Lukáš Lalinský
6b7ed4a5d5 Merge pull request #2 from wplaschg/master
Added ignore rules for MSVC 2008 build results
2011-05-09 10:02:21 -07:00
Wolfgang Plaschg
adb0984c87 Adding ignore rules for MSVC 2008 build results 2011-05-09 16:23:38 +02:00
Lukáš Lalinský
a38d2b2995 Simplify static builds 2011-05-08 15:57:34 +02:00
Lukáš Lalinský
b5b8387aee Don't install pkg-config files when building a framework 2011-05-08 15:50:44 +02:00
Lukáš Lalinský
c337694165 Make it possible to build an OS X framework 2011-05-08 15:46:19 +02:00
Lukáš Lalinský
b2e3a477e9 Always make a copy of the ID3v1 genre name strings
http://thread.gmane.org/gmane.comp.kde.devel.taglib/1876
2011-05-02 22:41:01 +02:00
Lukáš Lalinský
81734919d2 Add info about BUILD_EXAMPLES to the INSTALL file 2011-04-19 12:45:11 +02:00
Lukáš Lalinský
d03ef3c312 Use the PUBLIC_HEADER property to prepare for building an OS X framework 2011-04-18 16:52:47 +02:00
Lukáš Lalinský
e92ed0a830 Remove unnecessary code from tfile.cpp 2011-04-12 14:35:31 +02:00
Lukáš Lalinský
65ca29b3e2 Add a ByteVector-backed stream class 2011-04-12 14:28:02 +02:00
Lukáš Lalinský
26c130c387 Duplicate contructors of File subclasses to accept IOStream* 2011-04-11 23:31:44 +02:00
Lukáš Lalinský
8b59bb5957 Make it possible to actually pass a IOStream instance to File 2011-04-11 23:15:46 +02:00
Lukáš Lalinský
b53a577e38 Add FileStream as a copy of File's methods 2011-04-11 23:12:58 +02:00
Lukáš Lalinský
0b0cbc2e34 Add an abstract IOStream class 2011-04-11 22:46:56 +02:00
Lukáš Lalinský
4cda0eeb7b Make it possible to run the test suite out of the source tree 2011-04-11 18:32:40 +02:00
Lukáš Lalinský
2fa8c93776 The website has more up-to-date links 2011-04-09 20:15:00 +02:00
Lukáš Lalinský
266200d77e Add myself to the AUTHORS file 2011-04-09 20:09:51 +02:00
Lukáš Lalinský
aa84b8b674 Obsolete comment now that we are not in kdesupport 2011-04-09 20:07:15 +02:00
Lukáš Lalinský
ee920a461c Clean up the library CMakeLists.txt file 2011-04-09 20:05:50 +02:00
Lukáš Lalinský
1596dc7c69 Clean up the main CMakeLists.txt file 2011-04-09 19:51:23 +02:00
Lukáš Lalinský
f3d3af9355 Don't set unnecessary compiler options 2011-04-09 19:42:56 +02:00
Lukáš Lalinský
9653796640 Merge branch 'master' of github.com:taglib/taglib 2011-04-09 19:19:49 +02:00
Lukáš Lalinský
a4a097d2f8 Merge branch 'stable' 2011-04-09 19:16:01 +02:00
Modestas Vainius
d112a68193 Support building documentation out-of-source-dir 2011-04-09 19:15:46 +02:00
Lukáš Lalinský
5eda17aa96 NEWS entries 2011-04-06 00:08:42 +02:00
Lukáš Lalinský
8878c9158c Upgrade IPLS (2.3) to TIPL (2.4) 2011-04-05 17:08:25 +02:00
Lukáš Lalinský
3715b96477 Protect against incorrect ID3v2 version parameter 2011-04-05 15:36:23 +02:00
Lukáš Lalinský
aa57db3a39 Convert frames TIPL and TMCL (2.4) to IPLS (2.3) 2011-04-05 15:16:17 +02:00
Lukáš Lalinský
f9d38129b8 Merge branch 'master' into id3v23 2011-04-05 14:37:36 +02:00
Lukáš Lalinský
0c6e2a0aa9 NEWS entry 2011-03-30 09:19:25 +02:00
Martijn van Rheenen
e16829190a Fix DRM detection in WMA files 2011-03-30 09:15:28 +02:00
Lukáš Lalinský
7a6647cb99 Untested version of DRM checking in WMA files 2011-03-29 15:49:24 +02:00
Lukáš Lalinský
97cd58bc65 Check for the presence of the drms atom in MP4 files 2011-03-29 15:41:17 +02:00
M.A. Brand Consulting
8f42d5b594 Make it possible to build a static version of the C bindings
https://bugs.kde.org/show_bug.cgi?id=268441
2011-03-19 08:28:35 +01:00
Lukáš Lalinský
158152cb46 Use the same SO versioning as we had with automake/libtool
http://article.gmane.org/gmane.comp.kde.devel.taglib/1826
2011-03-19 08:18:34 +01:00
Lukáš Lalinský
f624d6e2af Don't overwrite fields that already exist
We can have multiple fields in the Vorbis Comment (e.g. two artist names),
but TagUnion only takes the first one, so it will effectively strip the
extra fields.

https://bugs.kde.org/show_bug.cgi?id=268854
2011-03-19 07:42:47 +01:00
Lukáš Lalinský
d3e79ddc38 Partial protection against broken WMA files
This fixes the problem on the reported file, but in general this code
needs a lot more checks.

https://bugs.kde.org/show_bug.cgi?id=268401
2011-03-19 07:42:23 +01:00
Lukáš Lalinský
71e224fed8 Don't overwrite fields that already exist
We can have multiple fields in the Vorbis Comment (e.g. two artist names),
but TagUnion only takes the first one, so it will effectively strip the
extra fields.

https://bugs.kde.org/show_bug.cgi?id=268854
2011-03-19 07:37:28 +01:00
Lukáš Lalinský
80decd737d Define NOMINMAX so that windows.h doesn't define it's own versions
http://article.gmane.org/gmane.comp.kde.devel.taglib/1833
http://www.devx.com/tips/Tip/14540
2011-03-19 07:26:55 +01:00
Lukáš Lalinský
d169a670e0 Merge branch 'master' into id3v23 2011-03-17 09:16:29 +01:00
Scott Wheeler
a6cb74ad5d Ignore docs and OS X dylibs 2011-03-17 08:01:33 +01:00
Scott Wheeler
27aa8cc293 These aren't needed anymore now that we're not in kdesupport 2011-03-17 07:57:24 +01:00
Lukáš Lalinský
d3df66f196 Convert TDRC to TYER+TDAT+TIME 2011-03-16 22:54:58 +01:00
Lukáš Lalinský
1453a7b157 Clean-up temporary files 2011-03-16 17:19:11 +01:00
Lukáš Lalinský
e8d0551c9a Simple ID3v2.4 => ID3v2.3 frame migration 2011-03-16 17:14:36 +01:00
Lukáš Lalinský
061b381ea8 Make sure we don't write UTF8 or UTF16BE to ID3v2.3 tags 2011-03-15 21:57:49 +01:00
Lukáš Lalinský
1802237c75 Support for writing structuraly correct ID3v2.3 tags
We don't use the tag footer, extended header or unsynchronization, so we
only need to change the frame size format.

Note that this doesn't write correct ID3v2.3 tags, just tags that have
the correct structure. The content is sill incorrect, unless you add
the right frames manually to the tag instance.
2011-03-15 20:50:47 +01:00
Lukáš Lalinský
4bdcc9662e Partial protection against broken WMA files
This fixes the problem on the reported file, but in general this code
needs a lot more checks.

https://bugs.kde.org/show_bug.cgi?id=268401
2011-03-13 21:33:57 +01:00
Lukáš Lalinský
41f1828719 Use the memory barrier variants on OS X 2011-03-12 23:21:54 +01:00
Lukáš Lalinský
223b85d345 Use GCC automic builtins where possible 2011-03-12 23:19:01 +01:00
Lukáš Lalinský
ee49b781eb Add .gitignore 2011-03-11 15:16:05 +01:00
Lukáš Lalinský
065fcd5077 Merge branch 'release-1.7' 2011-03-11 14:16:11 +01:00
Lukáš Lalinský
b3ae839a38 Add release date 2011-03-11 14:15:38 +01:00
Lukáš Lalinský
cce88b7005 News for 1.7 2011-03-11 13:21:54 +01:00
Lukáš Lalinský
311be56432 Merge commit 'eee860f9c6' into release-1.7 2011-03-11 13:19:35 +01:00
Lukáš Lalinský
5685dd078f Fix memory leaks in the FLAC parsing code
Thanks to Daniel Schaack for reporting these.
2011-03-11 10:29:27 +01:00
Nick Shaforostoff
38219b88b3 ups, revert my accidentally commited debug output
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1224409 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-03-10 17:30:22 +00:00
Nick Shaforostoff
0cdfa793e9 use atomic refcounting on mac and win32, todo for linux
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1224407 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-03-10 17:29:30 +00:00
Raphael Kubo da Costa
eee860f9c6 Fix build when the 'uint' typedef is already defined.
Using uint in those structs gave me the following error:

  /home/rakuco/kde4/src/kdesupport/taglib/taglib/riff/rifffile.cpp:38:
error: reference to 'uint' is ambiguous
  /usr/include/sys/types.h:56: error: candidates are: typedef unsigned
int uint

Is it really necessary to have those typedefs in taglib.h? It'd be
nice to at least check if they are not being redefined.

CCMAIL: lalinsky@gmail.com



git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1223282 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-03-02 03:05:28 +00:00
Lukáš Lalinský
10fff6d797 Update the AIFF test
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1222753 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-25 19:43:25 +00:00
Lukáš Lalinský
7cc1ce1c36 Fix the patch from r1222376
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1222752 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-25 19:42:49 +00:00
Nick Shaforostoff
272719e666 a formal change: convert rifffile.cpp to use vector of structs instead of several vectors of simple types
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1222376 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-23 09:16:25 +00:00
Nick Shaforostoff
d21ff8be54 divide by 1000 instead of 1024 when calculating riff bitrate to get standard 1411 kbps bitrate on AudioCD wavs
CCMAIL:taglib-devel@kde.org



git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1222375 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-23 08:58:17 +00:00
Lukáš Lalinský
f89c16cd65 More news
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220247 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 12:47:52 +00:00
Lukáš Lalinský
be8fff3768 Automatically generate the version number in taglib-config
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220246 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 12:45:24 +00:00
Lukáš Lalinský
263832cf6a CMake-specific INSTALL file
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220241 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 12:36:04 +00:00
Lukáš Lalinský
95c09d232d Add svn:ignore
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220239 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 12:25:39 +00:00
Lukáš Lalinský
378fd15b54 Move docs building to CMake
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220238 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 12:22:42 +00:00
Lukáš Lalinský
2f9838a440 *poof*
I've warned people about removing autoconf/automake support for a long time,
so let's make it happen for 1.7. CMake is now the only supported build system.
I'll update build docs in a following commit.

CCMAIL:taglib-devel@kde.org


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220235 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 11:50:25 +00:00
Lukáš Lalinský
4b00ef4acb Set the version number to 1.7
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220230 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 10:59:33 +00:00
Lukáš Lalinský
c21fd955ff Fix writing of new RIFF chunks at even positions
If the last chunk had an odd size, the new chunk would have been written at
odd position, which is incorrect.

This is based on the patch by Jens Dyffort, but I ended up changing the
implementation to correctly handle subsequential updates to the file.

The whole RIFF code really needs to be rewritten in a different way...

BUG:243954


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1220223 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-02-13 10:27:56 +00:00
Nick Shaforostoff
ad0494bb7e formal change: combine if-conditions for identical bodies
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1218105 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-31 12:24:30 +00:00
Lukáš Lalinský
7c776935e4 Revert r1217775
Please see my post in the mailing list. This can be done, but in a different way.

CCMAIL:shafff@ukr.net


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1218000 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-30 12:50:38 +00:00
Nick Shaforostoff
a4f53d9b4a disable creation of unknown objects for wma files, because we've seen the cases when it could be as large as whole file, and we are greedy for the ram
CCMAIL:lalinsky@gmail.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1217775 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-28 15:14:04 +00:00
Nick Shaforostoff
c56c0a3d0c fix crash on wma file parsing, add clarifications to API docs
CCMAIL: wheeler@kde.org



git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1217766 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-28 13:18:36 +00:00
Lukáš Lalinský
299e3f0ad6 Define a macro to properly construct std::bitset
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1216679 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-24 07:32:31 +00:00
Lukáš Lalinský
df86f45dad Back to unsigned long, it breaks compilation on Solaris
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1216598 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-24 06:02:15 +00:00
Lukáš Lalinský
b051df0062 Fix compilation on MSVC 2010 with the C++0x version of std::bitset
Hopefuly it doesn't break anything on older compilers...


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1216365 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-22 21:07:16 +00:00
Lukáš Lalinský
0087895206 News
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1214792 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-16 12:06:21 +00:00
Lukáš Lalinský
735e52392b Fixed copyright headers
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1214790 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-16 12:03:37 +00:00
Lukáš Lalinský
1352a4e0c3 Consistency with the rest of TagLib
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1214789 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-16 12:00:52 +00:00
Lukáš Lalinský
fb3cca2c44 Support for ASF embedded pictures
Patch by Anton Sergunov <setosha@gmail.com>

CCMAIL: setosha@gmail.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1214788 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-16 11:57:12 +00:00
Lukáš Lalinský
393e9c5572 Fix FSF address
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1212872 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-08 11:20:09 +00:00
Lukáš Lalinský
6f68c30db3 Fix memory leak in AttachedPictureFrameV22
BUG:257007


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1212871 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-08 11:14:47 +00:00
Lukáš Lalinský
085a54b67d Fix FLAC tests
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1212870 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-08 11:13:46 +00:00
Lukáš Lalinský
b43c149138 Documentation fix
CCBUG:209252


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1212867 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-08 11:00:36 +00:00
Lukáš Lalinský
3741c39295 Full read/write support for FLAC pictures
NEEDS MORE TESTING

BUG:218696


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1212863 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2011-01-08 10:36:26 +00:00
Scott Wheeler
d16be3fa98 Generate docs for ASF / MP4 as well
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1202935 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-12-02 20:08:43 +00:00
Andreas Hartmetz
fad0724bff Install flacmetadatablock.h. Required to make Amarok compile.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1201859 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-11-28 22:06:34 +00:00
Lukáš Lalinský
5c930a6a8c Work-in-progress support for writing FLAC picture
This will enable the possibility to add support for accessing the Seektable
and Cuesheet blocks, but I'm not planning on implementing that right now.

CCBUG:218696


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1201717 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-11-28 12:54:52 +00:00
Lukáš Lalinský
d21d8f9f3c More tests for WavPack audio properties
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1201478 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-11-27 21:12:14 +00:00
Lukáš Lalinský
56343767ce Fix reading of WavPack streams without a length information in the header
When the WavPack's total_samples header fiels contains -1, try to find
the final block and get the number of samples from there as
block_index + block_samples.

BUG:258016


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1201476 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-11-27 20:58:57 +00:00
Lukáš Lalinský
15d139e271 Docs
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1201208 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-11-27 07:32:32 +00:00
Lukáš Lalinský
259a9a1a14 Explicitly check for -1 in WavPack length
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1201207 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-11-27 07:32:16 +00:00
Lukáš Lalinský
874d495b29 Accept both "ID3 " and "id3 " as valid ID3 chunk IDs in RIFF files
Patch by Stephen F. Booth


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1191982 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-11-01 16:32:37 +00:00
Scott Wheeler
306aee3e7d Different LGPL version than was referenced in headers
CCMAIL:groot@kde.org

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1178016 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-09-22 00:07:26 +00:00
Lukáš Lalinský
32a10b53d5 Fix Automake build
Patch by Stephen F. Booth


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1167433 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-08-24 15:50:35 +00:00
Lukáš Lalinský
1c225ed37a Added information about the number of bits per sample in WAVE and AIFF files
Patch by Stephen F. Booth


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1167432 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-08-24 15:49:47 +00:00
Lukáš Lalinský
f887f5eec3 Make sure TAGLIB_EXPORT is empty when TAGLIB_STATIC is defined
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1160977 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-08-09 12:17:30 +00:00
Lukáš Lalinský
dcef0fbad2 Read-only support for FLAC picture blocks
CCBUG:218696


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1154376 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-25 11:06:36 +00:00
Lukáš Lalinský
0f979667be Don't unnecessarily include whole <iostream>
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1153989 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-24 13:17:01 +00:00
Lukáš Lalinský
5aed3681fb Missing file
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1148734 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-11 17:45:47 +00:00
David Faure
3cca3f17c5 I think you forgot a file :)
CCMAIL: lalinsky@gmail.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1148727 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-11 17:34:23 +00:00
Lukáš Lalinský
7426a64d2b Added FLAC::Properties::signature()
BUG:160172


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1148630 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-11 10:26:35 +00:00
Lukáš Lalinský
1d10bde500 Added reading of WAV audio length
BUG:116033


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1148614 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-11 09:47:58 +00:00
Lukáš Lalinský
49631a3013 Implemented a specialized version of APE::Tag::isEmpty()
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1148318 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-10 09:22:53 +00:00
Lukáš Lalinský
ab7e997bc6 Don't try to save read-only MP4 files
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1145556 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-03 11:36:08 +00:00
Lukáš Lalinský
a33f161999 Unused private attributes
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1145555 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-03 11:34:29 +00:00
Lukáš Lalinský
ab1bc06172 Support for reading/writing tags from Monkey's Audio files
Patch by Alex Novichkov, slightly modified by me (code formatting + tests).


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1145554 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-07-03 11:32:27 +00:00
Lukáš Lalinský
8792f8df82 Final changes
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1115755 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-17 11:31:35 +00:00
Lukáš Lalinský
9dcdecc810 Fix parsing of regular 32-bit integers in SynchData::toUInt()
BUG:231075


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1115275 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-15 20:22:21 +00:00
Lukáš Lalinský
f6478a4172 Add a BIC comment about merging String::toInt
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1114105 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-12 18:53:27 +00:00
Lukáš Lalinský
91f94f593b Info about the new toInt method
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1114094 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-12 18:41:10 +00:00
Lukáš Lalinský
10e4350410 Updated NEWS
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1114093 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-12 18:35:41 +00:00
Lukáš Lalinský
414a49cc16 Include taglib_config.h by default
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1114090 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-12 18:32:04 +00:00
Lukáš Lalinský
19b2341411 Fix upgrading of ID3v2.3 genre with number 0 (Blues)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1114089 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-12 18:27:59 +00:00
Lukáš Lalinský
d5eb51e452 Update all version numbers to 1.6.3
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1114073 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-12 17:43:03 +00:00
Scott Wheeler
2811d24efa Update to current automake
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1113098 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-09 22:51:26 +00:00
Lukáš Lalinský
f7f46b2320 Fix release date
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1112833 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-09 09:37:51 +00:00
Scott Wheeler
c823c21eb2 Forward declarations don't need exports.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1111035 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 17:33:01 +00:00
Lukáš Lalinský
aee204df54 Ok, actually change the API version
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110990 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 15:31:23 +00:00
Lukáš Lalinský
7f860790ec There is actually one new function, so the API version needs to be different
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110988 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 15:20:46 +00:00
Lukáš Lalinský
b1cac7175f Increment version number
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110983 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-04 15:01:21 +00:00
Lukáš Lalinský
e76466097b Don't upgrade ID3v2.2 TDA frame when upgrading to TRCD
We already do this for TDAT. Using both parts, the year and the date,
would be better we the code currently doesn't have enough context to
do that.

BUG:228968


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110552 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-03 16:58:03 +00:00
Lukáš Lalinský
6612abce72 Changelog for 1.6.2
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110546 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-03 16:16:51 +00:00
Lukáš Lalinský
3943668603 Ignore trailing non-data atoms when parsing MP4 covr atoms
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110209 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-02 12:14:32 +00:00
Lukáš Lalinský
2ef8fc5118 Save ASF attributes larger than 64k to the metadata library object
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1110205 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-04-02 11:53:28 +00:00
Scott Wheeler
4202ce3ec9 Update .pro file
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1100537 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-03-07 19:03:35 +00:00
Lukáš Lalinský
0d16255d09 Fix compilation fo the test runner on Windows
Patch by Stephen Hewitt


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1078612 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-01-22 13:30:05 +00:00
Lukáš Lalinský
d394317767 MP4 int pair atoms should have flags set to 0
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1078611 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2010-01-22 13:28:14 +00:00
Lukáš Lalinský
9e9077d1e0 Be more paranoid about checking MP4 files
To consider something a valid MP4 file, it must have a 'moov' atom. Otherwise
it's marked as invalid and we won't try to read/write tags.

CCBUG:216819


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1062426 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-14 18:42:40 +00:00
Urs Wolfer
b11d2e8b56 optimizegraphics: Losslessly optimized PNG and SVGZ files with "optipng -o5" and "advdef -z -4".
Reduced disk space: 10144KB (9MB)

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1062098 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-13 19:51:03 +00:00
Lukáš Lalinský
74c3c282c4 Handle WM/TrackNumber with DWORD content
The default type for this attribute is String, but even MSDN suggests to
support also DWORD, because some applications write such files.

BUG:218526


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1062026 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-13 15:32:55 +00:00
Lukáš Lalinský
004551faec Fix tagreader_c.c to not try to access invalid pointers
BUG:218334


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1061671 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-12 16:44:34 +00:00
Scott Wheeler
5df7692aa1 pedantry++
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1057066 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-01 12:01:43 +00:00
Peter van Hardenberg
85df71ea2e When decoding syncsafe integers, assume non-syncsafe integers are written by buggy software and treat them as normal integers.
From Songbird bug 12964, original author Mike Smith (msmith@songbirdnest.com)

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1056922 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-12-01 09:11:21 +00:00
Alexander Neundorf
1b6ab18080 this patch should make taglib build with the Sun Studio compiler (http://bugs.kde.org/show_bug.cgi?id=215225)
Alex




git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1054212 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-25 18:45:13 +00:00
Lukáš Lalinský
0f0f2f7288 Explicitly say that we are using TagLib::File (CCBUG:213544)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1046111 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-07 15:05:25 +00:00
Lukáš Lalinský
4c70372fe4 Fixed a memory leak in FileRef's OGA format detection
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1044769 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-04 15:37:21 +00:00
Lukáš Lalinský
d81af82ec4 Add test_flac.cpp to Makefile.am
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1043989 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-02 19:54:10 +00:00
Lukáš Lalinský
44c08b8ca2 New utility class to make sure temporary files are always deleted
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1043988 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-02 19:53:15 +00:00
Lukáš Lalinský
c962d78a57 Always read tags from the first Vorbis Comment block in FLAC files
Prevously TagLib saved tags to the first block, but read them from the
last one. Having multiple VC blocks is a non-standard situation, but
this is the best we can do (libFLAC also uses the first block in the
case of multiple VC blocks). 

BUG:211089


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1043985 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-11-02 19:41:12 +00:00
Scott Wheeler
2039c725f4 Missing "not" in docs.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042978 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 11:32:31 +00:00
Lukáš Lalinský
dcf4c7458b A few more version numbers. We really need a way to automate this :(
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042960 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 09:57:13 +00:00
Lukáš Lalinský
de162a9734 Update version in API docs
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042958 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 09:43:51 +00:00
Lukáš Lalinský
d685cd6e47 Bump version numbers
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042955 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 09:23:58 +00:00
Lukáš Lalinský
f1abbf33f2 A little more complex checking for broken files
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042948 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 08:59:40 +00:00
Lukáš Lalinský
5a40a45cc5 Make sure we are not trying to read a file where MP4 atom header != 8 bytes
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042945 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-31 08:36:26 +00:00
Lukáš Lalinský
76b6d4fc9e Fixed ID3v1-style genre to string conversion in MP4 files
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1042312 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-29 15:53:20 +00:00
Lukáš Lalinský
e8281e1b9f Support for MP4 cover art
CCMAIL:martin.trashbox@gmail.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039809 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 16:55:54 +00:00
Lukáš Lalinský
bffd4da8b6 Return NULL/false rather than crash when accessing file attributes in FileRef
BUG:209417


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039724 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:45:58 +00:00
Lukáš Lalinský
fa1a23fe5c Changelog for 1.6.1
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039711 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:22:10 +00:00
Lukáš Lalinský
4e9b41f540 Proper .oga file handling in FileRef
This fixes a problem introduced in r983337. OGA files are mostly likely going
to be Ogg::FLAC, if applications are following the Xiph recommendation. But
they can be using any Ogg codec, so we must check multiple formats (Sound Juicer
on Ubuntu used to produce .oga files for Ogg Vorbis, I believe it doesn't do that
anymore).


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039708 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:17:08 +00:00
Lukáš Lalinský
724a68c79c Don't wrote the Vorbis framing bit to OggFLAC files
https://bugs.launchpad.net/maxosx/+bug/445970
http://www.hydrogenaudio.org/forums/index.php?showtopic=75263

CCMAIL:me@sbooth.org


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039704 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 12:01:40 +00:00
Lukáš Lalinský
03c63a11a5 Set visibility("default") for GCC on exported symbols
This does nothing with the current configuration, but it's useful if you compile the library with -fvisibility=hidden

Patch by Modestas Vainius


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1039693 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-24 11:07:41 +00:00
Lukáš Lalinský
ea9dbfd7ae Add missing exports for a few public ID3v1 functions
Patch by Modestas Vainius


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1038114 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-20 16:45:10 +00:00
Lukáš Lalinský
af65fefef7 Fix typo in taglib_c.pc
Patch by Modestas Vainius to fix a bug reported in Debian - http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=524696


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1038111 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-20 16:41:59 +00:00
Jeff Mitchell
752a21edc9 Fix copy+paste typos
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1035209 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-14 14:44:15 +00:00
Lukáš Lalinský
18c621cdc2 Always use #include "XXX" in TagLib's code
Patch by Stephen F. Booth, thanks!


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1033289 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-10-09 21:03:59 +00:00
Lukáš Lalinský
be2f9ad6e5 This value should be bool, not int
Since bool and int have the same size on x86 architectures, this worked for
me, but since they have a different size on ppc64, it caused the test to
fail. See http://marc.info/?l=taglib-devel&m=125291701231305&w=2 for details.

We should store the type in MP4::Item and do some type checking to avoid
mistakes like this...


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1023246 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-14 10:25:34 +00:00
Lukáš Lalinský
f6083f327f Remove extra commas from configure.in.in
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1022859 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-13 11:30:19 +00:00
Lukáš Lalinský
8b43367eb4 Update libtool version-info
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1022852 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-13 11:17:49 +00:00
Lukáš Lalinský
639b604a55 Changelog
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1022849 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-13 11:15:54 +00:00
Christophe Giboudeaux
482431286e Remove a non-existing dir.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1022837 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-13 10:19:34 +00:00
Lukáš Lalinský
cc7c66bf86 Upgrade obsolete gnre MP4 atoms to ©gen
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1021692 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-09 20:11:29 +00:00
Lukáš Lalinský
db3db34e21 Fix building of examples with ENABLE_STATIC
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1021651 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-09 18:16:38 +00:00
Lukáš Lalinský
9b17ca219c Add option for building a static version of taglib
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1021124 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-08 08:52:57 +00:00
Lukáš Lalinský
f644bafa44 Use the internal config names
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1021106 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-08 07:26:12 +00:00
Lukáš Lalinský
06f405f719 Add support for a global, installable config header
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1019671 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-04 09:29:59 +00:00
Lukáš Lalinský
cf83551c93 Define MAKE_TAGLIB_LIB from the automake build system
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1019659 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-04 09:07:27 +00:00
Lukáš Lalinský
0adea10728 Fix compilation warnings
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1019655 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-04 08:50:24 +00:00
Lukáš Lalinský
b26f8bf5a8 Autoconf options for enabling MP4 and ASF support
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1019514 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-03 19:14:12 +00:00
Lukáš Lalinský
92391e38e8 Fix version in configure.in.in
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1019491 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-03 18:32:16 +00:00
Lukáš Lalinský
41fd27a5d2 Update docs and version numbers
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1019481 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-03 18:05:58 +00:00
Lukáš Lalinský
67bdd5b8d1 Split Ogg packets larger than 64kb into multiple pages
The implementation is not very efficient, but the current Ogg
code makes it hard to write it properly. :(

Patch by Marc Halbruegge
BUG:171957


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1019459 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-09-03 17:20:29 +00:00
David Faure
ee7703d29b svn is weird, I have deleted this external in 1010855 already
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1012887 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-08-18 10:06:44 +00:00
David Faure
624b8594ca another tool which is not necessary in this copy
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1010859 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-08-13 14:48:07 +00:00
David Faure
52fba4ec09 replace external with a copy of the admin dir, as suggested by Jeff Mitchell
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1010858 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-08-13 14:46:52 +00:00
David Faure
3ffe65c5f4 replace external with a copy of the admin dir, as suggested by Jeff Mitchell
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1010855 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-08-13 14:44:55 +00:00
Lukáš Lalinský
9b7463225a Add a check to not crash on corrupted files
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1005918 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-08-02 15:17:36 +00:00
Lukáš Lalinský
93272b4181 Add missing tests to Makefile.am
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1003760 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-28 19:08:40 +00:00
Lukáš Lalinský
d10c9e9166 Add a changelog
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1003757 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-28 18:57:49 +00:00
Lukáš Lalinský
8636eb749a Handle RIFF chunk padding and ignore trailing garbage
This is based on patches by Marc Halbruegge, but those only deal with
read-only cases. The code now also correctly adds padding to RIFF
chunks, and calculates offsets in chunkData taking the padding into
account.

BUG:171957
BUG:175781


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1003745 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-28 18:29:39 +00:00
Lukáš Lalinský
834d9d6b23 Partial support for 64-bit atoms
We still can't handle actual 64-bit atoms, but we can handle 32-bit sizes
stored in 64 bits.

CCBUG:198730


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@1001897 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-24 13:08:51 +00:00
Scott Wheeler
097ae0d785 Use flac padding.
Updated patch from Toby Dickenson

BUG:107659


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@995518 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-12 21:53:18 +00:00
Scott Wheeler
7f0f90b4ea Make docs consistant with behavior.
BUG:178174


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@995471 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-12 19:54:46 +00:00
Lukáš Lalinský
f7fc585665 Don't save ID3v2.2 frames.
Patch by Marc Halbruegge
BUG:176373


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994842 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-11 14:43:58 +00:00
Lukáš Lalinský
0f11c5ab0c Support for ID3v2.2 PIC frames
Patch by Marc Halbruegge
BUG:167786


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994836 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-11 14:27:17 +00:00
Lukáš Lalinský
39e6891c92 Fix off-by-one error in ByteVectorList::split
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994815 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-11 13:24:21 +00:00
Lukáš Lalinský
5e1eb18df9 Try to read track also from TRACKNUM and year from YEAR.
Patch by David Bishop
BUG:144396


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994811 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-11 13:17:06 +00:00
Lukáš Lalinský
59e35efc1b TCON parsing fixes
* Don't join multiple 2.4 TCON fields together
 * Don't add duplicate fields for 2.3 genres where the refinement matches the ID3v1 genre

Patch by Michael Smith
BUG:188578


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994805 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-11 12:55:36 +00:00
Lukáš Lalinský
c92a02b0d7 One more check for invalid frame in AttachedPictureFrame::parseFields
Patch by Mook
BUG:168382


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994361 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-10 14:43:15 +00:00
Lukáš Lalinský
b70e3b2304 Use floting point length to calculate bitrate from the Xing header information
Patch by Mook
BUG:172556


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@994337 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-10 14:34:04 +00:00
Tom Albers
bed793f703 Move external to anonsvn (http://svn.kde.org -> svn://anonsvn.kde.org)
BUG:195492


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@991290 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-04 15:41:38 +00:00
Scott Wheeler
be640ed19f Build on Haiku
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@990628 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-07-02 20:54:32 +00:00
Médéric Boquien
b19a4cf81c .oga files were not processed. Fix this. The problem was that even if the extension was defined in defaultFileExtensions(), it was not defined in create() so the file was never processed. As a
nice side effect, it also fixes the Amarok bug that caused .oga files not to be picked up by the collection scanner.

BUG:178602


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@983337 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-06-18 02:15:19 +00:00
Jeff Mitchell
901a427d1f Fix typo
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@982404 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-06-15 19:40:33 +00:00
Laurent Montel
c6e7812d37 not generate it on win32
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@980173 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-06-11 11:13:48 +00:00
Tanguy Krotoff
98a9b850cf Compilation fix for Visual C++ .NET 2003 (msvc71)
Explanations:
/Zc:wchar_t is recognized by msvc71, /Zc:wchar_t- is not (the - is important and was introduced only with msvc >= msvc80)
Thus /Zc:wchar_t- is recognized as /Zc:wchar_t and this is not what we want :)
Default behavior of msvc71 is already /Zc:wchar_t-

Solution:
Test the msvc version and add the compiler flag only if compiler >= msvc80 (e.g MSVC_VERSION >= 1400)
Same for /D_CRT_SECURE_NO_DEPRECATE and /D_CRT_NONSTDC_NO_DEPRECATE, there were introduced with msvc >= msvc80

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@978720 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-06-07 23:07:32 +00:00
Tanguy Krotoff
fd20da2ef8 Fix a stupid crash inside mp4file.cpp (variable not initialized)
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@978719 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-06-07 23:05:11 +00:00
Lukáš Lalinský
0974882ecd Simplify extension checking in FileRef
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@961189 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-04-29 16:00:39 +00:00
Lukáš Lalinský
a9bce47f96 Add String:rfind
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@961188 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-04-29 15:57:05 +00:00
Lukáš Lalinský
321997c399 Make FileRef handle the .mp4 extension, too
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@961181 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-04-29 15:46:23 +00:00
Lukáš Lalinský
94a402395b Fix off-by-one error in MP4::Tag when looking for free padding to use
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@961160 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-04-29 15:12:19 +00:00
Jeff Mitchell
f1a16bcf0f Style and safety fixes backported from taglib-extras
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@961000 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-04-29 12:55:33 +00:00
Jeff Mitchell
40bdaedb71 This commit adds support for building taglib-extras against taglib during kdesupport build time. If kdesupport is not what is being built, the normal system taglib is used.
This adds forward includes to taglib; these may be very useful to other projects as well, since taglib's includes are rather spread out.  The README file in the include folder has instructions for regenerating them.


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@952369 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-04-11 17:13:24 +00:00
Lukáš Lalinský
33b939c76f Don't build ASF/MP4 FileRef tests if WITH_ASF/WITH_MP4 are undefined
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@945359 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-27 10:45:00 +00:00
Lukáš Lalinský
1eace99153 Detach before appending a character
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@944552 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-25 17:52:23 +00:00
Andreas Hartmetz
98d2808c17 this modified version has the advantage that it compiles
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@942892 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-22 20:48:27 +00:00
Scott Wheeler
fad967ae0b Less of The Big Ugly in the middle of the classes.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@942880 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-22 19:27:38 +00:00
Andrew Coles
56e8766126 Added GCC pragma to suppress non-virtual dtor warning which is being preserved
to maintain BIC.



git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@942876 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-22 19:06:05 +00:00
Jeff Mitchell
36a398a156 Finish making .asf readable, thanks Lukas
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@937985 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-10 22:33:13 +00:00
Jeff Mitchell
f1fd227fce Several of us have seen .asf WMA files in the wild.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@937972 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-10 22:02:20 +00:00
David Faure
c918150b72 Generate config.h in builddir again, and fix compilation when compiling taglib alone
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@937935 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-10 20:27:59 +00:00
Jeff Mitchell
3ec42c7b84 Re-add building things depending on config.h by having it generate in the source tree instead of the build tree, so that when cmake uses a non-source build dir (as it's supposed to) it can actually find the file. I think this is messy, as AFAIK cmake shouldn't be modifying the contents of the source tree...any cmake gurus out there, feel free to let me know if there's a better way.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@937552 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-09 22:20:50 +00:00
Jeff Mitchell
f024f9ab1b This is surely an oversight; fix documentation
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@937541 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-03-09 21:53:46 +00:00
Scott Wheeler
66b3a1a184 Patch from Josef Radinger fixing typo in debug message.
BUG:30212
CCMAIL:taglib-devel@kde.org


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@911772 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-01-16 05:16:48 +00:00
Scott Wheeler
4fbd7c5d93 revert last
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@909079 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-01-10 23:15:33 +00:00
Scott Wheeler
3a390a11d0 Also counts as being empty.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@909060 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-01-10 22:21:45 +00:00
Scott Wheeler
16a7efcd1c remove debug line from mac os framework build file
CCMAIL:taglib-devel@kde.org


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@907136 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2009-01-07 14:14:14 +00:00
Michael Jansen
fc80167a4f Fix build by copying strigis FindCppUnit.cmake to taglib. Build failed because CPPUNIT_LIBRARIES didn't
contain cppunits dependencies reported by cppunit-config.

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@899928 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-12-21 21:46:41 +00:00
Michael Jansen
df3eb22060 Suppress warning about this check missing. if someone has a lower cmake version please check
and decrease the required version if successfull.

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@899927 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-12-21 21:46:37 +00:00
Scott Wheeler
27e3643d19 Should fix the build.
CCMAIL:tbscope@gmail.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@892977 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-12-05 16:43:38 +00:00
Scott Wheeler
977ec6d41f warnings--
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@892694 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-12-05 00:37:39 +00:00
Scott Wheeler
e989d7ad1d fix warnings
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@892447 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-12-04 12:37:36 +00:00
Alexander Neundorf
e2c76396dd -INSTALL_DIR_NAME doesn't have to be set in the toplevel CMakeLists.txt, since it is already set as target property
-remove some unnecessary code
-use BIN_INSTALL_DIR for the RUNTIME destination

Alex




git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@891512 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-12-02 12:06:49 +00:00
Jeff Mitchell
5c0eb1d698 config.h doesn't exist, at least in my checkout, so explicitly defining HAVE_CONFIG_H was breaking build. I'm guessing this was a mistake, and should either be taken out, or
something needs to be fixed.

CCMAIL: lalinsky@gmail.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@883891 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-11-13 19:23:56 +00:00
Jeff Mitchell
1bcb9a6cc7 Add default case switch to fix compiler warnings when ASF or MP4 are not defined.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@883884 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-11-13 19:19:39 +00:00
Lukáš Lalinský
5df6ef092b Add my old WMA and MP4 code. It is disabled by default, must be explicitly enabled to be compiled.
Scott: If you think this is really a bad idea, please revert.


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@883108 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-11-12 08:17:11 +00:00
Scott Wheeler
fa31fa29d7 typo
BUG:170036


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@854564 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-08-29 19:59:26 +00:00
Scott Wheeler
13fddc3974 Don't try to access the string list if the item type is a locator.
Allan, does this look correct?  (It at least fixes the crash...)

BUG:169810
CCMAIL:kde@carewolf.com


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@852712 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-08-26 12:19:47 +00:00
Scott Wheeler
d2a1cfa32d detach when using non-const operator[]
BUG:169389


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@850657 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-08-21 22:56:44 +00:00
Scott Wheeler
8434d19928 remove exec bit
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@824940 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-26 22:11:11 +00:00
Scott Wheeler
9947f45b31 Add support for private frames.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@824701 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-26 15:06:20 +00:00
Scott Wheeler
07a6c86a31 If the genre string is empty don't treat it as a number.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@823961 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-24 14:08:03 +00:00
Andy Goossens
bd90f1b9d4 SVN_SILENT: fix typo
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@822327 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-19 20:44:39 +00:00
Scott Wheeler
50fe14f4b7 add files here
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@822217 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-19 14:19:31 +00:00
Scott Wheeler
75579dc0dd Provisional .wav support. Tag writing will probably be disabled by default...
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@822160 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-19 11:15:39 +00:00
Scott Wheeler
1d86a684b2 wrong copyright
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@821783 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-18 13:21:35 +00:00
Scott Wheeler
be99222f29 Add a warning here so that it's clear that this constructor is not to be used for setting the
object's data.


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@821128 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-06-16 14:21:03 +00:00
Lukáš Lalinský
9ce4c72995 Fix reading of POPM rating -- it's unsigned char, not just char
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@811387 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-22 20:40:14 +00:00
Lukáš Lalinský
f6994ec26c Support for POPM ID3 frame
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@811137 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-22 12:06:45 +00:00
Benjamin Reed
51ca869f65 fix install_name RPATH stuff on OSX
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@810378 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-20 15:17:15 +00:00
Adriaan de Groot
55c788b608 Previous was me being stupid and too-quick on the commit button. Need unistd as well for read, write.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@810229 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-20 09:29:09 +00:00
Adriaan de Groot
3fe0895f62 Need plain <fcntl.h> for open and its flags, not necessarily sys/fcntl.h
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@810223 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-20 09:20:19 +00:00
Adriaan de Groot
388d0f353d ldexp is a c99-ism, which is not available in strict C++; use math.h as well to pull it in and hope for the best.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808578 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 22:59:07 +00:00
Scott Wheeler
aec136f119 SVN_SILENT this isn't needed anymore
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808293 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 09:47:19 +00:00
Scott Wheeler
08b6514420 Get all of the basic AIFF properties working.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808275 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 08:50:17 +00:00
Scott Wheeler
c52f3a4974 Add a skeleton (unimplemented) AIFF properties class.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808255 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 07:09:20 +00:00
Scott Wheeler
918366adcf Uff. Tabs-be-gone!
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808250 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 07:05:55 +00:00
Scott Wheeler
5175ed952b Add AIFF here too.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808247 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 06:47:29 +00:00
Scott Wheeler
ea839c286a update cmake files
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808246 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 06:46:03 +00:00
Scott Wheeler
123aa8a775 And now make it work for non-existing RIFF chunks.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808241 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 06:28:35 +00:00
Scott Wheeler
1d1fab1122 Now working for replacing an existing riff chunk.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808240 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 06:22:36 +00:00
Scott Wheeler
b2778ed715 Untested chunk writing code.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808237 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 06:01:52 +00:00
Scott Wheeler
d302b299d1 Add some docs.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808236 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 05:29:38 +00:00
Scott Wheeler
a2aaf8a8e1 Make reading an ID3v2 tag out of a RIFF chunk possible.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808235 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 05:08:51 +00:00
Scott Wheeler
0d10ae449c Groovy. Chunk parser worked on first try.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808232 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 04:35:59 +00:00
Scott Wheeler
d367a2f429 Add the skeleton of an AIFF implementation.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808225 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 04:20:50 +00:00
Scott Wheeler
efdcc7b01f Untested implementation of RIFF chunk parsing.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808221 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 03:49:44 +00:00
Scott Wheeler
40da982936 Add outline for RIFF files.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@808211 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-16 02:13:56 +00:00
Scott Wheeler
d4527a0141 Do a dynamic_cast on these instead of a static since in the case of a non-supported
frame flag the frame will still be added to the list, but using the UnknownFrame type
rather than the canonical type.  At the moment, on systems with a build in zlib, this
should only happen for the (very rare) encrypted frames.

BUG:161721
CCMAIL:taglib-devel@kde.org


git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@805637 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-05-09 00:16:30 +00:00
Harald Sitter
09dfbb7c3a change external prop back to https://svn.kde.org
CCMAIL: faure@kde.org
CCMAIL: mueller@kde.org

git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@795727 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-04-11 08:45:32 +00:00
Adriaan de Groot
5fe5ee1074 kdesupport is going to compile against stdcxx anyway, Cstd wont cut it, so document better and just put stdcxx in there.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@794718 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-04-08 12:40:52 +00:00
Scott Wheeler
a724586b43 Don't overflow for really high bitrate files.
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@794711 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-04-08 12:15:20 +00:00
Andreas Hartmetz
bbfcc84dec add missing include; fixes compilation with tests
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@794194 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-04-06 21:22:49 +00:00
Harald Sitter
29995f8c2a change externals property to use svn://anonsvn.kde.org
git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/kdesupport/taglib@793327 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
2008-04-03 17:04:12 +00:00
329 changed files with 21326 additions and 2372 deletions

44
.gitignore vendored Normal file
View File

@@ -0,0 +1,44 @@
cmake_install.cmake
cmake_uninstall.cmake
Makefile
CTestTestfile.cmake
CMakeFiles/
*.so
*.so.*
*.dylib
*.vcproj
*.ncb
*.sln
*.suo
*.user
.*
*~
/CMakeCache.txt
/Doxyfile
/config.h
/taglib.pc
/tests/test_runner
/tests/Testing
/taglib_config.h
/taglib-config
/bindings/c/taglib_c.pc
/bindings/c/Debug
/bindings/c/MinSizeRel
/bindings/c/Release
/bindings/c/tag_c.dir/Debug
/bindings/c/tag_c.dir/MinSizeRel
/bindings/c/tag_c.dir/Release
/examples/framelist
/examples/strip-id3v1
/examples/tagreader
/examples/tagreader_c
/examples/tagwriter
/doc/html
/taglib/Debug
/taglib/MinSizeRel
/taglib/Release
/taglib/tag.dir/Debug
/taglib/tag.dir/MinSizeRel
/taglib/tag.dir/Release
/ALL_BUILD.dir
/ZERO_CHECK.dir

View File

@@ -1,11 +1,15 @@
Scott Wheeler <wheeler@kde.org>
Author, maintainer
Lukas Lalinsky <lalinsky@gmail.com>
Implementation of multiple new file formats, many bug fixes, maintainer
Ismael Orenstein <orenstein@kde.org>
Xing header implementation
Allan Sandfeld Jensen <kde@carewolf.org>
FLAC metadata implementation
Teemu Tervo <teemu.tervo@gmx.net>
Numerous bug reports and fixes
Mathias Panzenböck <grosser.meister.morti@gmx.net>
Mod, S3M, IT and XM metadata implementations
Please send all patches and questions to taglib-devel@kde.org rather than to
individual developers!

View File

@@ -1,56 +1,108 @@
project(taglib)
OPTION(BUILD_TESTS "Build the test suite" OFF)
OPTION(BUILD_EXAMPLES "Build the examples" OFF)
cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR)
OPTION(NO_ITUNES_HACKS "Disable workarounds for iTunes bugs" OFF)
option(ENABLE_STATIC "Make static version of libtag" OFF)
if(ENABLE_STATIC)
add_definitions(-DTAGLIB_STATIC)
set(BUILD_SHARED_LIBS OFF)
else()
set(BUILD_SHARED_LIBS ON)
endif()
OPTION(ENABLE_STATIC_RUNTIME "Visual Studio, link with runtime statically" OFF)
option(VISIBILITY_HIDDEN "Build with -fvisibility=hidden" OFF)
if(VISIBILITY_HIDDEN)
add_definitions (-fvisibility=hidden)
endif()
option(BUILD_TESTS "Build the test suite" OFF)
option(BUILD_EXAMPLES "Build the examples" OFF)
option(NO_ITUNES_HACKS "Disable workarounds for iTunes bugs" OFF)
add_definitions(-DHAVE_CONFIG_H)
set(TESTS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/tests/")
#add some KDE specific stuff
set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)" )
set(EXEC_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX} CACHE PATH "Base directory for executables and libraries" FORCE)
#
## the following are directories where stuff will be installed to
set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The kde info install dir (default prefix/info)" FORCE)
set(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The subdirectory to the header prefix" FORCE)
set(LIB_SUFFIX "" CACHE STRING "Define suffix of directory name (32/64)")
set(EXEC_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}" CACHE PATH "Base directory for executables and libraries" FORCE)
set(BIN_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/bin" CACHE PATH "The subdirectory to the binaries prefix (default prefix/bin)" FORCE)
set(LIB_INSTALL_DIR "${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX}" CACHE PATH "The subdirectory relative to the install prefix where libraries will be installed (default is /lib${LIB_SUFFIX})" FORCE)
set(INCLUDE_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "The subdirectory to the header prefix" FORCE)
if (CMAKE_COMPILER_IS_GNUCXX)
if (CMAKE_SYSTEM_NAME MATCHES Linux)
set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-long-long -ansi -Wundef -Wcast-align -Werror-implicit-function-declaration -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common")
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wnon-virtual-dtor -Wno-long-long -ansi -Wundef -Wcast-align -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -Wformat-security -fno-check-new -fno-common")
endif (CMAKE_SYSTEM_NAME MATCHES Linux)
endif (CMAKE_COMPILER_IS_GNUCXX)
if(MSVC)
add_definitions( -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE )
endif(MSVC)
if (WIN32)
set(CMAKE_DEBUG_POSTFIX "d")
endif (WIN32)
if(APPLE)
option(BUILD_FRAMEWORK "Build an OS X framework" OFF)
set(FRAMEWORK_INSTALL_DIR "/Library/Frameworks" CACHE STRING "Directory to install frameworks to.")
endif()
SET(TAGLIB_LIB_MAJOR_VERSION "1")
SET(TAGLIB_LIB_MINOR_VERSION "5")
SET(TAGLIB_LIB_PATCH_VERSION "0")
if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
endif()
if (MSVC AND ENABLE_STATIC_RUNTIME)
foreach(flag_var CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endforeach(flag_var)
endif()
SET(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}")
set(TAGLIB_LIB_MAJOR_VERSION "1")
set(TAGLIB_LIB_MINOR_VERSION "8")
set(TAGLIB_LIB_PATCH_VERSION "0")
set(TAGLIB_LIB_VERSION_STRING "${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}")
# 1. If the library source code has changed at all since the last update, then increment revision.
# 2. If any interfaces have been added, removed, or changed since the last update, increment current, and set revision to 0.
# 3. If any interfaces have been added since the last public release, then increment age.
# 4. If any interfaces have been removed since the last public release, then set age to 0.
set(TAGLIB_SOVERSION_CURRENT 13)
set(TAGLIB_SOVERSION_REVISION 0)
set(TAGLIB_SOVERSION_AGE 12)
math(EXPR TAGLIB_SOVERSION_MAJOR "${TAGLIB_SOVERSION_CURRENT} - ${TAGLIB_SOVERSION_AGE}")
math(EXPR TAGLIB_SOVERSION_MINOR "${TAGLIB_SOVERSION_AGE}")
math(EXPR TAGLIB_SOVERSION_PATCH "${TAGLIB_SOVERSION_REVISION}")
include(ConfigureChecks.cmake)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib-config )
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib.pc )
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/taglib-config DESTINATION ${BIN_INSTALL_DIR})
configure_file(config-taglib.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h )
if(NOT WIN32 AND NOT BUILD_FRAMEWORK)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib.pc )
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif()
ADD_SUBDIRECTORY( taglib )
include_directories(${CMAKE_CURRENT_BINARY_DIR})
configure_file(config-taglib.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h)
ADD_SUBDIRECTORY(tests)
ADD_SUBDIRECTORY(examples)
if(WITH_ASF)
set(TAGLIB_WITH_ASF TRUE)
endif()
if(WITH_MP4)
set(TAGLIB_WITH_MP4 TRUE)
endif()
ADD_SUBDIRECTORY(bindings)
if(NOT WIN32)
INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig )
endif(NOT WIN32)
configure_file(taglib/taglib_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_config.h)
INSTALL( PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/taglib-config DESTINATION ${BIN_INSTALL_DIR})
add_subdirectory(taglib)
add_subdirectory(bindings)
if(BUILD_TESTS)
enable_testing()
add_subdirectory(tests)
endif(BUILD_TESTS)
add_subdirectory(examples)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.cmake ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
file(COPY doc/taglib.png DESTINATION doc)
add_custom_target(docs doxygen)
# uninstall target
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")

View File

@@ -1,113 +1,125 @@
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991 Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA.
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the library GPL. It is
numbered 2 because it goes with version 2 of the ordinary GPL.]
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Library General Public License, applies to some
specially designated Free Software Foundation software, and to any
other libraries whose authors decide to use it. You can use it for
your libraries, too.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations below.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if
you distribute copies of the library, or if you modify it.
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link a program with the library, you must provide
complete object files to the recipients so that they can relink them
with the library, after making changes to the library and recompiling
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
Our method of protecting your rights has two steps: (1) copyright
the library, and (2) offer you this license which gives you legal
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
Also, for each distributor's protection, we want to make certain
that everyone understands that there is no warranty for this free
library. If the library is modified by someone else and passed on, we
want its recipients to know that what they have is not the original
version, so that any problems introduced by others will not reflect on
the original authors' reputations.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that companies distributing free
software will individually obtain patent licenses, thus in effect
transforming the program into proprietary software. To prevent this,
we have made it clear that any patent must be licensed for everyone's
free use or not licensed at all.
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the ordinary
GNU General Public License, which was designed for utility programs. This
license, the GNU Library General Public License, applies to certain
designated libraries. This license is quite different from the ordinary
one; be sure to read it in full, and don't assume that anything in it is
the same as in the ordinary license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
The reason we have a separate public license for some libraries is that
they blur the distinction we usually make between modifying or adding to a
program and simply using it. Linking a program with a library, without
changing the library, is in some sense simply using the library, and is
analogous to running a utility program or application program. However, in
a textual and legal sense, the linked executable is a combined work, a
derivative of the original library, and the ordinary General Public License
treats it as such.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
Because of this blurred distinction, using the ordinary General
Public License for libraries did not effectively promote software
sharing, because most developers did not use the libraries. We
concluded that weaker conditions might promote sharing better.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
However, unrestricted linking of non-free programs would deprive the
users of those programs of all benefit from the free status of the
libraries themselves. This Library General Public License is intended to
permit developers of non-free programs to use free libraries, while
preserving your freedom as a user of such programs to change the free
libraries that are incorporated in them. (We have not seen how to achieve
this as regards changes in header files, but we have achieved it as regards
changes in the actual functions of the Library.) The hope is that this
will lead to faster development of free libraries.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it becomes
a de-facto standard. To achieve this, non-free programs must be
allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, while the latter only
works together with the library.
Note that it is possible for a library to be covered by the ordinary
General Public License rather than by this special one.
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
GNU LIBRARY GENERAL PUBLIC LICENSE
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library which
contains a notice placed by the copyright holder or other authorized
party saying it may be distributed under the terms of this Library
General Public License (also called "this License"). Each licensee is
addressed as "you".
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
@@ -134,7 +146,7 @@ such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
@@ -256,7 +268,7 @@ distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
6. As an exception to the Sections above, you may also compile or
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
@@ -283,23 +295,31 @@ of these things:
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Accompany the work with a written offer, valid for at
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at
least three years, to give the same user the materials
specified in Subsection 6a, above, for a charge no more
than the cost of performing this distribution.
c) If distribution of the work is made by offering access to copy
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
d) Verify that the user has already received a copy of these
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the source code distributed need not include anything that is normally
distributed (in either source or binary form) with the major
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
@@ -348,7 +368,7 @@ Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
You are not responsible for enforcing compliance by third parties with
this License.
11. If, as a consequence of a court judgment or allegation of patent
@@ -391,7 +411,7 @@ excluded. In such case, this License incorporates the limitation as if
written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Library General Public License from time to time.
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
@@ -412,7 +432,7 @@ decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
@@ -435,8 +455,9 @@ FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Libraries
If you develop a new library, and you want it to be of the greatest
possible use to the public, we recommend making it free software that
@@ -455,7 +476,7 @@ convey the exclusion of warranty; and each file should have at least the
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -464,7 +485,7 @@ convey the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.

View File

@@ -1,8 +1,3 @@
# NOTE: only add something here if it is really needed by all of kdelibs.
# Otherwise please prefer adding to the relevant config-foo.h.cmake file,
# and the CMakeLists.txt that generates it (or a separate ConfigureChecks.make file if you prefer)
# to minimize recompilations and increase modularity.
include(CheckIncludeFile)
include(CheckIncludeFiles)
include(CheckSymbolExists)
@@ -11,18 +6,18 @@ include(CheckLibraryExists)
include(CheckTypeSize)
include(CheckCXXSourceCompiles)
#check for libz using the cmake supplied FindZLIB.cmake
FIND_PACKAGE(ZLIB)
# check for libz using the cmake supplied FindZLIB.cmake
find_package(ZLIB)
if(ZLIB_FOUND)
set(HAVE_ZLIB 1)
else()
set(HAVE_ZLIB 0)
endif()
IF(ZLIB_FOUND)
SET(HAVE_ZLIB 1)
ELSE(ZLIB_FOUND)
SET(HAVE_ZLIB 0)
ENDIF(ZLIB_FOUND)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
find_package(CppUnit)
if(NOT CppUnit_FOUND AND BUILD_TESTS)
message(STATUS "CppUnit not found, disabling tests.")
set(BUILD_TESTS OFF)
endif()
SET(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
FIND_PACKAGE(CppUnit)
IF (NOT CPPUNIT_FOUND AND BUILD_TESTS)
MESSAGE(STATUS "CppUnit not found, disabling tests.")
SET(BUILD_TESTS OFF)
ENDIF(NOT CPPUNIT_FOUND AND BUILD_TESTS)

View File

@@ -4,8 +4,8 @@
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = TagLib
PROJECT_NUMBER =
OUTPUT_DIRECTORY = .
PROJECT_NUMBER = ${TAGLIB_LIB_VERSION_STRING}
OUTPUT_DIRECTORY = doc
OUTPUT_LANGUAGE = English
USE_WINDOWS_ENCODING = NO
BRIEF_MEMBER_DESC = YES
@@ -61,7 +61,7 @@ WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = ../taglib/
INPUT = @CMAKE_SOURCE_DIR@/taglib
FILE_PATTERNS = *.h \
*.hh \
*.H
@@ -96,9 +96,9 @@ IGNORE_PREFIX =
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_FILE_EXTENSION = .html
HTML_HEADER = api-header.html
HTML_FOOTER = api-footer.html
HTML_STYLESHEET = taglib-api.css
HTML_HEADER = @CMAKE_SOURCE_DIR@/doc/api-header.html
HTML_FOOTER = @CMAKE_SOURCE_DIR@/doc/api-footer.html
HTML_STYLESHEET = @CMAKE_SOURCE_DIR@/doc/taglib-api.css
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
CHM_FILE =
@@ -169,7 +169,9 @@ SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED = DO_NOT_DOCUMENT \
DOXYGEN
DOXYGEN \
WITH_MP4 \
WITH_ASF
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------

199
INSTALL
View File

@@ -1,167 +1,70 @@
Basic Installation
==================
TagLib Installation
===================
These are generic installation instructions.
TagLib uses the CMake build system. As a user, you will most likely want to
build TagLib in release mode and install it into a system-wide location.
This can be done using the following commands:
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
cmake -DCMAKE_INSTALL_PREFIX=/usr/local -DCMAKE_RELEASE_TYPE=Release .
make
sudo make install
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
In order to build the included examples, use the BUILD_EXAMPLES option:
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
cmake -DBUILD_EXAMPLES=ON [...]
The simplest way to compile this package is:
See http://www.cmake.org/cmake/help/runningcmake.html for generic help on
running CMake.
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Mac OS X
--------
Running `configure' takes a while. While running, it prints some
messages telling which features it is checking for.
On Mac OS X, you might want to build a framework that can be easily integrated
into your application. If you set the BUILD_FRAMEWORK option on, it will compile
TagLib as a framework. For example, the following command can be used to build
an Universal Binary framework with Mac OS X 10.4 as the deployment target:
2. Type `make' to compile the package.
cmake -DCMAKE_BUILD_TYPE=Release \
-DBUILD_FRAMEWORK=ON \
-DCMAKE_C_COMPILER=/usr/bin/gcc-4.0 \
-DCMAKE_CXX_COMPILER=/usr/bin/c++-4.0 \
-DCMAKE_OSX_SYSROOT=/Developer/SDKs/MacOSX10.4u.sdk/ \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.4 \
-DCMAKE_OSX_ARCHITECTURES="ppc;i386;x86_64"
3. Type `make install' to install the programs and any data files and
documentation.
For a 10.6 Snow Leopard static library with both 32-bit and 64-bit code, use:
4. You can remove the program binaries and object files from the
source code directory by typing `make clean'.
cmake -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_OSX_DEPLOYMENT_TARGET=10.6 \
-DCMAKE_OSX_ARCHITECTURES="i386;x86_64" \
-DENABLE_STATIC=ON \
-DCMAKE_INSTALL_PREFIX="<folder you want to build to>"
Compilers and Options
=====================
After 'make', and 'make install', add libtag.a to your XCode project, and add
the include folder to the project's User Header Search Paths.
Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like
this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Windows
-------
Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
For building a static library on Windows with Visual Studio 2010, cd to
the TagLib folder then:
Compiling For Multiple Architectures
====================================
cmake -DENABLE_STATIC=ON -DENABLE_STATIC_RUNTIME=ON -G "Visual Studio 10" ...
Including ENABLE_STATIC_RUNTIME=ON indicates you want TagLib built using the
static runtime library, rather than the DLL form of the runtime.
CMake will create a Visual Studio solution, taglib.sln that you can open and
build as normal.
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
Unit Tests
----------
If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time
in the source code directory. After you have installed the package for
one architecture, use `make distclean' before reconfiguring for another
architecture.
If you want to run the test suite to make sure TagLib works properly on your
system, you need to have cppunit installed. To build the tests, include
the option -DBUILD_TESTS=on when running cmake.
Installation Names
==================
The test suite has a custom target in the build system, so you can run
the tests using make:
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PATH'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PATH', the package will use
PATH as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package
will run on. Usually `configure' can figure that out, but if it prints
a message saying it can not guess the host type, give it the
`--host=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name with three fields:
CPU-COMPANY-SYSTEM
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Operation Controls
==================
`configure' recognizes the following options to control how it
operates.
`--cache-file=FILE'
Use and save the results of the tests in FILE instead of
`./config.cache'. Set FILE to `/dev/null' to disable caching, for
debugging `configure'.
`--help'
Print a summary of the options to `configure', and exit.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made.
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`--version'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`configure' also accepts some other, not widely useful, options.
make check

View File

@@ -1,54 +0,0 @@
SUBDIRS = taglib bindings tests
AUTOMAKE_OPTIONS = foreign
$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ;
$(top_srcdir)/subdirs:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
@cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4
MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files
bin_SCRIPTS = taglib-config
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = taglib.pc
package-messages:
$(MAKE) -f admin/Makefile.common package-messages
dist-hook:
cd $(top_distdir) && perl admin/am_edit -padmin
cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs
examples: examples-all
examples-all:
cd examples ; \
$(MAKE) all
apidox:
$(mkinstalldirs) doc/api; \
if test ! -x doc/common; then \
$(LN_S) $(kde_libs_htmldir)/en/common doc/common ; \
fi; \
cp $(top_srcdir)/admin/Doxyfile.global taglib.doxyfile; \
echo "PROJECT_NAME = TagLib" >> taglib.doxyfile; \
echo "PROJECT_NUMBER = \"Version 1.5\"" >> taglib.doxyfile; \
echo "INPUT = $(srcdir)" >> taglib.doxyfile; \
echo "OUTPUT_DIRECTORY = doc/api" >> taglib.doxyfile; \
echo "HTML_OUTPUT = html" >> taglib.doxyfile; \
echo "GENERATE_HTML = YES" >> taglib.doxyfile ; \
echo "GENERATE_MAN = NO" >> taglib.doxyfile ; \
echo "GENERATE_LATEX = NO" >> taglib.doxyfile ; \
echo "HTML_HEADER = doc/common/header.html" >> taglib.doxyfile ; \
echo "HTML_FOOTER = doc/common/footer.html" >> taglib.doxyfile ; \
echo "HTML_STYLESHEET = doc/common/doxygen.css" >> taglib.doxyfile ; \
echo "FILE_PATTERNS = *.h" >> taglib.doxyfile ; \
echo "PREDEFINED = DO_NOT_DOCUMENT DOXYGEN" >> taglib.doxyfile ; \
echo "EXTRACT_ALL = YES" >> taglib.doxyfile ; \
doxygen taglib.doxyfile

View File

@@ -1,14 +0,0 @@
all:
@echo "This Makefile is only for the CVS repository"
@echo "This will be deleted before making the distribution"
@echo ""
@if test ! -d admin; then \
echo "Please recheckout this module!" ;\
echo "for cvs: use checkout once and after that update again" ;\
echo "for cvsup: checkout kde-common from cvsup and" ;\
echo " link kde-common/admin to ./admin" ;\
exit 1 ;\
fi
$(MAKE) -f admin/Makefile.common cvs
.SILENT:

158
NEWS Normal file
View File

@@ -0,0 +1,158 @@
TagLib 1.8 (Sep 6, 2012)
==============================
1.8:
* Added support for OWNE ID3 frames.
* Changed key validation in the new PropertyMap API.
* ID3v1::Tag::setStringHandler will no londer delete the previous handler,
the caller is responsible for this.
* File objects will also no longer delete the passed IOStream objects. It
should be done in the caller code after the File object is no longer
used.
* Added ID3v2::Tag::setLatin1StringHandler for custom handling of
latin1-encoded text in ID3v2 frames.
* Fixed validation of ID3v2 frame IDs (IDs with '0' were ignored).
1.8 BETA:
* New API for accessing tags by name.
* New abstract I/O stream layer to allow custom I/O handlers.
* Support for writing ID3v2.3 tags.
* Support for various module file formats (MOD, S3M, IT, XM).
* Support for MP4 and ASF is now enabled by default.
* Started using atomic int operations for reference counting.
* Added methods for checking if WMA and MP4 files are DRM-protected.
* Added taglib_free to the C bindings.
* New method to allow removing pictures from FLAC files.
* Support for reading audio properties from ALAC and Musepack SV8 files.
* Added replay-gain information to Musepack audio properties.
* Support for APEv2 binary tags.
* Many AudioProperties subclasses now provide information about the total number of samples.
* Various small bug fixes.
TagLib 1.7.2 (Apr 20, 2012)
===========================
* Fixed division by zero while parsing corrupted MP4 files (CVE-2012-2396).
* Fixed compilation on Haiku.
TagLib 1.7.1 (Mar 17, 2012)
===========================
* Improved parsing of corrupted WMA, RIFF and OGG files.
* Fixed a memory leak in the WMA parser.
* Fixed a memory leak in the FLAC parser.
* Fixed a possible division by zero in the APE parser.
* Added detection of TTA2 files.
* Fixed saving of multiple identically named tags to Vorbis Comments.
TagLib 1.7 (Mar 11, 2011)
=========================
1.7:
* Fixed memory leaks in the FLAC file format parser.
* Fixed bitrate calculation for WAV files.
1.7 RC1:
* Support for reading/writing tags from Monkey's Audio files. (BUG:210404)
* Support for reading/writing embedded pictures from WMA files.
* Support for reading/writing embedded pictures from FLAC files (BUG:218696).
* Implemented APE::Tag::isEmpty() to check for all APE tags, not just the
basic ones.
* Added reading of WAV audio length. (BUG:116033)
* Exposed FLAC MD5 signature of the uncompressed audio stream via
FLAC::Properties::signature(). (BUG:160172)
* Added function ByteVector::toHex() for hex-encoding of byte vectors.
* WavPack reader now tries to get the audio length by finding the final
block, if the header doesn't have the information. (BUG:258016)
* Fixed a memory leak in the ID3v2.2 PIC frame parser. (BUG:257007)
* Fixed writing of RIFF files with even chunk sizes. (BUG:243954)
* Fixed compilation on MSVC 2010.
* Removed support for building using autoconf/automake.
* API docs can be now built using "make docs".
TagLib 1.6.3 (Apr 17, 2010)
===========================
* Fixed definitions of the TAGLIB_WITH_MP4 and TAGLIB_WITH_ASF macros.
* Fixed upgrading of ID3v2.3 genre frame with ID3v1 code 0 (Blues).
* New method `int String::toInt(bool *ok)` which can return whether the
conversion to a number was successfull.
* Fixed parsing of incorrectly written lengths in ID3v2 (affects mainly
compressed frames). (BUG:231075)
TagLib 1.6.2 (Apr 9, 2010)
==========================
* Read Vorbis Comments from the first FLAC metadata block, if there are
multipe ones. (BUG:211089)
* Fixed a memory leak in FileRef's OGA format detection.
* Fixed compilation with the Sun Studio compiler. (BUG:215225)
* Handle WM/TrackNumber attributes with DWORD content in WMA files.
(BUG:218526)
* More strict check if something is a valid MP4 file. (BUG:216819)
* Correctly save MP4 int-pair atoms with flags set to 0.
* Fixed compilation of the test runner on Windows.
* Store ASF attributes larger than 64k in the metadata library object.
* Ignore trailing non-data atoms when parsing MP4 covr atoms.
* Don't upgrade ID3v2.2 frame TDA to TDRC. (BUG:228968)
TagLib 1.6.1 (Oct 31, 2009)
===========================
* Better detection of the audio codec of .oga files in FileRef.
* Fixed saving of Vorbis comments to Ogg FLAC files. TagLib tried to
include the Vorbis framing bit, which is only correct for Ogg Vorbis.
* Public symbols now have explicitly set visibility to "default" on GCC.
* Added missing exports for static ID3v1 functions.
* Fixed a typo in taglib_c.pc
* Fixed a failing test on ppc64.
* Support for binary 'covr' atom in MP4 files. TagLib 1.6 treated them
as text atoms, which corrupted them in some cases.
* Fixed ID3v1-style genre to string conversion in MP4 files.
TagLib 1.6 (Sep 13, 2009)
=========================
1.6:
* New CMake option to build a static version - ENABLE_STATIC.
* Added support for disabling dllimport/dllexport on Windows using the
TAGLIB_STATIC macro.
* Support for parsing the obsolete 'gnre' MP4 atom.
* New cpp macros TAGLIB_WITH_MP4 and TAGLIB_WITH_ASF to determin if
TagLib was built with MP4/ASF support.
1.6 RC1:
* Split Ogg packets larger than 64k into multiple pages. (BUG:171957)
* TagLib can now use FLAC padding block. (BUG:107659)
* ID3v2.2 frames are now not incorrectly saved. (BUG:176373)
* Support for ID3v2.2 PIC frames. (BUG:167786)
* Fixed a bug in ByteVectorList::split().
* XiphComment::year() now falls back to YEAR if DATE doesn't exist
and XiphComment::year() falls back to TRACKNUM if TRACKNUMBER doesn't
exist. (BUG:144396)
* Improved ID3v2.3 genre parsing. (BUG:188578)
* Better checking of corrupted ID3v2 APIC data. (BUG:168382)
* Bitrate calculating using the Xing header now uses floating point
numbers. (BUG:172556)
* New TagLib::String method rfind().
* Added support for MP4 file format with iTunes-style metadata [optional].
* Added support for ASF (WMA) file format [optional].
* Fixed crash when saving a Locator APEv2 tag. (BUG:169810)
* Fixed a possible crash in the non-const version of String::operator[]
and in String::operator+=. (BUG:169389)
* Added support for PRIV ID3v2 frames.
* Empty ID3v2 genres are no longer treated as numeric ID3v1 genres.
* Added support for the POPM (rating/playcount) ID3v2 frame.
* Generic RIFF file format support:
* Support for AIFF files with ID3v2 tags.
* Support for WAV files with ID3v2 tags.
* Fixed crash on handling unsupported ID3v2 frames, e.g. on encrypted
frames. (BUG:161721)
* Fixed overflow while calculating bitrate of FLAC files with a very
high bitrate.

View File

@@ -1 +1 @@
ADD_SUBDIRECTORY( c )
add_subdirectory(c)

View File

@@ -1 +0,0 @@
SUBDIRS = c

View File

@@ -2,5 +2,5 @@ There are a few other people that have done bindings externally that I have
been made aware of. I have not personally reviewed these bindings, but I'm
listing them here so that those who find them useful are able to find them:
- Ruby - http://www.hakubi.us/ruby-taglib/
- Python - http://namingmuse.berlios.de/
http://developer.kde.org/~wheeler/taglib.html#bindings

View File

@@ -1,59 +1,68 @@
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../../taglib
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/toolkit
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/flac
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/flac
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpc
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/wavpack
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/speex
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/trueaudio
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/toolkit
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/asf
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/flac
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/flac
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpc
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mp4
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/mpeg/id3v2/frames
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/wavpack
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/ogg/speex
${CMAKE_CURRENT_SOURCE_DIR}/../../taglib/trueaudio
)
set(tag_c_HDRS tag_c.h)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib_c.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc )
########### next target ###############
add_library(tag_c tag_c.cpp ${tag_c_HDRS})
SET(tag_c_LIB_SRCS
tag_c.cpp
)
ADD_LIBRARY(tag_c SHARED ${tag_c_LIB_SRCS})
TARGET_LINK_LIBRARIES(tag_c tag )
target_link_libraries(tag_c tag)
set_target_properties(tag_c PROPERTIES PUBLIC_HEADER "${tag_c_HDRS}")
if(BUILD_FRAMEWORK)
set_target_properties(tag_c PROPERTIES FRAMEWORK TRUE)
endif()
# On Solaris we need to explicitly add the C++ standard and runtime
# libraries to the libs used by this library, to link them to apps
# using these bindings.
CHECK_LIBRARY_EXISTS(Crun __RTTI___ "" HAVE_CRUN_LIB)
IF(HAVE_CRUN_LIB)
# libraries to the libs used by the C bindings, because those C bindings
# themselves won't pull in the C++ libs -- and if a C application is
# using the C bindings then we get link errors.
check_library_exists(Crun __RTTI___ "" HAVE_CRUN_LIB)
if(HAVE_CRUN_LIB)
# Which libraries to link depends critically on which
# STL version is going to be used by your application
# and which runtime is in use. While Crun is pretty much
# the only game in town, the three available STLs -- Cstd,
# stlport4 and stdcxx -- make this a mess. We really only
# support stdcxx, but won't force the issue here.
#
TARGET_LINK_LIBRARIES(tag_c Crun)
ENDIF(HAVE_CRUN_LIB)
# stlport4 and stdcxx -- make this a mess. The KDE-Solaris
# team supports stdcxx (Apache RogueWave stdcxx 4.1.3).
# According to http://bugs.kde.org/show_bug.cgi?id=215225 the library can have the following two names:
find_library(ROGUEWAVE_STDCXX_LIBRARY NAMES stdcxx4 stdcxx)
if(NOT ROGUEWAVE_STDCXX_LIBRARY)
message(FATAL_ERROR "Did not find supported STL library (tried stdcxx4 and stdcxx)")
endif()
target_link_libraries(tag_c ${ROGUEWAVE_STDCXX_LIBRARY} Crun)
endif()
SET_TARGET_PROPERTIES(tag_c PROPERTIES
set_target_properties(tag_c PROPERTIES
VERSION 0.0.0
SOVERSION 0
DEFINE_SYMBOL MAKE_TAGLIB_C_LIB
)
INSTALL(TARGETS tag_c
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
)
install(TARGETS tag_c
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION bin
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/taglib
)
########### install files ###############
INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
INSTALL( FILES tag_c.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)
if(NOT WIN32 AND NOT BUILD_FRAMEWORK)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/taglib_c.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/taglib_c.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif()

View File

@@ -1,26 +0,0 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/ogg/vorbis \
-I$(top_srcdir)/taglib/ogg/speex \
-I$(top_srcdir)/taglib/ogg/flac \
-I$(top_srcdir)/taglib/flac \
-I$(top_srcdir)/taglib/mpc \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
-I$(top_srcdir)/taglib/wavpack \
-I$(top_srcdir)/taglib/trueaudio \
$(all_includes)
lib_LTLIBRARIES = libtag_c.la
libtag_c_la_SOURCES = tag_c.cpp
taglib_include_HEADERS = tag_c.h
taglib_includedir = $(includedir)/taglib
libtag_c_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 0:0
libtag_c_la_LIBADD = ../../taglib/libtag.la
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = taglib_c.pc

View File

@@ -1 +0,0 @@
dnl AC_OUTPUT(bindings/c/taglib_c.pc)

View File

@@ -19,11 +19,14 @@
* USA *
***************************************************************************/
#include "tag_c.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <fileref.h>
#include <tfile.h>
#include <asffile.h>
#include <vorbisfile.h>
#include <mpegfile.h>
#include <flacfile.h>
@@ -32,10 +35,13 @@
#include <wavpackfile.h>
#include <speexfile.h>
#include <trueaudiofile.h>
#include <mp4file.h>
#include <tag.h>
#include <string.h>
#include <id3v2framefactory.h>
#include "tag_c.h"
using namespace TagLib;
static List<char *> strings;
@@ -52,6 +58,11 @@ void taglib_set_string_management_enabled(BOOL management)
stringManagementEnabled = bool(management);
}
void taglib_free(void* pointer)
{
free(pointer);
}
////////////////////////////////////////////////////////////////////////////////
// TagLib::File wrapper
////////////////////////////////////////////////////////////////////////////////
@@ -80,6 +91,12 @@ TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type)
return reinterpret_cast<TagLib_File *>(new Ogg::Speex::File(filename));
case TagLib_File_TrueAudio:
return reinterpret_cast<TagLib_File *>(new TrueAudio::File(filename));
case TagLib_File_MP4:
return reinterpret_cast<TagLib_File *>(new MP4::File(filename));
case TagLib_File_ASF:
return reinterpret_cast<TagLib_File *>(new ASF::File(filename));
default:
return 0;
}
return 0;
@@ -92,7 +109,7 @@ void taglib_file_free(TagLib_File *file)
BOOL taglib_file_is_valid(const TagLib_File *file)
{
return reinterpret_cast<const File *>(file)->isValid();
return reinterpret_cast<const File *>(file)->isValid();
}
TagLib_Tag *taglib_file_tag(const TagLib_File *file)

View File

@@ -35,6 +35,8 @@ extern "C" {
#else
#define TAGLIB_C_EXPORT __declspec(dllimport)
#endif
#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 1)
#define TAGLIB_C_EXPORT __attribute__ ((visibility("default")))
#else
#define TAGLIB_C_EXPORT
#endif
@@ -77,6 +79,11 @@ TAGLIB_C_EXPORT void taglib_set_strings_unicode(BOOL unicode);
*/
TAGLIB_C_EXPORT void taglib_set_string_management_enabled(BOOL management);
/*!
* Explicitly free a string returned from TagLib
*/
TAGLIB_C_EXPORT void taglib_free(void* pointer);
/*******************************************************************************
* File API
******************************************************************************/
@@ -89,13 +96,15 @@ typedef enum {
TagLib_File_OggFlac,
TagLib_File_WavPack,
TagLib_File_Speex,
TagLib_File_TrueAudio
TagLib_File_TrueAudio,
TagLib_File_MP4,
TagLib_File_ASF
} TagLib_File_Type;
/*!
* Creates a TagLib file based on \a filename. TagLib will try to guess the file
* type.
*
*
* \returns NULL if the file type cannot be determined or the file cannot
* be opened.
*/

View File

@@ -9,4 +9,4 @@ Description: Audio meta-data library (C bindings)
Requires: taglib
Version: ${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}
Libs: -L${LIB_INSTALL_DIR} -ltag_c
Cflags: -I=${INCLUDE_INSTALL_DIR}/taglib
Cflags: -I${INCLUDE_INSTALL_DIR}/taglib

View File

@@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: TagLib C Bindings
Description: Audio meta-data library (C bindings)
Requires: taglib
Version: 1.5
Libs: -L${libdir} -ltag_c
Cflags: -I${includedir}/taglib

View File

@@ -1,28 +1,69 @@
INCLUDE(UsePkgConfig)
PKGCONFIG(cppunit _CppUnitIncDir _CppUnitLinkDir _CppUnitLinkFlags _CppUnitCflags)
# - Try to find the libcppunit libraries
# Once done this will define
#
# CppUnit_FOUND - system has libcppunit
# CPPUNIT_INCLUDE_DIR - the libcppunit include directory
# CPPUNIT_LIBRARIES - libcppunit library
FIND_PATH(CPPUNIT_INCLUDE_DIR cppunit/TestCase.h
${_CppUnitIncDir}
/usr/local/include
/usr/include
)
include (MacroEnsureVersion)
FIND_LIBRARY(CPPUNIT_LIBRARIES cppunit
${_CppUnitLinkDir}
/usr/local/lib
/usr/lib
)
if(NOT CPPUNIT_MIN_VERSION)
SET(CPPUNIT_MIN_VERSION 1.12.0)
endif(NOT CPPUNIT_MIN_VERSION)
IF (CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
SET(CPPUNIT_FOUND TRUE)
ENDIF (CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
FIND_PROGRAM(CPPUNIT_CONFIG_EXECUTABLE cppunit-config )
IF (CPPUNIT_FOUND)
IF (NOT CppUnit_FIND_QUIETLY)
MESSAGE(STATUS "Found CppUnit: ${CPPUNIT_LIBRARIES}")
ENDIF (NOT CppUnit_FIND_QUIETLY)
ELSE (CPPUNIT_FOUND)
IF (CppUnit_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find CppUnit")
ENDIF (CppUnit_FIND_REQUIRED)
ENDIF (CPPUNIT_FOUND)
IF(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
# in cache already
SET(CppUnit_FOUND TRUE)
ELSE(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
SET(CPPUNIT_INCLUDE_DIR)
SET(CPPUNIT_LIBRARIES)
IF(CPPUNIT_CONFIG_EXECUTABLE)
EXEC_PROGRAM(${CPPUNIT_CONFIG_EXECUTABLE} ARGS --cflags RETURN_VALUE _return_VALUE OUTPUT_VARIABLE CPPUNIT_CFLAGS)
EXEC_PROGRAM(${CPPUNIT_CONFIG_EXECUTABLE} ARGS --libs RETURN_VALUE _return_VALUE OUTPUT_VARIABLE CPPUNIT_LIBRARIES)
EXEC_PROGRAM(${CPPUNIT_CONFIG_EXECUTABLE} ARGS --version RETURN_VALUE _return_VALUE OUTPUT_VARIABLE CPPUNIT_INSTALLED_VERSION)
STRING(REGEX REPLACE "-I(.+)" "\\1" CPPUNIT_CFLAGS "${CPPUNIT_CFLAGS}")
ELSE(CPPUNIT_CONFIG_EXECUTABLE)
# in case win32 needs to find it the old way?
FIND_PATH(CPPUNIT_CFLAGS cppunit/TestRunner.h PATHS /usr/include /usr/local/include )
FIND_LIBRARY(CPPUNIT_LIBRARIES NAMES cppunit PATHS /usr/lib /usr/local/lib )
# how can we find cppunit version?
MESSAGE (STATUS "Ensure you cppunit installed version is at least ${CPPUNIT_MIN_VERSION}")
SET (CPPUNIT_INSTALLED_VERSION ${CPPUNIT_MIN_VERSION})
ENDIF(CPPUNIT_CONFIG_EXECUTABLE)
SET(CPPUNIT_INCLUDE_DIR ${CPPUNIT_CFLAGS} "${CPPUNIT_CFLAGS}/cppunit")
ENDIF(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
IF(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
SET(CppUnit_FOUND TRUE)
if(NOT CppUnit_FIND_QUIETLY)
MESSAGE (STATUS "Found cppunit: ${CPPUNIT_LIBRARIES}")
endif(NOT CppUnit_FIND_QUIETLY)
IF(CPPUNIT_CONFIG_EXECUTABLE)
EXEC_PROGRAM(${CPPUNIT_CONFIG_EXECUTABLE} ARGS --version RETURN_VALUE _return_VALUE OUTPUT_VARIABLE CPPUNIT_INSTALLED_VERSION)
ENDIF(CPPUNIT_CONFIG_EXECUTABLE)
macro_ensure_version( ${CPPUNIT_MIN_VERSION} ${CPPUNIT_INSTALLED_VERSION} CPPUNIT_INSTALLED_VERSION_OK )
IF(NOT CPPUNIT_INSTALLED_VERSION_OK)
MESSAGE ("** CppUnit version is too old: found ${CPPUNIT_INSTALLED_VERSION} installed, ${CPPUNIT_MIN_VERSION} or major is required")
SET(CppUnit_FOUND FALSE)
ENDIF(NOT CPPUNIT_INSTALLED_VERSION_OK)
ELSE(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
SET(CppUnit_FOUND FALSE CACHE BOOL "Not found cppunit library")
ENDIF(CPPUNIT_INCLUDE_DIR AND CPPUNIT_LIBRARIES)
MARK_AS_ADVANCED(CPPUNIT_INCLUDE_DIR CPPUNIT_LIBRARIES)

View File

@@ -0,0 +1,71 @@
# This macro compares version numbers of the form "x.y.z"
# MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK)
# will set FOO_VERSIN_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION
# where both have to be in a 3-part-version format, leading and trailing
# text is ok, e.g.
# MACRO_ENSURE_VERSION( "2.5.31" "flex 2.5.4a" VERSION_OK)
# which means 2.5.31 is required and "flex 2.5.4a" is what was found on the system
# Copyright (c) 2006, David Faure, <faure@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
MACRO(MACRO_ENSURE_VERSION requested_version found_version var_too_old)
# parse the parts of the version string
STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+\\.[0-9]+" "\\1" req_major_vers "${requested_version}")
STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)\\.[0-9]+" "\\1" req_minor_vers "${requested_version}")
STRING(REGEX REPLACE "[0-9]+\\.[0-9]+\\.([0-9]+)" "\\1" req_patch_vers "${requested_version}")
STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" found_major_vers "${found_version}")
STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" found_minor_vers "${found_version}")
STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" found_patch_vers "${found_version}")
# compute an overall version number which can be compared at once
MATH(EXPR req_vers_num "${req_major_vers}*10000 + ${req_minor_vers}*100 + ${req_patch_vers}")
MATH(EXPR found_vers_num "${found_major_vers}*10000 + ${found_minor_vers}*100 + ${found_patch_vers}")
if (found_vers_num LESS req_vers_num)
set( ${var_too_old} FALSE )
else (found_vers_num LESS req_vers_num)
set( ${var_too_old} TRUE )
endif (found_vers_num LESS req_vers_num)
ENDMACRO(MACRO_ENSURE_VERSION)
# This macro compares version numbers of the form "x.y"
# MACRO_ENSURE_VERSION( FOO_MIN_VERSION FOO_VERSION_FOUND FOO_VERSION_OK)
# will set FOO_VERSIN_OK to true if FOO_VERSION_FOUND >= FOO_MIN_VERSION
# where both have to be in a 2-part-version format, leading and trailing
# text is ok, e.g.
# MACRO_ENSURE_VERSION( "0.5" "foo 0.6" VERSION_OK)
# which means 0.5 is required and "foo 0.6" is what was found on the system
# Copyright (c) 2006, David Faure, <faure@kde.org>
# Copyright (c) 2007, Pino Toscano, <pino@kde.org>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
MACRO(MACRO_ENSURE_VERSION2 requested_version found_version var_too_old)
# parse the parts of the version string
STRING(REGEX REPLACE "([0-9]+)\\.[0-9]+" "\\1" req_major_vers "${requested_version}")
STRING(REGEX REPLACE "[0-9]+\\.([0-9]+)" "\\1" req_minor_vers "${requested_version}")
STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+.*" "\\1" found_major_vers "${found_version}")
STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+).*" "\\1" found_minor_vers "${found_version}")
# compute an overall version number which can be compared at once
MATH(EXPR req_vers_num "${req_major_vers}*100 + ${req_minor_vers}")
MATH(EXPR found_vers_num "${found_major_vers}*100 + ${found_minor_vers}")
if (found_vers_num LESS req_vers_num)
set( ${var_too_old} FALSE )
else (found_vers_num LESS req_vers_num)
set( ${var_too_old} TRUE )
endif (found_vers_num LESS req_vers_num)
ENDMACRO(MACRO_ENSURE_VERSION2)

21
cmake_uninstall.cmake.in Normal file
View File

@@ -0,0 +1,21 @@
if (NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"")
endif()
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach (file ${files})
message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"")
if (EXISTS "$ENV{DESTDIR}${file}")
execute_process(
COMMAND @CMAKE_COMMAND@ -E remove "$ENV{DESTDIR}${file}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if(NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"")
endif ()
else ()
message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.")
endif ()
endforeach()

View File

@@ -1,9 +1,11 @@
/* config-taglib.h. Generated by cmake from config-taglib.h.cmake */
/* NOTE: only add something here if it is really needed by all of kdelibs.
Otherwise please prefer adding to the relevant config-foo.h.cmake file,
to minimize recompilations and increase modularity. */
/* Define if you have libz */
#cmakedefine HAVE_ZLIB 1
#cmakedefine NO_ITUNES_HACKS 1
#cmakedefine WITH_ASF 1
#cmakedefine WITH_MP4 1
#cmakedefine TESTS_DIR "@TESTS_DIR@"

View File

@@ -1,8 +0,0 @@
if test "x$have_zlib" = "xfalse"; then
echo "**************************************************"
echo "*"
echo "* You don't seem to have libz / zlib.h installed."
echo "* Compressed frames have been disabled."
echo "*"
echo "**************************************************"
fi

View File

@@ -1,133 +0,0 @@
dnl This file is part of the KDE libraries/packages
dnl Copyright (C) 2001 Stephan Kulow (coolo@kde.org)
dnl modified by Walter Tasin (tasin@kdevelop.org)
dnl for c++ console applications
dnl This file is free software; you can redistribute it and/or
dnl modify it under the terms of the GNU Library General Public
dnl License as published by the Free Software Foundation; either
dnl version 2 of the License, or (at your option) any later version.
dnl This library is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
dnl Library General Public License for more details.
dnl You should have received a copy of the GNU Library General Public License
dnl along with this library; see the file COPYING.LIB. If not, write to
dnl the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
dnl Boston, MA 02111-1307, USA.
# Original Author was Kalle@kde.org
# I lifted it in some mater. (Stephan Kulow)
# I used much code from Janos Farkas
dnl Process this file with autoconf to produce a configure script.
AC_INIT(acinclude.m4) dnl a source file from your sub dir
dnl This is so we can use kde-common
AC_CONFIG_AUX_DIR(admin)
dnl This ksh/zsh feature conflicts with `cd blah ; pwd`
unset CDPATH
dnl Checking host/target/build systems, for make, install etc.
AC_CANONICAL_SYSTEM
dnl Perform program name transformation
AC_ARG_PROGRAM
dnl Automake doc recommends to do this only here. (Janos)
AM_INIT_AUTOMAKE(taglib,1.4)
dnl almost the same like KDE_SET_PEFIX but the path is /usr/local
dnl
unset CDPATH
dnl make /usr/local the default for the installation
AC_PREFIX_DEFAULT(/usr/local)
if test "x$prefix" = "xNONE"; then
prefix=$ac_default_prefix
ac_configure_args="$ac_configure_args --prefix $prefix"
fi
KDE_FAST_CONFIGURE
KDE_CONF_FILES
dnl without this order in this file, automake will be confused!
dnl
AM_CONFIG_HEADER(config.h)
dnl checks for programs.
dnl first check for c/c++ compilers
AC_CHECK_COMPILERS
dnl CXXFLAGS="$NOOPT_CXXFLAGS" dnl __kdevelop[noopt]__
dnl CFLAGS="$NOOPT_CFLAGS" dnl __kdevelop[noopt]__
CXXFLAGS="$CXXFLAGS $USE_EXCEPTIONS" dnl __kdevelop[exc]__
dnl create only shared libtool-libraries
AC_ENABLE_SHARED(yes)
dnl set the following to yes, if you want to create static
dnl libtool-libraries, too.
AC_ENABLE_STATIC(no)
dnl create a working libtool-script
KDE_PROG_LIBTOOL
dnl activate the next macro call for DLOPEN tests and setting LIBDL
dnl (n.b. KDE_MISC_TESTS does the same to you, so use either this or the next one)
dnl KDE_CHECK_DLOPEN
dnl activate the next macro call for some additional tests
dnl (compat, crypt, socket, nsl, dlopen, ...)
dnl KDE_MISC_TESTS dnl __kdevelop__
dnl KDE_NEED_FLEX dnl __kdevelop__
dnl AC_PROG_YACC dnl __kdevelop__
dnl KDE_CHECK_EXTRA_LIBS
all_libraries="$all_libraries $USER_LDFLAGS"
all_includes="$all_includes $USER_INCLUDES"
AC_SUBST(all_includes)
AC_SUBST(all_libraries)
AC_SUBST(AUTODIRS)
#AM_INIT_AUTOMAKE(taglib,1.0)
dnl don't remove the below
dnl AC_OUTPUT(taglib-config)
dnl AC_OUTPUT(taglib.pc)
AC_DEFUN([AC_HAVE_ZLIB],
[
AC_DEFINE(HAVE_ZLIB, 1, [have zlib])
have_zlib=true
])
AC_DEFUN([AC_NO_ZLIB],
[
AC_DEFINE(HAVE_ZLIB, 0, [have zlib])
have_zlib=false
])
AC_CHECK_HEADER(zlib.h, AC_HAVE_ZLIB, AC_NO_ZLIB)
AM_CONDITIONAL(link_zlib, test x$have_zlib = xtrue)
AC_DEFUN([AC_HAVE_CPPUNIT],
[
AC_DEFINE(HAVE_CPPUNIT, 1, [have cppunit])
have_cppunit=true
])
AC_DEFUN([AC_NO_CPPUNIT],
[
AC_DEFINE(HAVE_CPPUNIT, 0, [have cppunit])
have_cppunit=false
])
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
AC_CHECK_HEADER(cppunit/extensions/HelperMacros.h, AC_HAVE_CPPUNIT, AC_NO_CPPUNIT)
AC_LANG_RESTORE
AM_CONDITIONAL(build_tests, test x$have_cppunit = xtrue)

View File

@@ -1 +1 @@
Run "doxygen taglib.doxgen" to generate the TagLib API documentation.
Run "make docs" in the parent directory to generate the TagLib API documentation.

View File

@@ -17,7 +17,7 @@
<td>
<div id="intro">
<table border="0" height="119" cellpadding="0" cellspacing="0" width="100%">
<tr><td valign="top"><h1>TagLib 1.5 ($title)</h1></td></tr>
<tr><td valign="top"><h1>TagLib $projectnumber ($title)</h1></td></tr>
<tr>
<td valign="bottom">
<div id="links">

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -7,72 +7,44 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_SOURCE_DIR}/../taglib
${CMAKE_CURRENT_SOURCE_DIR}/../taglib/mpeg/id3v2
${CMAKE_CURRENT_SOURCE_DIR}/../bindings/c/ )
if(ENABLE_STATIC)
add_definitions(-DTAGLIB_STATIC)
endif(ENABLE_STATIC)
########### next target ###############
SET(tagreader_SRCS
tagreader.cpp
)
ADD_EXECUTABLE(tagreader ${tagreader_SRCS})
ADD_EXECUTABLE(tagreader tagreader.cpp)
TARGET_LINK_LIBRARIES(tagreader tag )
#INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/tagreader DESTINATION ${BIN_INSTALL_DIR} )
########### next target ###############
SET(tagreader_c_SRCS
tagreader_c.c
)
ADD_EXECUTABLE(tagreader_c ${tagreader_c_SRCS})
ADD_EXECUTABLE(tagreader_c tagreader_c.c)
TARGET_LINK_LIBRARIES(tagreader_c tag_c )
#INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/tagreader_c DESTINATION ${BIN_INSTALL_DIR})
########### next target ###############
SET(tagwriter_SRCS
tagwriter.cpp
)
ADD_EXECUTABLE(tagwriter ${tagwriter_SRCS})
ADD_EXECUTABLE(tagwriter tagwriter.cpp)
TARGET_LINK_LIBRARIES(tagwriter tag )
#INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/tagwriter DESTINATION ${BIN_INSTALL_DIR})
########### next target ###############
SET(framelist_SRCS
framelist.cpp
)
ADD_EXECUTABLE(framelist ${framelist_SRCS})
ADD_EXECUTABLE(framelist framelist.cpp)
TARGET_LINK_LIBRARIES(framelist tag )
#INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/framelist DESTINATION ${BIN_INSTALL_DIR})
########### next target ###############
SET(strip-id3v1_SRCS
strip-id3v1.cpp)
ADD_EXECUTABLE(strip-id3v1 ${strip-id3v1_SRCS})
ADD_EXECUTABLE(strip-id3v1 strip-id3v1.cpp)
TARGET_LINK_LIBRARIES(strip-id3v1 tag )
#INSTALL(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/strip-id3v1 DESTINATION ${BIN_INSTALL_DIR})
endif(BUILD_EXAMPLES)

View File

@@ -1,18 +0,0 @@
bin_PROGRAMS = tagreader tagreader_c tagwriter framelist strip-id3v1
tagreader_SOURCES = tagreader.cpp
tagreader_c_SOURCES = tagreader_c.c
tagwriter_SOURCES = tagwriter.cpp
framelist_SOURCES = framelist.cpp
strip_id3v1_SOURCES = strip-id3v1.cpp
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ape \
-I$(top_srcdir)/taglib/mpeg \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
-I$(top_srcdir)/bindings/c
LDADD = ../taglib/libtag.la
tagreader_c_LDADD = ../bindings/c/libtag_c.la

View File

@@ -51,23 +51,27 @@ int main(int argc, char *argv[])
tag = taglib_file_tag(file);
properties = taglib_file_audioproperties(file);
printf("-- TAG --\n");
printf("title - \"%s\"\n", taglib_tag_title(tag));
printf("artist - \"%s\"\n", taglib_tag_artist(tag));
printf("album - \"%s\"\n", taglib_tag_album(tag));
printf("year - \"%i\"\n", taglib_tag_year(tag));
printf("comment - \"%s\"\n", taglib_tag_comment(tag));
printf("track - \"%i\"\n", taglib_tag_track(tag));
printf("genre - \"%s\"\n", taglib_tag_genre(tag));
if(tag != NULL) {
printf("-- TAG --\n");
printf("title - \"%s\"\n", taglib_tag_title(tag));
printf("artist - \"%s\"\n", taglib_tag_artist(tag));
printf("album - \"%s\"\n", taglib_tag_album(tag));
printf("year - \"%i\"\n", taglib_tag_year(tag));
printf("comment - \"%s\"\n", taglib_tag_comment(tag));
printf("track - \"%i\"\n", taglib_tag_track(tag));
printf("genre - \"%s\"\n", taglib_tag_genre(tag));
}
seconds = taglib_audioproperties_length(properties) % 60;
minutes = (taglib_audioproperties_length(properties) - seconds) / 60;
if(properties != NULL) {
seconds = taglib_audioproperties_length(properties) % 60;
minutes = (taglib_audioproperties_length(properties) - seconds) / 60;
printf("-- AUDIO --\n");
printf("bitrate - %i\n", taglib_audioproperties_bitrate(properties));
printf("sample rate - %i\n", taglib_audioproperties_samplerate(properties));
printf("channels - %i\n", taglib_audioproperties_channels(properties));
printf("length - %i:%02i\n", minutes, seconds);
printf("-- AUDIO --\n");
printf("bitrate - %i\n", taglib_audioproperties_bitrate(properties));
printf("sample rate - %i\n", taglib_audioproperties_samplerate(properties));
printf("channels - %i\n", taglib_audioproperties_channels(properties));
printf("length - %i:%02i\n", minutes, seconds);
}
taglib_tag_free_strings();
taglib_file_free(file);

View File

@@ -35,7 +35,7 @@ do
flags="$flags -I$includedir/taglib"
;;
--version)
echo 1.5
echo ${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}
;;
--prefix)
echo $prefix

View File

@@ -1,55 +0,0 @@
#!/bin/sh
usage()
{
echo "usage: $0 [OPTIONS]"
cat << EOH
options:
[--libs]
[--cflags]
[--version]
[--prefix]
EOH
exit 1;
}
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
flags=""
if test $# -eq 0 ; then
usage
fi
while test $# -gt 0
do
case $1 in
--libs)
flags="$flags -L$libdir -ltag"
;;
--cflags)
flags="$flags -I$includedir/taglib"
;;
--version)
echo 1.5
;;
--prefix)
echo $prefix
;;
*)
echo "$0: unknown option $1"
echo
usage
;;
esac
shift
done
if test -n "$flags"
then
echo $flags
fi

View File

@@ -1,11 +0,0 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
Name: TagLib
Description: Audio meta-data library
Requires:
Version: 1.5
Libs: -L${libdir} -ltag
Cflags: -I${includedir}/taglib

View File

@@ -1,160 +1,321 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/toolkit
${CMAKE_CURRENT_SOURCE_DIR}/mpeg
${CMAKE_CURRENT_SOURCE_DIR}/ogg
${CMAKE_CURRENT_SOURCE_DIR}/ogg/flac
${CMAKE_CURRENT_SOURCE_DIR}/flac
${CMAKE_CURRENT_SOURCE_DIR}/mpc
${CMAKE_CURRENT_SOURCE_DIR}/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/ogg/speex
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v1
${CMAKE_CURRENT_SOURCE_DIR}/ape
${CMAKE_CURRENT_SOURCE_DIR}/wavpack
${CMAKE_CURRENT_SOURCE_DIR}/trueaudio
${CMAKE_CURRENT_BINARY_DIR}/taglib
${CMAKE_CURRENT_BINARY_DIR}/..
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/toolkit
${CMAKE_CURRENT_SOURCE_DIR}/asf
${CMAKE_CURRENT_SOURCE_DIR}/mpeg
${CMAKE_CURRENT_SOURCE_DIR}/ogg
${CMAKE_CURRENT_SOURCE_DIR}/ogg/flac
${CMAKE_CURRENT_SOURCE_DIR}/flac
${CMAKE_CURRENT_SOURCE_DIR}/mpc
${CMAKE_CURRENT_SOURCE_DIR}/mp4
${CMAKE_CURRENT_SOURCE_DIR}/ogg/vorbis
${CMAKE_CURRENT_SOURCE_DIR}/ogg/speex
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v2/frames
${CMAKE_CURRENT_SOURCE_DIR}/mpeg/id3v1
${CMAKE_CURRENT_SOURCE_DIR}/ape
${CMAKE_CURRENT_SOURCE_DIR}/wavpack
${CMAKE_CURRENT_SOURCE_DIR}/trueaudio
${CMAKE_CURRENT_SOURCE_DIR}/riff
${CMAKE_CURRENT_SOURCE_DIR}/riff/aiff
${CMAKE_CURRENT_SOURCE_DIR}/riff/wav
${CMAKE_CURRENT_SOURCE_DIR}/mod
${CMAKE_CURRENT_SOURCE_DIR}/s3m
${CMAKE_CURRENT_SOURCE_DIR}/it
${CMAKE_CURRENT_SOURCE_DIR}/xm
)
if(ZLIB_FOUND)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
endif(ZLIB_FOUND)
include_directories(${ZLIB_INCLUDE_DIR})
endif()
ADD_SUBDIRECTORY( toolkit )
ADD_SUBDIRECTORY( mpeg )
ADD_SUBDIRECTORY( ogg )
ADD_SUBDIRECTORY( flac )
ADD_SUBDIRECTORY( ape )
ADD_SUBDIRECTORY( mpc )
ADD_SUBDIRECTORY( wavpack )
ADD_SUBDIRECTORY( trueaudio )
########### next target ###############
SET(mpeg_SRCS
mpeg/mpegfile.cpp
mpeg/mpegproperties.cpp
mpeg/mpegheader.cpp
mpeg/xingheader.cpp
set(tag_HDRS
tag.h
fileref.h
audioproperties.h
taglib_export.h
${CMAKE_BINARY_DIR}/taglib_config.h
toolkit/taglib.h
toolkit/tstring.h
toolkit/tlist.h
toolkit/tlist.tcc
toolkit/tstringlist.h
toolkit/tbytevector.h
toolkit/tbytevectorlist.h
toolkit/tbytevectorstream.h
toolkit/tiostream.h
toolkit/tfile.h
toolkit/tfilestream.h
toolkit/tmap.h
toolkit/tmap.tcc
toolkit/tpropertymap.h
mpeg/mpegfile.h
mpeg/mpegproperties.h
mpeg/mpegheader.h
mpeg/xingheader.h
mpeg/id3v1/id3v1tag.h
mpeg/id3v1/id3v1genres.h
mpeg/id3v2/id3v2extendedheader.h
mpeg/id3v2/id3v2frame.h
mpeg/id3v2/id3v2header.h
mpeg/id3v2/id3v2synchdata.h
mpeg/id3v2/id3v2footer.h
mpeg/id3v2/id3v2framefactory.h
mpeg/id3v2/id3v2tag.h
mpeg/id3v2/frames/attachedpictureframe.h
mpeg/id3v2/frames/commentsframe.h
mpeg/id3v2/frames/generalencapsulatedobjectframe.h
mpeg/id3v2/frames/ownershipframe.h
mpeg/id3v2/frames/popularimeterframe.h
mpeg/id3v2/frames/privateframe.h
mpeg/id3v2/frames/relativevolumeframe.h
mpeg/id3v2/frames/textidentificationframe.h
mpeg/id3v2/frames/uniquefileidentifierframe.h
mpeg/id3v2/frames/unknownframe.h
mpeg/id3v2/frames/unsynchronizedlyricsframe.h
mpeg/id3v2/frames/urllinkframe.h
ogg/oggfile.h
ogg/oggpage.h
ogg/oggpageheader.h
ogg/xiphcomment.h
ogg/vorbis/vorbisfile.h
ogg/vorbis/vorbisproperties.h
ogg/flac/oggflacfile.h
ogg/speex/speexfile.h
ogg/speex/speexproperties.h
flac/flacfile.h
flac/flacpicture.h
flac/flacproperties.h
flac/flacmetadatablock.h
ape/apefile.h
ape/apeproperties.h
ape/apetag.h
ape/apefooter.h
ape/apeitem.h
mpc/mpcfile.h
mpc/mpcproperties.h
wavpack/wavpackfile.h
wavpack/wavpackproperties.h
trueaudio/trueaudiofile.h
trueaudio/trueaudioproperties.h
riff/rifffile.h
riff/aiff/aifffile.h
riff/aiff/aiffproperties.h
riff/wav/wavfile.h
riff/wav/wavproperties.h
asf/asffile.h
asf/asfproperties.h
asf/asftag.h
asf/asfattribute.h
asf/asfpicture.h
mp4/mp4file.h
mp4/mp4atom.h
mp4/mp4tag.h
mp4/mp4item.h
mp4/mp4properties.h
mp4/mp4coverart.h
mod/modfilebase.h
mod/modfile.h
mod/modtag.h
mod/modproperties.h
it/itfile.h
it/itproperties.h
s3m/s3mfile.h
s3m/s3mproperties.h
xm/xmfile.h
xm/xmproperties.h
)
SET(id3v1_SRCS
mpeg/id3v1/id3v1tag.cpp
mpeg/id3v1/id3v1genres.cpp
set(mpeg_SRCS
mpeg/mpegfile.cpp
mpeg/mpegproperties.cpp
mpeg/mpegheader.cpp
mpeg/xingheader.cpp
)
SET(id3v2_SRCS
mpeg/id3v2/id3v2framefactory.cpp
mpeg/id3v2/id3v2synchdata.cpp
mpeg/id3v2/id3v2tag.cpp
mpeg/id3v2/id3v2header.cpp
mpeg/id3v2/id3v2frame.cpp
mpeg/id3v2/id3v2footer.cpp
mpeg/id3v2/id3v2extendedheader.cpp
set(id3v1_SRCS
mpeg/id3v1/id3v1tag.cpp
mpeg/id3v1/id3v1genres.cpp
)
set(id3v2_SRCS
mpeg/id3v2/id3v2framefactory.cpp
mpeg/id3v2/id3v2synchdata.cpp
mpeg/id3v2/id3v2tag.cpp
mpeg/id3v2/id3v2header.cpp
mpeg/id3v2/id3v2frame.cpp
mpeg/id3v2/id3v2footer.cpp
mpeg/id3v2/id3v2extendedheader.cpp
)
SET(frames_SRCS
mpeg/id3v2/frames/attachedpictureframe.cpp
mpeg/id3v2/frames/commentsframe.cpp
mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp
mpeg/id3v2/frames/relativevolumeframe.cpp
mpeg/id3v2/frames/textidentificationframe.cpp
mpeg/id3v2/frames/uniquefileidentifierframe.cpp
mpeg/id3v2/frames/unknownframe.cpp
mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp
mpeg/id3v2/frames/urllinkframe.cpp
set(frames_SRCS
mpeg/id3v2/frames/attachedpictureframe.cpp
mpeg/id3v2/frames/commentsframe.cpp
mpeg/id3v2/frames/generalencapsulatedobjectframe.cpp
mpeg/id3v2/frames/ownershipframe.cpp
mpeg/id3v2/frames/popularimeterframe.cpp
mpeg/id3v2/frames/privateframe.cpp
mpeg/id3v2/frames/relativevolumeframe.cpp
mpeg/id3v2/frames/textidentificationframe.cpp
mpeg/id3v2/frames/uniquefileidentifierframe.cpp
mpeg/id3v2/frames/unknownframe.cpp
mpeg/id3v2/frames/unsynchronizedlyricsframe.cpp
mpeg/id3v2/frames/urllinkframe.cpp
)
SET(ogg_SRCS
ogg/oggfile.cpp
ogg/oggpage.cpp
ogg/oggpageheader.cpp
ogg/xiphcomment.cpp
set(ogg_SRCS
ogg/oggfile.cpp
ogg/oggpage.cpp
ogg/oggpageheader.cpp
ogg/xiphcomment.cpp
)
SET(vorbis_SRCS
ogg/vorbis/vorbisfile.cpp
ogg/vorbis/vorbisproperties.cpp
set(vorbis_SRCS
ogg/vorbis/vorbisfile.cpp
ogg/vorbis/vorbisproperties.cpp
)
SET(flacs_SRCS
flac/flacfile.cpp
flac/flacproperties.cpp
set(flacs_SRCS
flac/flacfile.cpp
flac/flacpicture.cpp
flac/flacproperties.cpp
flac/flacmetadatablock.cpp
flac/flacunknownmetadatablock.cpp
)
SET(oggflacs_SRCS
ogg/flac/oggflacfile.cpp
set(oggflacs_SRCS
ogg/flac/oggflacfile.cpp
)
SET(mpc_SRCS
mpc/mpcfile.cpp
mpc/mpcproperties.cpp
set(mpc_SRCS
mpc/mpcfile.cpp
mpc/mpcproperties.cpp
)
SET(ape_SRCS
ape/apetag.cpp
ape/apefooter.cpp
ape/apeitem.cpp
set(mp4_SRCS
mp4/mp4file.cpp
mp4/mp4atom.cpp
mp4/mp4tag.cpp
mp4/mp4item.cpp
mp4/mp4properties.cpp
mp4/mp4coverart.cpp
)
SET(wavpack_SRCS
wavpack/wavpackfile.cpp
wavpack/wavpackproperties.cpp
set(ape_SRCS
ape/apetag.cpp
ape/apefooter.cpp
ape/apeitem.cpp
ape/apefile.cpp
ape/apeproperties.cpp
)
SET(speex_SRCS
ogg/speex/speexfile.cpp
ogg/speex/speexproperties.cpp
set(wavpack_SRCS
wavpack/wavpackfile.cpp
wavpack/wavpackproperties.cpp
)
SET(trueaudio_SRCS
trueaudio/trueaudiofile.cpp
trueaudio/trueaudioproperties.cpp
set(speex_SRCS
ogg/speex/speexfile.cpp
ogg/speex/speexproperties.cpp
)
SET(toolkit_SRCS
toolkit/tstring.cpp
toolkit/tstringlist.cpp
toolkit/tbytevector.cpp
toolkit/tbytevectorlist.cpp
toolkit/tfile.cpp
toolkit/tdebug.cpp
toolkit/unicode.cpp
set(trueaudio_SRCS
trueaudio/trueaudiofile.cpp
trueaudio/trueaudioproperties.cpp
)
SET(tag_LIB_SRCS ${mpeg_SRCS} ${id3v1_SRCS} ${id3v2_SRCS} ${frames_SRCS} ${ogg_SRCS}
${vorbis_SRCS} ${oggflacs_SRCS} ${mpc_SRCS} ${ape_SRCS} ${toolkit_SRCS} ${flacs_SRCS}
${wavpack_SRCS} ${speex_SRCS} ${trueaudio_SRCS}
tag.cpp
tagunion.cpp
fileref.cpp
audioproperties.cpp
set(asf_SRCS
asf/asftag.cpp
asf/asffile.cpp
asf/asfproperties.cpp
asf/asfattribute.cpp
asf/asfpicture.cpp
)
set(riff_SRCS
riff/rifffile.cpp
)
ADD_LIBRARY(tag SHARED ${tag_LIB_SRCS})
set(aiff_SRCS
riff/aiff/aifffile.cpp
riff/aiff/aiffproperties.cpp
)
set(wav_SRCS
riff/wav/wavfile.cpp
riff/wav/wavproperties.cpp
)
set(mod_SRCS
mod/modfilebase.cpp
mod/modfile.cpp
mod/modtag.cpp
mod/modproperties.cpp
)
set(s3m_SRCS
s3m/s3mfile.cpp
s3m/s3mproperties.cpp
)
set(it_SRCS
it/itfile.cpp
it/itproperties.cpp
)
set(xm_SRCS
xm/xmfile.cpp
xm/xmproperties.cpp
)
set(toolkit_SRCS
toolkit/tstring.cpp
toolkit/tstringlist.cpp
toolkit/tbytevector.cpp
toolkit/tbytevectorlist.cpp
toolkit/tbytevectorstream.cpp
toolkit/tiostream.cpp
toolkit/tfile.cpp
toolkit/tfilestream.cpp
toolkit/tdebug.cpp
toolkit/tpropertymap.cpp
toolkit/unicode.cpp
)
set(tag_LIB_SRCS
${mpeg_SRCS} ${id3v1_SRCS} ${id3v2_SRCS} ${frames_SRCS} ${ogg_SRCS}
${vorbis_SRCS} ${oggflacs_SRCS} ${mpc_SRCS} ${ape_SRCS} ${toolkit_SRCS} ${flacs_SRCS}
${wavpack_SRCS} ${speex_SRCS} ${trueaudio_SRCS} ${riff_SRCS} ${aiff_SRCS} ${wav_SRCS}
${asf_SRCS} ${mp4_SRCS} ${mod_SRCS} ${s3m_SRCS} ${it_SRCS} ${xm_SRCS}
tag.cpp
tagunion.cpp
fileref.cpp
audioproperties.cpp
)
add_library(tag ${tag_LIB_SRCS} ${tag_HDRS})
TARGET_LINK_LIBRARIES(tag )
if(ZLIB_FOUND)
TARGET_LINK_LIBRARIES(tag ${ZLIB_LIBRARIES})
endif(ZLIB_FOUND)
target_link_libraries(tag ${ZLIB_LIBRARIES})
endif()
SET_TARGET_PROPERTIES(tag PROPERTIES
VERSION ${TAGLIB_LIB_MAJOR_VERSION}.${TAGLIB_LIB_MINOR_VERSION}.${TAGLIB_LIB_PATCH_VERSION}
SOVERSION ${TAGLIB_LIB_MAJOR_VERSION}
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
DEFINE_SYMBOL MAKE_TAGLIB_LIB
set_target_properties(tag PROPERTIES
VERSION ${TAGLIB_SOVERSION_MAJOR}.${TAGLIB_SOVERSION_MINOR}.${TAGLIB_SOVERSION_PATCH}
SOVERSION ${TAGLIB_SOVERSION_MAJOR}
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
DEFINE_SYMBOL MAKE_TAGLIB_LIB
LINK_INTERFACE_LIBRARIES ""
PUBLIC_HEADER "${tag_HDRS}"
)
INSTALL(TARGETS tag
if(BUILD_FRAMEWORK)
set_target_properties(tag PROPERTIES FRAMEWORK TRUE)
endif()
install(TARGETS tag
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION bin
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR}/taglib
)
INSTALL( FILES tag.h fileref.h audioproperties.h taglib_export.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)

View File

@@ -1,26 +0,0 @@
SUBDIRS = toolkit mpeg ogg flac ape mpc wavpack trueaudio
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/ogg/flac \
-I$(top_srcdir)/taglib/flac \
-I$(top_srcdir)/taglib/mpc \
-I$(top_srcdir)/taglib/ogg/vorbis \
-I$(top_srcdir)/taglib/ogg/speex \
-I$(top_srcdir)/taglib/wavpack \
-I$(top_srcdir)/taglib/trueaudio \
$(all_includes)
lib_LTLIBRARIES = libtag.la
libtag_la_SOURCES = tag.cpp tagunion.cpp fileref.cpp audioproperties.cpp
taglib_include_HEADERS = tag.h fileref.h audioproperties.h taglib_export.h
taglib_includedir = $(includedir)/taglib
libtag_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 6:0:5
libtag_la_LIBADD = ./mpeg/libmpeg.la ./ogg/libogg.la ./flac/libflac.la ./mpc/libmpc.la \
./ape/libape.la ./toolkit/libtoolkit.la ./wavpack/libwavpack.la \
./trueaudio/libtrueaudio.la

View File

@@ -1 +0,0 @@
INSTALL( FILES apetag.h apefooter.h apeitem.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib)

View File

@@ -1,11 +0,0 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
$(all_includes)
noinst_LTLIBRARIES = libape.la
libape_la_SOURCES = apetag.cpp apefooter.cpp apeitem.cpp
taglib_include_HEADERS = apetag.h apefooter.h apeitem.h
taglib_includedir = $(includedir)/taglib

305
taglib/ape/apefile.cpp Normal file
View File

@@ -0,0 +1,305 @@
/***************************************************************************
copyright : (C) 2010 by Alex Novichkov
email : novichko@atnet.ru
copyright : (C) 2006 by Lukáš Lalinský
email : lalinsky@gmail.com
(original WavPack implementation)
copyright : (C) 2004 by Allan Sandfeld Jensen
email : kde@carewolf.org
(original MPC implementation)
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tbytevector.h>
#include <tstring.h>
#include <tdebug.h>
#include <tagunion.h>
#include <id3v1tag.h>
#include <tpropertymap.h>
#include "apefile.h"
#include "apetag.h"
#include "apefooter.h"
using namespace TagLib;
namespace
{
enum { ApeAPEIndex, ApeID3v1Index };
}
class APE::File::FilePrivate
{
public:
FilePrivate() :
APELocation(-1),
APESize(0),
ID3v1Location(-1),
properties(0),
hasAPE(false),
hasID3v1(false) {}
~FilePrivate()
{
delete properties;
}
long APELocation;
uint APESize;
long ID3v1Location;
TagUnion tag;
Properties *properties;
// These indicate whether the file *on disk* has these tags, not if
// this data structure does. This is used in computing offsets.
bool hasAPE;
bool hasID3v1;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
APE::File::File(FileName file, bool readProperties,
Properties::ReadStyle propertiesStyle) : TagLib::File(file)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
APE::File::File(IOStream *stream, bool readProperties,
Properties::ReadStyle propertiesStyle) : TagLib::File(stream)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
APE::File::~File()
{
delete d;
}
TagLib::Tag *APE::File::tag() const
{
return &d->tag;
}
PropertyMap APE::File::properties() const
{
if(d->hasAPE)
return d->tag.access<APE::Tag>(ApeAPEIndex, false)->properties();
if(d->hasID3v1)
return d->tag.access<ID3v1::Tag>(ApeID3v1Index, false)->properties();
return PropertyMap();
}
void APE::File::removeUnsupportedProperties(const StringList &properties)
{
if(d->hasAPE)
d->tag.access<APE::Tag>(ApeAPEIndex, false)->removeUnsupportedProperties(properties);
if(d->hasID3v1)
d->tag.access<ID3v1::Tag>(ApeID3v1Index, false)->removeUnsupportedProperties(properties);
}
PropertyMap APE::File::setProperties(const PropertyMap &properties)
{
if(d->hasAPE)
return d->tag.access<APE::Tag>(ApeAPEIndex, false)->setProperties(properties);
else if(d->hasID3v1)
return d->tag.access<ID3v1::Tag>(ApeID3v1Index, false)->setProperties(properties);
else
return d->tag.access<APE::Tag>(ApeAPEIndex, true)->setProperties(properties);
}
APE::Properties *APE::File::audioProperties() const
{
return d->properties;
}
bool APE::File::save()
{
if(readOnly()) {
debug("APE::File::save() -- File is read only.");
return false;
}
// Update ID3v1 tag
if(ID3v1Tag()) {
if(d->hasID3v1) {
seek(d->ID3v1Location);
writeBlock(ID3v1Tag()->render());
}
else {
seek(0, End);
d->ID3v1Location = tell();
writeBlock(ID3v1Tag()->render());
d->hasID3v1 = true;
}
}
else {
if(d->hasID3v1) {
removeBlock(d->ID3v1Location, 128);
d->hasID3v1 = false;
if(d->hasAPE) {
if(d->APELocation > d->ID3v1Location)
d->APELocation -= 128;
}
}
}
// Update APE tag
if(APETag()) {
if(d->hasAPE)
insert(APETag()->render(), d->APELocation, d->APESize);
else {
if(d->hasID3v1) {
insert(APETag()->render(), d->ID3v1Location, 0);
d->APESize = APETag()->footer()->completeTagSize();
d->hasAPE = true;
d->APELocation = d->ID3v1Location;
d->ID3v1Location += d->APESize;
}
else {
seek(0, End);
d->APELocation = tell();
writeBlock(APETag()->render());
d->APESize = APETag()->footer()->completeTagSize();
d->hasAPE = true;
}
}
}
else {
if(d->hasAPE) {
removeBlock(d->APELocation, d->APESize);
d->hasAPE = false;
if(d->hasID3v1) {
if(d->ID3v1Location > d->APELocation) {
d->ID3v1Location -= d->APESize;
}
}
}
}
return true;
}
ID3v1::Tag *APE::File::ID3v1Tag(bool create)
{
return d->tag.access<ID3v1::Tag>(ApeID3v1Index, create);
}
APE::Tag *APE::File::APETag(bool create)
{
return d->tag.access<APE::Tag>(ApeAPEIndex, create);
}
void APE::File::strip(int tags)
{
if(tags & ID3v1) {
d->tag.set(ApeID3v1Index, 0);
APETag(true);
}
if(tags & APE) {
d->tag.set(ApeAPEIndex, 0);
if(!ID3v1Tag())
APETag(true);
}
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void APE::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
{
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->tag.set(ApeID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
d->hasID3v1 = true;
}
// Look for an APE tag
d->APELocation = findAPE();
if(d->APELocation >= 0) {
d->tag.set(ApeAPEIndex, new APE::Tag(this, d->APELocation));
d->APESize = APETag()->footer()->completeTagSize();
d->APELocation = d->APELocation + APETag()->footer()->size() - d->APESize;
d->hasAPE = true;
}
if(!d->hasID3v1)
APETag(true);
// Look for APE audio properties
if(readProperties) {
d->properties = new Properties(this);
}
}
long APE::File::findAPE()
{
if(!isValid())
return -1;
if(d->hasID3v1)
seek(-160, End);
else
seek(-32, End);
long p = tell();
if(readBlock(8) == APE::Tag::fileIdentifier())
return p;
return -1;
}
long APE::File::findID3v1()
{
if(!isValid())
return -1;
seek(-128, End);
long p = tell();
if(readBlock(3) == ID3v1::Tag::fileIdentifier())
return p;
return -1;
}

201
taglib/ape/apefile.h Normal file
View File

@@ -0,0 +1,201 @@
/***************************************************************************
copyright : (C) 2010 by Alex Novichkov
email : novichko@atnet.ru
copyright : (C) 2006 by Lukáš Lalinský
email : lalinsky@gmail.com
(original WavPack implementation)
copyright : (C) 2004 by Allan Sandfeld Jensen
email : kde@carewolf.org
(original MPC implementation)
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_APEFILE_H
#define TAGLIB_APEFILE_H
#include "tfile.h"
#include "taglib_export.h"
#include "apeproperties.h"
namespace TagLib {
class Tag;
namespace ID3v1 { class Tag; }
namespace APE { class Tag; }
//! An implementation of APE metadata
/*!
* This is implementation of APE metadata.
*
* This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream
* properties from the file.
*/
namespace APE {
//! An implementation of TagLib::File with APE specific methods
/*!
* This implements and provides an interface APE WavPack files to the
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
* the abstract TagLib::File API as well as providing some additional
* information specific to APE files.
*/
class TAGLIB_EXPORT File : public TagLib::File
{
public:
/*!
* This set of flags is used for various operations and is suitable for
* being OR-ed together.
*/
enum TagTypes {
//! Empty set. Matches no tag types.
NoTags = 0x0000,
//! Matches ID3v1 tags.
ID3v1 = 0x0001,
//! Matches APE tags.
APE = 0x0002,
//! Matches all tag types.
AllTags = 0xffff
};
/*!
* Contructs an WavPack file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*/
File(FileName file, bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Contructs an WavPack file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
File(IOStream *stream, bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Destroys this instance of the File.
*/
virtual ~File();
/*!
* Returns the Tag for this file. This will be an APE tag, an ID3v1 tag
* or a combination of the two.
*/
virtual TagLib::Tag *tag() const;
/*!
* Implements the unified property interface -- export function.
* If the file contains both an APE and an ID3v1 tag, only APE
* will be converted to the PropertyMap.
*/
PropertyMap properties() const;
/*!
* Removes unsupported properties. Forwards to the actual Tag's
* removeUnsupportedProperties() function.
*/
void removeUnsupportedProperties(const StringList &properties);
/*!
* Implements the unified property interface -- import function.
* As for the export, only one tag is taken into account. If the file
* has no tag at all, APE will be created.
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Returns the APE::Properties for this file. If no audio properties
* were read then this will return a null pointer.
*/
virtual Properties *audioProperties() const;
/*!
* Saves the file.
*
* \note According to the official Monkey's Audio SDK, an APE file
* can only have either ID3V1 or APE tags, so a parameter is used here.
*/
virtual bool save();
/*!
* Returns a pointer to the ID3v1 tag of the file.
*
* If \a create is false (the default) this will return a null pointer
* if there is no valid ID3v1 tag. If \a create is true it will create
* an ID3v1 tag if one does not exist. If there is already an APE tag, the
* new ID3v1 tag will be placed after it.
*
* \note The Tag <b>is still</b> owned by the APE::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*/
ID3v1::Tag *ID3v1Tag(bool create = false);
/*!
* Returns a pointer to the APE tag of the file.
*
* If \a create is false (the default) this will return a null pointer
* if there is no valid APE tag. If \a create is true it will create
* a APE tag if one does not exist.
*
* \note The Tag <b>is still</b> owned by the APE::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*/
APE::Tag *APETag(bool create = false);
/*!
* This will remove the tags that match the OR-ed together TagTypes from the
* file. By default it removes all tags.
*
* \note This will also invalidate pointers to the tags
* as their memory will be freed.
* \note In order to make the removal permanent save() still needs to be called
*/
void strip(int tags = AllTags);
private:
File(const File &);
File &operator=(const File &);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
void scan();
long findID3v1();
long findAPE();
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

View File

@@ -16,8 +16,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -35,7 +35,7 @@
using namespace TagLib;
using namespace APE;
class Footer::FooterPrivate
class APE::Footer::FooterPrivate
{
public:
FooterPrivate() : version(0),
@@ -64,12 +64,12 @@ public:
// static members
////////////////////////////////////////////////////////////////////////////////
TagLib::uint Footer::size()
TagLib::uint APE::Footer::size()
{
return FooterPrivate::size;
}
ByteVector Footer::fileIdentifier()
ByteVector APE::Footer::fileIdentifier()
{
return ByteVector::fromCString("APETAGEX");
}
@@ -78,63 +78,63 @@ ByteVector Footer::fileIdentifier()
// public members
////////////////////////////////////////////////////////////////////////////////
Footer::Footer()
APE::Footer::Footer()
{
d = new FooterPrivate;
}
Footer::Footer(const ByteVector &data)
APE::Footer::Footer(const ByteVector &data)
{
d = new FooterPrivate;
parse(data);
}
Footer::~Footer()
APE::Footer::~Footer()
{
delete d;
}
TagLib::uint Footer::version() const
TagLib::uint APE::Footer::version() const
{
return d->version;
}
bool Footer::headerPresent() const
bool APE::Footer::headerPresent() const
{
return d->headerPresent;
}
bool Footer::footerPresent() const
bool APE::Footer::footerPresent() const
{
return d->footerPresent;
}
bool Footer::isHeader() const
bool APE::Footer::isHeader() const
{
return d->isHeader;
}
void Footer::setHeaderPresent(bool b) const
void APE::Footer::setHeaderPresent(bool b) const
{
d->headerPresent = b;
}
TagLib::uint Footer::itemCount() const
TagLib::uint APE::Footer::itemCount() const
{
return d->itemCount;
}
void Footer::setItemCount(uint s)
void APE::Footer::setItemCount(uint s)
{
d->itemCount = s;
}
TagLib::uint Footer::tagSize() const
TagLib::uint APE::Footer::tagSize() const
{
return d->tagSize;
}
TagLib::uint Footer::completeTagSize() const
TagLib::uint APE::Footer::completeTagSize() const
{
if(d->headerPresent)
return d->tagSize + d->size;
@@ -142,22 +142,22 @@ TagLib::uint Footer::completeTagSize() const
return d->tagSize;
}
void Footer::setTagSize(uint s)
void APE::Footer::setTagSize(uint s)
{
d->tagSize = s;
}
void Footer::setData(const ByteVector &data)
void APE::Footer::setData(const ByteVector &data)
{
parse(data);
}
ByteVector Footer::renderFooter() const
ByteVector APE::Footer::renderFooter() const
{
return render(false);
}
ByteVector Footer::renderHeader() const
ByteVector APE::Footer::renderHeader() const
{
if (!d->headerPresent) return ByteVector();
@@ -168,7 +168,7 @@ ByteVector Footer::renderHeader() const
// protected members
////////////////////////////////////////////////////////////////////////////////
void Footer::parse(const ByteVector &data)
void APE::Footer::parse(const ByteVector &data)
{
if(data.size() < size())
return;
@@ -189,7 +189,7 @@ void Footer::parse(const ByteVector &data)
// Read the flags
std::bitset<32> flags(data.mid(20, 4).toUInt(false));
std::bitset<32> flags(TAGLIB_CONSTRUCT_BITSET(data.mid(20, 4).toUInt(false)));
d->headerPresent = flags[31];
d->footerPresent = !flags[30];
@@ -197,7 +197,7 @@ void Footer::parse(const ByteVector &data)
}
ByteVector Footer::render(bool isHeader) const
ByteVector APE::Footer::render(bool isHeader) const
{
ByteVector v;

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -62,6 +62,18 @@ APE::Item::Item(const String &key, const StringList &values)
d->text = values;
}
APE::Item::Item(const String &key, const ByteVector &value, bool binary)
{
d = new ItemPrivate;
d->key = key;
if(binary) {
d->type = Binary;
d->value = value;
}
else
d->text.append(value);
}
APE::Item::Item(const Item &item)
{
d = new ItemPrivate(*item.d);
@@ -104,6 +116,17 @@ String APE::Item::key() const
return d->key;
}
ByteVector APE::Item::binaryData() const
{
return d->value;
}
void APE::Item::setBinaryData(const ByteVector &value)
{
d->type = Binary;
d->value = value;
}
ByteVector APE::Item::value() const
{
// This seems incorrect as it won't be actually rendering the value to keep it
@@ -119,27 +142,50 @@ void APE::Item::setKey(const String &key)
void APE::Item::setValue(const String &value)
{
d->type = Text;
d->text = value;
}
void APE::Item::setValues(const StringList &value)
{
d->type = Text;
d->text = value;
}
void APE::Item::appendValue(const String &value)
{
d->type = Text;
d->text.append(value);
}
void APE::Item::appendValues(const StringList &values)
{
d->type = Text;
d->text.append(values);
}
int APE::Item::size() const
{
return 8 + d->key.size() + 1 + d->value.size();
// SFB: Why is d->key.size() used when size() returns the length in UniChars and not UTF-8?
int result = 8 + d->key.size() /* d->key.data(String::UTF8).size() */ + 1;
switch (d->type) {
case Text:
if(d->text.size()) {
StringList::ConstIterator it = d->text.begin();
result += it->data(String::UTF8).size();
it++;
for(; it != d->text.end(); ++it)
result += 1 + it->data(String::UTF8).size();
}
break;
case Binary:
case Locator:
result += d->value.size();
break;
}
return result;
}
StringList APE::Item::toStringList() const
@@ -160,14 +206,14 @@ String APE::Item::toString() const
bool APE::Item::isEmpty() const
{
switch(d->type) {
case 0:
case 1:
case Text:
if(d->text.isEmpty())
return true;
if(d->text.size() == 1 && d->text.front().isEmpty())
return true;
return false;
case 2:
case Binary:
case Locator:
return d->value.isEmpty();
default:
return false;
@@ -193,7 +239,7 @@ void APE::Item::parse(const ByteVector &data)
setReadOnly(flags & 1);
setType(ItemTypes((flags >> 1) & 3));
if(int(d->type) < 2)
if(Text == d->type)
d->text = StringList(ByteVectorList::split(d->value, '\0'), String::UTF8);
}
@@ -206,8 +252,9 @@ ByteVector APE::Item::render() const
if(isEmpty())
return data;
if(d->type != Item::Binary) {
if(d->type == Text) {
StringList::ConstIterator it = d->text.begin();
value.append(it->data(String::UTF8));
it++;
for(; it != d->text.end(); ++it) {

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -59,16 +59,22 @@ namespace TagLib {
Item();
/*!
* Constructs an item with \a key and \a value.
* Constructs a text item with \a key and \a value.
*/
// BIC: Remove this, StringList has a constructor from a single string
Item(const String &key, const String &value);
/*!
* Constructs an item with \a key and \a values.
* Constructs a text item with \a key and \a values.
*/
Item(const String &key, const StringList &values);
/*!
* Constructs an item with \a key and \a value.
* If \a binary is true a Binary item will be created, otherwise \a value will be interpreted as text
*/
Item(const String &key, const ByteVector &value, bool binary);
/*!
* Construct an item as a copy of \a item.
*/
@@ -91,12 +97,20 @@ namespace TagLib {
/*!
* Returns the binary value.
*
* \deprecated This will be removed in the next binary incompatible version
* as it is not kept in sync with the things that are set using setValue()
* and friends.
* If the item type is not \a Binary, the returned contents are undefined
*/
ByteVector binaryData() const;
/*!
* Set the binary value to \a value
* The item's type will also be set to \a Binary
*/
void setBinaryData(const ByteVector &value);
#ifndef DO_NOT_DOCUMENT
/* Remove in next binary incompatible release */
ByteVector value() const;
#endif
/*!
* Sets the key for the item to \a key.
@@ -104,14 +118,14 @@ namespace TagLib {
void setKey(const String &key);
/*!
* Sets the value of the item to \a value and clears any previous contents.
* Sets the text value of the item to \a value and clears any previous contents.
*
* \see toString()
*/
void setValue(const String &value);
/*!
* Sets the value of the item to the list of values in \a value and clears
* Sets the text value of the item to the list of values in \a value and clears
* any previous contents.
*
* \see toStringList()
@@ -119,14 +133,14 @@ namespace TagLib {
void setValues(const StringList &values);
/*!
* Appends \a value to create (or extend) the current list of values.
* Appends \a value to create (or extend) the current list of text values.
*
* \see toString()
*/
void appendValue(const String &value);
/*!
* Appends \a values to extend the current list of values.
* Appends \a values to extend the current list of text values.
*
* \see toStringList()
*/
@@ -143,14 +157,13 @@ namespace TagLib {
*/
String toString() const;
/*!
* \deprecated
* \see values
*/
#ifndef DO_NOT_DOCUMENT
/* Remove in next binary incompatible release */
StringList toStringList() const;
#endif
/*!
* Returns the list of values.
* Returns the list of text values.
*/
StringList values() const;

View File

@@ -0,0 +1,231 @@
/***************************************************************************
copyright : (C) 2010 by Alex Novichkov
email : novichko@atnet.ru
copyright : (C) 2006 by Lukáš Lalinský
email : lalinsky@gmail.com
(original WavPack implementation)
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#include <tstring.h>
#include <tdebug.h>
#include <bitset>
#include "id3v2tag.h"
#include "apeproperties.h"
#include "apefile.h"
using namespace TagLib;
class APE::Properties::PropertiesPrivate
{
public:
PropertiesPrivate(File *file, long streamLength) :
length(0),
bitrate(0),
sampleRate(0),
channels(0),
version(0),
bitsPerSample(0),
sampleFrames(0),
file(file),
streamLength(streamLength) {}
int length;
int bitrate;
int sampleRate;
int channels;
int version;
int bitsPerSample;
uint sampleFrames;
File *file;
long streamLength;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
APE::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
{
d = new PropertiesPrivate(file, file->length());
read();
}
APE::Properties::~Properties()
{
delete d;
}
int APE::Properties::length() const
{
return d->length;
}
int APE::Properties::bitrate() const
{
return d->bitrate;
}
int APE::Properties::sampleRate() const
{
return d->sampleRate;
}
int APE::Properties::channels() const
{
return d->channels;
}
int APE::Properties::version() const
{
return d->version;
}
int APE::Properties::bitsPerSample() const
{
return d->bitsPerSample;
}
TagLib::uint APE::Properties::sampleFrames() const
{
return d->sampleFrames;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void APE::Properties::read()
{
// First we are searching the descriptor
long offset = findDescriptor();
if(offset < 0)
return;
// Then we read the header common for all versions of APE
d->file->seek(offset);
ByteVector commonHeader=d->file->readBlock(6);
if(!commonHeader.startsWith("MAC "))
return;
d->version = commonHeader.mid(4).toUInt(false);
if(d->version >= 3980) {
analyzeCurrent();
}
else {
analyzeOld();
}
}
long APE::Properties::findDescriptor()
{
long ID3v2Location = findID3v2();
long ID3v2OriginalSize = 0;
bool hasID3v2 = false;
if(ID3v2Location >= 0) {
ID3v2::Tag tag(d->file, ID3v2Location);
ID3v2OriginalSize = tag.header()->completeTagSize();
if(tag.header()->tagSize() > 0)
hasID3v2 = true;
}
long offset = 0;
if(hasID3v2)
offset = d->file->find("MAC ", ID3v2Location + ID3v2OriginalSize);
else
offset = d->file->find("MAC ");
if(offset < 0) {
debug("APE::Properties::findDescriptor() -- APE descriptor not found");
return -1;
}
return offset;
}
long APE::Properties::findID3v2()
{
if(!d->file->isValid())
return -1;
d->file->seek(0);
if(d->file->readBlock(3) == ID3v2::Header::fileIdentifier())
return 0;
return -1;
}
void APE::Properties::analyzeCurrent()
{
// Read the descriptor
d->file->seek(2, File::Current);
ByteVector descriptor = d->file->readBlock(44);
uint descriptorBytes = descriptor.mid(0,4).toUInt(false);
if ((descriptorBytes - 52) > 0)
d->file->seek(descriptorBytes - 52, File::Current);
// Read the header
ByteVector header = d->file->readBlock(24);
// Get the APE info
d->channels = header.mid(18, 2).toShort(false);
d->sampleRate = header.mid(20, 4).toUInt(false);
d->bitsPerSample = header.mid(16, 2).toShort(false);
//d->compressionLevel =
uint totalFrames = header.mid(12, 4).toUInt(false);
uint blocksPerFrame = header.mid(4, 4).toUInt(false);
uint finalFrameBlocks = header.mid(8, 4).toUInt(false);
d->sampleFrames = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0;
d->length = d->sampleRate > 0 ? d->sampleFrames / d->sampleRate : 0;
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
}
void APE::Properties::analyzeOld()
{
ByteVector header = d->file->readBlock(26);
uint totalFrames = header.mid(18, 4).toUInt(false);
// Fail on 0 length APE files (catches non-finalized APE files)
if(totalFrames == 0)
return;
short compressionLevel = header.mid(0, 2).toShort(false);
uint blocksPerFrame;
if(d->version >= 3950)
blocksPerFrame = 73728 * 4;
else if(d->version >= 3900 || (d->version >= 3800 && compressionLevel == 4000))
blocksPerFrame = 73728;
else
blocksPerFrame = 9216;
d->channels = header.mid(4, 2).toShort(false);
d->sampleRate = header.mid(6, 4).toUInt(false);
uint finalFrameBlocks = header.mid(22, 4).toUInt(false);
uint totalBlocks = totalFrames > 0 ? (totalFrames - 1) * blocksPerFrame + finalFrameBlocks : 0;
d->length = totalBlocks / d->sampleRate;
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
}

View File

@@ -0,0 +1,99 @@
/***************************************************************************
copyright : (C) 2010 by Alex Novichkov
email : novichko@atnet.ru
copyright : (C) 2006 by Lukáš Lalinský
email : lalinsky@gmail.com
(original WavPack implementation)
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_APEPROPERTIES_H
#define TAGLIB_APEPROPERTIES_H
#include "taglib_export.h"
#include "audioproperties.h"
namespace TagLib {
namespace APE {
class File;
//! An implementation of audio property reading for APE
/*!
* This reads the data from an APE stream found in the AudioProperties
* API.
*/
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:
/*!
* Create an instance of APE::Properties with the data read from the
* ByteVector \a data.
*/
Properties(File *f, ReadStyle style = Average);
/*!
* Destroys this APE::Properties instance.
*/
virtual ~Properties();
// Reimplementations.
virtual int length() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
/*!
* Returns number of bits per sample.
*/
int bitsPerSample() const;
uint sampleFrames() const;
/*!
* Returns APE version.
*/
int version() const;
private:
Properties(const Properties &);
Properties &operator=(const Properties &);
void read();
long findDescriptor();
long findID3v2();
void analyzeCurrent();
void analyzeOld();
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -34,6 +34,7 @@
#include <tfile.h>
#include <tstring.h>
#include <tmap.h>
#include <tpropertymap.h>
#include "apetag.h"
#include "apefooter.h"
@@ -47,7 +48,7 @@ class APE::Tag::TagPrivate
public:
TagPrivate() : file(0), footerLocation(-1), tagLength(0) {}
File *file;
TagLib::File *file;
long footerLocation;
long tagLength;
@@ -65,7 +66,7 @@ APE::Tag::Tag() : TagLib::Tag()
d = new TagPrivate;
}
APE::Tag::Tag(File *file, long footerLocation) : TagLib::Tag()
APE::Tag::Tag(TagLib::File *file, long footerLocation) : TagLib::Tag()
{
d = new TagPrivate;
d->file = file;
@@ -174,6 +175,103 @@ void APE::Tag::setTrack(uint i)
addValue("TRACK", String::number(i), true);
}
// conversions of tag keys between what we use in PropertyMap and what's usual
// for APE tags
static const TagLib::uint keyConversionsSize = 5; //usual, APE
static const char *keyConversions[][2] = {{"TRACKNUMBER", "TRACK" },
{"DATE", "YEAR" },
{"ALBUMARTIST", "ALBUM ARTIST"},
{"DISCNUMBER", "DISC" },
{"REMIXER", "MIXARTIST" }};
PropertyMap APE::Tag::properties() const
{
PropertyMap properties;
ItemListMap::ConstIterator it = itemListMap().begin();
for(; it != itemListMap().end(); ++it) {
String tagName = it->first.upper();
// if the item is Binary or Locator, or if the key is an invalid string,
// add to unsupportedData
if(it->second.type() != Item::Text || tagName.isNull())
properties.unsupportedData().append(it->first);
else {
// Some tags need to be handled specially
for(uint i = 0; i < keyConversionsSize; ++i)
if(tagName == keyConversions[i][1])
tagName = keyConversions[i][0];
properties[tagName].append(it->second.toStringList());
}
}
return properties;
}
void APE::Tag::removeUnsupportedProperties(const StringList &properties)
{
StringList::ConstIterator it = properties.begin();
for(; it != properties.end(); ++it)
removeItem(*it);
}
PropertyMap APE::Tag::setProperties(const PropertyMap &origProps)
{
PropertyMap properties(origProps); // make a local copy that can be modified
// see comment in properties()
for(uint i = 0; i < keyConversionsSize; ++i)
if(properties.contains(keyConversions[i][0])) {
properties.insert(keyConversions[i][1], properties[keyConversions[i][0]]);
properties.erase(keyConversions[i][0]);
}
// first check if tags need to be removed completely
StringList toRemove;
ItemListMap::ConstIterator remIt = itemListMap().begin();
for(; remIt != itemListMap().end(); ++remIt) {
String key = remIt->first.upper();
// only remove if a) key is valid, b) type is text, c) key not contained in new properties
if(!key.isNull() && remIt->second.type() == APE::Item::Text && !properties.contains(key))
toRemove.append(remIt->first);
}
for (StringList::Iterator removeIt = toRemove.begin(); removeIt != toRemove.end(); removeIt++)
removeItem(*removeIt);
// now sync in the "forward direction"
PropertyMap::ConstIterator it = properties.begin();
PropertyMap invalid;
for(; it != properties.end(); ++it) {
const String &tagName = it->first;
if(!checkKey(tagName))
invalid.insert(it->first, it->second);
else if(!(itemListMap().contains(tagName)) || !(itemListMap()[tagName].values() == it->second)) {
if(it->second.size() == 0)
removeItem(tagName);
else {
StringList::ConstIterator valueIt = it->second.begin();
addValue(tagName, *valueIt, true);
++valueIt;
for(; valueIt != it->second.end(); ++valueIt)
addValue(tagName, *valueIt, false);
}
}
}
return invalid;
}
bool APE::Tag::checkKey(const String &key)
{
if(key.size() < 2 || key.size() > 16)
return false;
for(String::ConstIterator it = key.begin(); it != key.end(); it++)
// only allow printable ASCII including space (32..127)
if (*it < 32 || *it >= 128)
return false;
String upperKey = key.upper();
if (upperKey=="ID3" || upperKey=="TAG" || upperKey=="OGGS" || upperKey=="MP+")
return false;
return true;
}
APE::Footer *APE::Tag::footer() const
{
return &d->footer;
@@ -195,17 +293,36 @@ void APE::Tag::addValue(const String &key, const String &value, bool replace)
{
if(replace)
removeItem(key);
if(!value.isEmpty()) {
if(d->itemListMap.contains(key) || !replace)
d->itemListMap[key.upper()].appendValue(value);
if(!key.isEmpty() && !value.isEmpty()) {
if(!replace && d->itemListMap.contains(key)) {
// Text items may contain more than one value
if(APE::Item::Text == d->itemListMap.begin()->second.type())
d->itemListMap[key.upper()].appendValue(value);
// Binary or locator items may have only one value
else
setItem(key, Item(key, value));
}
else
setItem(key, Item(key, value));
}
}
void APE::Tag::setData(const String &key, const ByteVector &value)
{
removeItem(key);
if(!key.isEmpty() && !value.isEmpty())
setItem(key, Item(key, value, true));
}
void APE::Tag::setItem(const String &key, const Item &item)
{
d->itemListMap.insert(key.upper(), item);
if(!key.isEmpty())
d->itemListMap.insert(key.upper(), item);
}
bool APE::Tag::isEmpty() const
{
return d->itemListMap.isEmpty();
}
////////////////////////////////////////////////////////////////////////////////

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -66,7 +66,7 @@ namespace TagLib {
* Create an APE tag and parse the data in \a file with APE footer at
* \a tagOffset.
*/
Tag(File *file, long footerLocation);
Tag(TagLib::File *file, long footerLocation);
/*!
* Destroys this Tag instance.
@@ -103,6 +103,37 @@ namespace TagLib {
virtual void setYear(uint i);
virtual void setTrack(uint i);
/*!
* Implements the unified tag dictionary interface -- export function.
* APE tags are perfectly compatible with the dictionary interface because they
* support both arbitrary tag names and multiple values. Currently only
* APE items of type *Text* are handled by the dictionary interface; all *Binary*
* and *Locator* items will be put into the unsupportedData list and can be
* deleted on request using removeUnsupportedProperties(). The same happens
* to Text items if their key is invalid for PropertyMap (which should actually
* never happen).
*
* The only conversion done by this export function is to rename the APE tags
* TRACK to TRACKNUMBER, YEAR to DATE, and ALBUM ARTIST to ALBUMARTIST, respectively,
* in order to be compliant with the names used in other formats.
*/
PropertyMap properties() const;
void removeUnsupportedProperties(const StringList &properties);
/*!
* Implements the unified tag dictionary interface -- import function. The same
* comments as for the export function apply; additionally note that the APE tag
* specification requires keys to have between 2 and 16 printable ASCII characters
* with the exception of the fixed strings "ID3", "TAG", "OGGS", and "MP+".
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Check if the given String is a valid APE tag key.
*/
static bool checkKey(const String&);
/*!
* Returns a pointer to the tag's footer.
*/
@@ -114,6 +145,9 @@ namespace TagLib {
*
* This is the most powerfull structure for accessing the items of the tag.
*
* APE tags are case-insensitive, all keys in this map have been converted
* to upper case.
*
* \warning You should not modify this data structure directly, instead
* use setItem() and removeItem().
*/
@@ -125,18 +159,30 @@ namespace TagLib {
void removeItem(const String &key);
/*!
* Adds to the item specified by \a key the data \a value. If \a replace
* Adds to the text item specified by \a key the data \a value. If \a replace
* is true, then all of the other values on the same key will be removed
* first.
* first. If a binary item exists for \a key it will be removed first.
*/
void addValue(const String &key, const String &value, bool replace = true);
/*!
* Set the binary data for the key specified by \a item to \a value
* This will convert the item to type \a Binary if it isn't already and
* all of the other values on the same key will be removed.
*/
void setData(const String &key, const ByteVector &value);
/*!
* Sets the \a key item to the value of \a item. If an item with the \a key is already
* present, it will be replaced.
*/
void setItem(const String &key, const Item &item);
/*!
* Returns true if the tag does not contain any data.
*/
bool isEmpty() const;
protected:
/*!

353
taglib/asf/asfattribute.cpp Normal file
View File

@@ -0,0 +1,353 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <taglib.h>
#include <tdebug.h>
#include "asfattribute.h"
#include "asffile.h"
using namespace TagLib;
class ASF::Attribute::AttributePrivate : public RefCounter
{
public:
AttributePrivate()
: pictureValue(ASF::Picture::fromInvalid()),
stream(0),
language(0) {}
AttributeTypes type;
String stringValue;
ByteVector byteVectorValue;
ASF::Picture pictureValue;
union {
unsigned int intValue;
unsigned short shortValue;
unsigned long long longLongValue;
bool boolValue;
};
int stream;
int language;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
ASF::Attribute::Attribute()
{
d = new AttributePrivate;
d->type = UnicodeType;
}
ASF::Attribute::Attribute(const ASF::Attribute &other)
: d(other.d)
{
d->ref();
}
ASF::Attribute &ASF::Attribute::operator=(const ASF::Attribute &other)
{
if(d->deref())
delete d;
d = other.d;
d->ref();
return *this;
}
ASF::Attribute::~Attribute()
{
if(d->deref())
delete d;
}
ASF::Attribute::Attribute(const String &value)
{
d = new AttributePrivate;
d->type = UnicodeType;
d->stringValue = value;
}
ASF::Attribute::Attribute(const ByteVector &value)
{
d = new AttributePrivate;
d->type = BytesType;
d->byteVectorValue = value;
}
ASF::Attribute::Attribute(const ASF::Picture &value)
{
d = new AttributePrivate;
d->type = BytesType;
d->pictureValue = value;
}
ASF::Attribute::Attribute(unsigned int value)
{
d = new AttributePrivate;
d->type = DWordType;
d->intValue = value;
}
ASF::Attribute::Attribute(unsigned long long value)
{
d = new AttributePrivate;
d->type = QWordType;
d->longLongValue = value;
}
ASF::Attribute::Attribute(unsigned short value)
{
d = new AttributePrivate;
d->type = WordType;
d->shortValue = value;
}
ASF::Attribute::Attribute(bool value)
{
d = new AttributePrivate;
d->type = BoolType;
d->boolValue = value;
}
ASF::Attribute::AttributeTypes ASF::Attribute::type() const
{
return d->type;
}
String ASF::Attribute::toString() const
{
return d->stringValue;
}
ByteVector ASF::Attribute::toByteVector() const
{
if(d->pictureValue.isValid())
return d->pictureValue.render();
return d->byteVectorValue;
}
unsigned short ASF::Attribute::toBool() const
{
return d->shortValue;
}
unsigned short ASF::Attribute::toUShort() const
{
return d->shortValue;
}
unsigned int ASF::Attribute::toUInt() const
{
return d->intValue;
}
unsigned long long ASF::Attribute::toULongLong() const
{
return d->longLongValue;
}
ASF::Picture ASF::Attribute::toPicture() const
{
return d->pictureValue;
}
String ASF::Attribute::parse(ASF::File &f, int kind)
{
uint size, nameLength;
String name;
d->pictureValue = Picture::fromInvalid();
// extended content descriptor
if(kind == 0) {
nameLength = f.readWORD();
name = f.readString(nameLength);
d->type = ASF::Attribute::AttributeTypes(f.readWORD());
size = f.readWORD();
}
// metadata & metadata library
else {
int temp = f.readWORD();
// metadata library
if(kind == 2) {
d->language = temp;
}
d->stream = f.readWORD();
nameLength = f.readWORD();
d->type = ASF::Attribute::AttributeTypes(f.readWORD());
size = f.readDWORD();
name = f.readString(nameLength);
}
if(kind != 2 && size > 65535) {
debug("ASF::Attribute::parse() -- Value larger than 64kB");
}
switch(d->type) {
case WordType:
d->shortValue = f.readWORD();
break;
case BoolType:
if(kind == 0) {
d->boolValue = f.readDWORD() == 1;
}
else {
d->boolValue = f.readWORD() == 1;
}
break;
case DWordType:
d->intValue = f.readDWORD();
break;
case QWordType:
d->longLongValue = f.readQWORD();
break;
case UnicodeType:
d->stringValue = f.readString(size);
break;
case BytesType:
case GuidType:
d->byteVectorValue = f.readBlock(size);
break;
}
if(d->type == BytesType && name == "WM/Picture") {
d->pictureValue.parse(d->byteVectorValue);
if(d->pictureValue.isValid()) {
d->byteVectorValue.clear();
}
}
return name;
}
int ASF::Attribute::dataSize() const
{
switch (d->type) {
case WordType:
return 2;
case BoolType:
return 4;
case DWordType:
return 4;
case QWordType:
return 5;
case UnicodeType:
return d->stringValue.size() * 2 + 2;
case BytesType:
if(d->pictureValue.isValid())
return d->pictureValue.dataSize();
case GuidType:
return d->byteVectorValue.size();
}
return 0;
}
ByteVector ASF::Attribute::render(const String &name, int kind) const
{
ByteVector data;
switch (d->type) {
case WordType:
data.append(ByteVector::fromShort(d->shortValue, false));
break;
case BoolType:
if(kind == 0) {
data.append(ByteVector::fromUInt(d->boolValue ? 1 : 0, false));
}
else {
data.append(ByteVector::fromShort(d->boolValue ? 1 : 0, false));
}
break;
case DWordType:
data.append(ByteVector::fromUInt(d->intValue, false));
break;
case QWordType:
data.append(ByteVector::fromLongLong(d->longLongValue, false));
break;
case UnicodeType:
data.append(File::renderString(d->stringValue));
break;
case BytesType:
if(d->pictureValue.isValid()) {
data.append(d->pictureValue.render());
break;
}
case GuidType:
data.append(d->byteVectorValue);
break;
}
if(kind == 0) {
data = File::renderString(name, true) +
ByteVector::fromShort((int)d->type, false) +
ByteVector::fromShort(data.size(), false) +
data;
}
else {
ByteVector nameData = File::renderString(name);
data = ByteVector::fromShort(kind == 2 ? d->language : 0, false) +
ByteVector::fromShort(d->stream, false) +
ByteVector::fromShort(nameData.size(), false) +
ByteVector::fromShort((int)d->type, false) +
ByteVector::fromUInt(data.size(), false) +
nameData +
data;
}
return data;
}
int ASF::Attribute::language() const
{
return d->language;
}
void ASF::Attribute::setLanguage(int value)
{
d->language = value;
}
int ASF::Attribute::stream() const
{
return d->stream;
}
void ASF::Attribute::setStream(int value)
{
d->stream = value;
}

203
taglib/asf/asfattribute.h Normal file
View File

@@ -0,0 +1,203 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_ASFATTRIBUTE_H
#define TAGLIB_ASFATTRIBUTE_H
#include "tstring.h"
#include "tbytevector.h"
#include "taglib_export.h"
#include "asfpicture.h"
namespace TagLib
{
namespace ASF
{
class File;
class Picture;
class TAGLIB_EXPORT Attribute
{
public:
/*!
* Enum of types an Attribute can have.
*/
enum AttributeTypes {
UnicodeType = 0,
BytesType = 1,
BoolType = 2,
DWordType = 3,
QWordType = 4,
WordType = 5,
GuidType = 6
};
/*!
* Constructs an empty attribute.
*/
Attribute();
/*!
* Constructs an attribute with \a key and a UnicodeType \a value.
*/
Attribute(const String &value);
/*!
* Constructs an attribute with \a key and a BytesType \a value.
*/
Attribute(const ByteVector &value);
/*!
* Constructs an attribute with \a key and a Picture \a value.
*
* This attribute is compatible with the ID3 frame, APIC. The ID3 specification for the APIC frame stipulates that,
* while there may be any number of APIC frames associated with a file,
* only one may be of type 1 and only one may be of type 2.
*
* The specification also states that the description of the picture can be no longer than 64 characters, but can be empty.
* WM/Picture attributes added with TagLib::ASF are not automatically validated to conform to ID3 specifications.
* You must add code in your application to perform validations if you want to maintain complete compatibility with ID3.
*/
Attribute(const Picture &value);
/*!
* Constructs an attribute with \a key and a DWordType \a value.
*/
Attribute(unsigned int value);
/*!
* Constructs an attribute with \a key and a QWordType \a value.
*/
Attribute(unsigned long long value);
/*!
* Constructs an attribute with \a key and a WordType \a value.
*/
Attribute(unsigned short value);
/*!
* Constructs an attribute with \a key and a BoolType \a value.
*/
Attribute(bool value);
/*!
* Construct an attribute as a copy of \a other.
*/
Attribute(const Attribute &item);
/*!
* Copies the contents of \a other into this item.
*/
ASF::Attribute &operator=(const Attribute &other);
/*!
* Destroys the attribute.
*/
virtual ~Attribute();
/*!
* Returns type of the value.
*/
AttributeTypes type() const;
/*!
* Returns the BoolType \a value.
*/
unsigned short toBool() const;
/*!
* Returns the WordType \a value.
*/
unsigned short toUShort() const;
/*!
* Returns the DWordType \a value.
*/
unsigned int toUInt() const;
/*!
* Returns the QWordType \a value.
*/
unsigned long long toULongLong() const;
/*!
* Returns the UnicodeType \a value.
*/
String toString() const;
/*!
* Returns the BytesType \a value.
*/
ByteVector toByteVector() const;
/*!
* Returns the Picture \a value.
*/
Picture toPicture() const;
/*!
* Returns the language number, or 0 is no stream number was set.
*/
int language() const;
/*!
* Sets the language number.
*/
void setLanguage(int value);
/*!
* Returns the stream number, or 0 is no stream number was set.
*/
int stream() const;
/*!
* Sets the stream number.
*/
void setStream(int value);
#ifndef DO_NOT_DOCUMENT
/* THIS IS PRIVATE, DON'T TOUCH IT! */
String parse(ASF::File &file, int kind = 0);
#endif
//! Returns the size of the stored data
int dataSize() const;
private:
friend class File;
ByteVector render(const String &name, int kind = 0) const;
class AttributePrivate;
AttributePrivate *d;
};
}
}
#endif

615
taglib/asf/asffile.cpp Normal file
View File

@@ -0,0 +1,615 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tdebug.h>
#include <tbytevectorlist.h>
#include <tstring.h>
#include "asffile.h"
#include "asftag.h"
#include "asfproperties.h"
using namespace TagLib;
class ASF::File::FilePrivate
{
public:
FilePrivate():
size(0),
tag(0),
properties(0),
contentDescriptionObject(0),
extendedContentDescriptionObject(0),
headerExtensionObject(0),
metadataObject(0),
metadataLibraryObject(0) {}
unsigned long long size;
ASF::Tag *tag;
ASF::Properties *properties;
List<ASF::File::BaseObject *> objects;
ASF::File::ContentDescriptionObject *contentDescriptionObject;
ASF::File::ExtendedContentDescriptionObject *extendedContentDescriptionObject;
ASF::File::HeaderExtensionObject *headerExtensionObject;
ASF::File::MetadataObject *metadataObject;
ASF::File::MetadataLibraryObject *metadataLibraryObject;
};
static ByteVector headerGuid("\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
static ByteVector filePropertiesGuid("\xA1\xDC\xAB\x8C\x47\xA9\xCF\x11\x8E\xE4\x00\xC0\x0C\x20\x53\x65", 16);
static ByteVector streamPropertiesGuid("\x91\x07\xDC\xB7\xB7\xA9\xCF\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65", 16);
static ByteVector contentDescriptionGuid("\x33\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C", 16);
static ByteVector extendedContentDescriptionGuid("\x40\xA4\xD0\xD2\x07\xE3\xD2\x11\x97\xF0\x00\xA0\xC9\x5E\xA8\x50", 16);
static ByteVector headerExtensionGuid("\xb5\x03\xbf_.\xa9\xcf\x11\x8e\xe3\x00\xc0\x0c Se", 16);
static ByteVector metadataGuid("\xEA\xCB\xF8\xC5\xAF[wH\204g\xAA\214D\xFAL\xCA", 16);
static ByteVector metadataLibraryGuid("\224\034#D\230\224\321I\241A\x1d\x13NEpT", 16);
static ByteVector contentEncryptionGuid("\xFB\xB3\x11\x22\x23\xBD\xD2\x11\xB4\xB7\x00\xA0\xC9\x55\xFC\x6E", 16);
static ByteVector extendedContentEncryptionGuid("\x14\xE6\x8A\x29\x22\x26 \x17\x4C\xB9\x35\xDA\xE0\x7E\xE9\x28\x9C", 16);
static ByteVector advancedContentEncryptionGuid("\xB6\x9B\x07\x7A\xA4\xDA\x12\x4E\xA5\xCA\x91\xD3\x8D\xC1\x1A\x8D", 16);
class ASF::File::BaseObject
{
public:
ByteVector data;
virtual ~BaseObject() {}
virtual ByteVector guid() = 0;
virtual void parse(ASF::File *file, unsigned int size);
virtual ByteVector render(ASF::File *file);
};
class ASF::File::UnknownObject : public ASF::File::BaseObject
{
ByteVector myGuid;
public:
UnknownObject(const ByteVector &guid);
ByteVector guid();
};
class ASF::File::FilePropertiesObject : public ASF::File::BaseObject
{
public:
ByteVector guid();
void parse(ASF::File *file, uint size);
};
class ASF::File::StreamPropertiesObject : public ASF::File::BaseObject
{
public:
ByteVector guid();
void parse(ASF::File *file, uint size);
};
class ASF::File::ContentDescriptionObject : public ASF::File::BaseObject
{
public:
ByteVector guid();
void parse(ASF::File *file, uint size);
ByteVector render(ASF::File *file);
};
class ASF::File::ExtendedContentDescriptionObject : public ASF::File::BaseObject
{
public:
ByteVectorList attributeData;
ByteVector guid();
void parse(ASF::File *file, uint size);
ByteVector render(ASF::File *file);
};
class ASF::File::MetadataObject : public ASF::File::BaseObject
{
public:
ByteVectorList attributeData;
ByteVector guid();
void parse(ASF::File *file, uint size);
ByteVector render(ASF::File *file);
};
class ASF::File::MetadataLibraryObject : public ASF::File::BaseObject
{
public:
ByteVectorList attributeData;
ByteVector guid();
void parse(ASF::File *file, uint size);
ByteVector render(ASF::File *file);
};
class ASF::File::HeaderExtensionObject : public ASF::File::BaseObject
{
public:
List<ASF::File::BaseObject *> objects;
~HeaderExtensionObject();
ByteVector guid();
void parse(ASF::File *file, uint size);
ByteVector render(ASF::File *file);
};
ASF::File::HeaderExtensionObject::~HeaderExtensionObject()
{
for(unsigned int i = 0; i < objects.size(); i++) {
delete objects[i];
}
}
void ASF::File::BaseObject::parse(ASF::File *file, unsigned int size)
{
data.clear();
if (size > 24 && size <= (unsigned int)(file->length()))
data = file->readBlock(size - 24);
else
data = ByteVector::null;
}
ByteVector ASF::File::BaseObject::render(ASF::File * /*file*/)
{
return guid() + ByteVector::fromLongLong(data.size() + 24, false) + data;
}
ASF::File::UnknownObject::UnknownObject(const ByteVector &guid) : myGuid(guid)
{
}
ByteVector ASF::File::UnknownObject::guid()
{
return myGuid;
}
ByteVector ASF::File::FilePropertiesObject::guid()
{
return filePropertiesGuid;
}
void ASF::File::FilePropertiesObject::parse(ASF::File *file, uint size)
{
BaseObject::parse(file, size);
file->d->properties->setLength((int)(data.mid(40, 8).toLongLong(false) / 10000000L - data.mid(56, 8).toLongLong(false) / 1000L));
}
ByteVector ASF::File::StreamPropertiesObject::guid()
{
return streamPropertiesGuid;
}
void ASF::File::StreamPropertiesObject::parse(ASF::File *file, uint size)
{
BaseObject::parse(file, size);
file->d->properties->setChannels(data.mid(56, 2).toShort(false));
file->d->properties->setSampleRate(data.mid(58, 4).toUInt(false));
file->d->properties->setBitrate(data.mid(62, 4).toUInt(false) * 8 / 1000);
}
ByteVector ASF::File::ContentDescriptionObject::guid()
{
return contentDescriptionGuid;
}
void ASF::File::ContentDescriptionObject::parse(ASF::File *file, uint /*size*/)
{
file->d->contentDescriptionObject = this;
int titleLength = file->readWORD();
int artistLength = file->readWORD();
int copyrightLength = file->readWORD();
int commentLength = file->readWORD();
int ratingLength = file->readWORD();
file->d->tag->setTitle(file->readString(titleLength));
file->d->tag->setArtist(file->readString(artistLength));
file->d->tag->setCopyright(file->readString(copyrightLength));
file->d->tag->setComment(file->readString(commentLength));
file->d->tag->setRating(file->readString(ratingLength));
}
ByteVector ASF::File::ContentDescriptionObject::render(ASF::File *file)
{
ByteVector v1 = file->renderString(file->d->tag->title());
ByteVector v2 = file->renderString(file->d->tag->artist());
ByteVector v3 = file->renderString(file->d->tag->copyright());
ByteVector v4 = file->renderString(file->d->tag->comment());
ByteVector v5 = file->renderString(file->d->tag->rating());
data.clear();
data.append(ByteVector::fromShort(v1.size(), false));
data.append(ByteVector::fromShort(v2.size(), false));
data.append(ByteVector::fromShort(v3.size(), false));
data.append(ByteVector::fromShort(v4.size(), false));
data.append(ByteVector::fromShort(v5.size(), false));
data.append(v1);
data.append(v2);
data.append(v3);
data.append(v4);
data.append(v5);
return BaseObject::render(file);
}
ByteVector ASF::File::ExtendedContentDescriptionObject::guid()
{
return extendedContentDescriptionGuid;
}
void ASF::File::ExtendedContentDescriptionObject::parse(ASF::File *file, uint /*size*/)
{
file->d->extendedContentDescriptionObject = this;
int count = file->readWORD();
while(count--) {
ASF::Attribute attribute;
String name = attribute.parse(*file);
file->d->tag->addAttribute(name, attribute);
}
}
ByteVector ASF::File::ExtendedContentDescriptionObject::render(ASF::File *file)
{
data.clear();
data.append(ByteVector::fromShort(attributeData.size(), false));
data.append(attributeData.toByteVector(ByteVector::null));
return BaseObject::render(file);
}
ByteVector ASF::File::MetadataObject::guid()
{
return metadataGuid;
}
void ASF::File::MetadataObject::parse(ASF::File *file, uint /*size*/)
{
file->d->metadataObject = this;
int count = file->readWORD();
while(count--) {
ASF::Attribute attribute;
String name = attribute.parse(*file, 1);
file->d->tag->addAttribute(name, attribute);
}
}
ByteVector ASF::File::MetadataObject::render(ASF::File *file)
{
data.clear();
data.append(ByteVector::fromShort(attributeData.size(), false));
data.append(attributeData.toByteVector(ByteVector::null));
return BaseObject::render(file);
}
ByteVector ASF::File::MetadataLibraryObject::guid()
{
return metadataLibraryGuid;
}
void ASF::File::MetadataLibraryObject::parse(ASF::File *file, uint /*size*/)
{
file->d->metadataLibraryObject = this;
int count = file->readWORD();
while(count--) {
ASF::Attribute attribute;
String name = attribute.parse(*file, 2);
file->d->tag->addAttribute(name, attribute);
}
}
ByteVector ASF::File::MetadataLibraryObject::render(ASF::File *file)
{
data.clear();
data.append(ByteVector::fromShort(attributeData.size(), false));
data.append(attributeData.toByteVector(ByteVector::null));
return BaseObject::render(file);
}
ByteVector ASF::File::HeaderExtensionObject::guid()
{
return headerExtensionGuid;
}
void ASF::File::HeaderExtensionObject::parse(ASF::File *file, uint /*size*/)
{
file->d->headerExtensionObject = this;
file->seek(18, File::Current);
long long dataSize = file->readDWORD();
long long dataPos = 0;
while(dataPos < dataSize) {
ByteVector guid = file->readBlock(16);
if(guid.size() != 16) {
file->setValid(false);
break;
}
bool ok;
long long size = file->readQWORD(&ok);
if(!ok) {
file->setValid(false);
break;
}
BaseObject *obj;
if(guid == metadataGuid) {
obj = new MetadataObject();
}
else if(guid == metadataLibraryGuid) {
obj = new MetadataLibraryObject();
}
else {
obj = new UnknownObject(guid);
}
obj->parse(file, (unsigned int)size);
objects.append(obj);
dataPos += size;
}
}
ByteVector ASF::File::HeaderExtensionObject::render(ASF::File *file)
{
data.clear();
for(unsigned int i = 0; i < objects.size(); i++) {
data.append(objects[i]->render(file));
}
data = ByteVector("\x11\xD2\xD3\xAB\xBA\xA9\xcf\x11\x8E\xE6\x00\xC0\x0C\x20\x53\x65\x06\x00", 18) + ByteVector::fromUInt(data.size(), false) + data;
return BaseObject::render(file);
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
ASF::File::File(FileName file, bool readProperties, Properties::ReadStyle propertiesStyle)
: TagLib::File(file)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
ASF::File::File(IOStream *stream, bool readProperties, Properties::ReadStyle propertiesStyle)
: TagLib::File(stream)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
ASF::File::~File()
{
for(unsigned int i = 0; i < d->objects.size(); i++) {
delete d->objects[i];
}
if(d->tag) {
delete d->tag;
}
if(d->properties) {
delete d->properties;
}
delete d;
}
ASF::Tag *ASF::File::tag() const
{
return d->tag;
}
ASF::Properties *ASF::File::audioProperties() const
{
return d->properties;
}
void ASF::File::read(bool /*readProperties*/, Properties::ReadStyle /*propertiesStyle*/)
{
if(!isValid())
return;
ByteVector guid = readBlock(16);
if(guid != headerGuid) {
debug("ASF: Not an ASF file.");
setValid(false);
return;
}
d->tag = new ASF::Tag();
d->properties = new ASF::Properties();
bool ok;
d->size = readQWORD(&ok);
if(!ok) {
setValid(false);
return;
}
int numObjects = readDWORD(&ok);
if(!ok) {
setValid(false);
return;
}
seek(2, Current);
for(int i = 0; i < numObjects; i++) {
ByteVector guid = readBlock(16);
if(guid.size() != 16) {
setValid(false);
break;
}
long size = (long)readQWORD(&ok);
if(!ok) {
setValid(false);
break;
}
BaseObject *obj;
if(guid == filePropertiesGuid) {
obj = new FilePropertiesObject();
}
else if(guid == streamPropertiesGuid) {
obj = new StreamPropertiesObject();
}
else if(guid == contentDescriptionGuid) {
obj = new ContentDescriptionObject();
}
else if(guid == extendedContentDescriptionGuid) {
obj = new ExtendedContentDescriptionObject();
}
else if(guid == headerExtensionGuid) {
obj = new HeaderExtensionObject();
}
else {
if(guid == contentEncryptionGuid ||
guid == extendedContentEncryptionGuid ||
guid == advancedContentEncryptionGuid) {
d->properties->setEncrypted(true);
}
obj = new UnknownObject(guid);
}
obj->parse(this, size);
d->objects.append(obj);
}
}
bool ASF::File::save()
{
if(readOnly()) {
debug("ASF::File::save() -- File is read only.");
return false;
}
if(!isValid()) {
debug("ASF::File::save() -- Trying to save invalid file.");
return false;
}
if(!d->contentDescriptionObject) {
d->contentDescriptionObject = new ContentDescriptionObject();
d->objects.append(d->contentDescriptionObject);
}
if(!d->extendedContentDescriptionObject) {
d->extendedContentDescriptionObject = new ExtendedContentDescriptionObject();
d->objects.append(d->extendedContentDescriptionObject);
}
if(!d->headerExtensionObject) {
d->headerExtensionObject = new HeaderExtensionObject();
d->objects.append(d->headerExtensionObject);
}
if(!d->metadataObject) {
d->metadataObject = new MetadataObject();
d->headerExtensionObject->objects.append(d->metadataObject);
}
if(!d->metadataLibraryObject) {
d->metadataLibraryObject = new MetadataLibraryObject();
d->headerExtensionObject->objects.append(d->metadataLibraryObject);
}
ASF::AttributeListMap::ConstIterator it = d->tag->attributeListMap().begin();
for(; it != d->tag->attributeListMap().end(); it++) {
const String &name = it->first;
const AttributeList &attributes = it->second;
bool inExtendedContentDescriptionObject = false;
bool inMetadataObject = false;
for(unsigned int j = 0; j < attributes.size(); j++) {
const Attribute &attribute = attributes[j];
bool largeValue = attribute.dataSize() > 65535;
if(!inExtendedContentDescriptionObject && !largeValue && attribute.language() == 0 && attribute.stream() == 0) {
d->extendedContentDescriptionObject->attributeData.append(attribute.render(name));
inExtendedContentDescriptionObject = true;
}
else if(!inMetadataObject && !largeValue && attribute.language() == 0 && attribute.stream() != 0) {
d->metadataObject->attributeData.append(attribute.render(name, 1));
inMetadataObject = true;
}
else {
d->metadataLibraryObject->attributeData.append(attribute.render(name, 2));
}
}
}
ByteVector data;
for(unsigned int i = 0; i < d->objects.size(); i++) {
data.append(d->objects[i]->render(this));
}
data = headerGuid + ByteVector::fromLongLong(data.size() + 30, false) + ByteVector::fromUInt(d->objects.size(), false) + ByteVector("\x01\x02", 2) + data;
insert(data, 0, (TagLib::ulong)d->size);
return true;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
int ASF::File::readBYTE(bool *ok)
{
ByteVector v = readBlock(1);
if(v.size() != 1) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v[0];
}
int ASF::File::readWORD(bool *ok)
{
ByteVector v = readBlock(2);
if(v.size() != 2) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toUShort(false);
}
unsigned int ASF::File::readDWORD(bool *ok)
{
ByteVector v = readBlock(4);
if(v.size() != 4) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toUInt(false);
}
long long ASF::File::readQWORD(bool *ok)
{
ByteVector v = readBlock(8);
if(v.size() != 8) {
if(ok) *ok = false;
return 0;
}
if(ok) *ok = true;
return v.toLongLong(false);
}
String ASF::File::readString(int length)
{
ByteVector data = readBlock(length);
unsigned int size = data.size();
while (size >= 2) {
if(data[size - 1] != '\0' || data[size - 2] != '\0') {
break;
}
size -= 2;
}
if(size != data.size()) {
data.resize(size);
}
return String(data, String::UTF16LE);
}
ByteVector ASF::File::renderString(const String &str, bool includeLength)
{
ByteVector data = str.data(String::UTF16LE) + ByteVector::fromShort(0, false);
if(includeLength) {
data = ByteVector::fromShort(data.size(), false) + data;
}
return data;
}

136
taglib/asf/asffile.h Normal file
View File

@@ -0,0 +1,136 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_ASFFILE_H
#define TAGLIB_ASFFILE_H
#include "tag.h"
#include "tfile.h"
#include "taglib_export.h"
#include "asfproperties.h"
#include "asftag.h"
namespace TagLib {
//! An implementation of ASF (WMA) metadata
namespace ASF {
/*!
* This implements and provides an interface for ASF files to the
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
* the abstract TagLib::File API as well as providing some additional
* information specific to ASF files.
*/
class TAGLIB_EXPORT File : public TagLib::File
{
public:
/*!
* Contructs an ASF file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
File(FileName file, bool readProperties = true, Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Contructs an ASF file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
File(IOStream *stream, bool readProperties = true, Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Destroys this instance of the File.
*/
virtual ~File();
/*!
* Returns a pointer to the ASF tag of the file.
*
* ASF::Tag implements the tag interface, so this serves as the
* reimplementation of TagLib::File::tag().
*
* \note The Tag <b>is still</b> owned by the ASF::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*/
virtual Tag *tag() const;
/*!
* Returns the ASF audio properties for this file.
*/
virtual Properties *audioProperties() const;
/*!
* Save the file.
*
* This returns true if the save was successful.
*/
virtual bool save();
private:
int readBYTE(bool *ok = 0);
int readWORD(bool *ok = 0);
unsigned int readDWORD(bool *ok = 0);
long long readQWORD(bool *ok = 0);
static ByteVector renderString(const String &str, bool includeLength = false);
String readString(int len);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
friend class Attribute;
friend class Picture;
class BaseObject;
class UnknownObject;
class FilePropertiesObject;
class StreamPropertiesObject;
class ContentDescriptionObject;
class ExtendedContentDescriptionObject;
class HeaderExtensionObject;
class MetadataObject;
class MetadataLibraryObject;
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

182
taglib/asf/asfpicture.cpp Normal file
View File

@@ -0,0 +1,182 @@
/**************************************************************************
copyright : (C) 2010 by Anton Sergunov
email : setosha@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <taglib.h>
#include <tdebug.h>
#include "asfattribute.h"
#include "asffile.h"
#include "asfpicture.h"
using namespace TagLib;
class ASF::Picture::PicturePrivate : public RefCounter
{
public:
bool valid;
Type type;
String mimeType;
String description;
ByteVector picture;
};
////////////////////////////////////////////////////////////////////////////////
// Picture class members
////////////////////////////////////////////////////////////////////////////////
ASF::Picture::Picture()
{
d = new PicturePrivate();
d->valid = true;
}
ASF::Picture::Picture(const Picture& other)
: d(other.d)
{
d->ref();
}
ASF::Picture::~Picture()
{
if(d->deref())
delete d;
}
bool ASF::Picture::isValid() const
{
return d->valid;
}
String ASF::Picture::mimeType() const
{
return d->mimeType;
}
void ASF::Picture::setMimeType(const String &value)
{
d->mimeType = value;
}
ASF::Picture::Type ASF::Picture::type() const
{
return d->type;
}
void ASF::Picture::setType(const ASF::Picture::Type& t)
{
d->type = t;
}
String ASF::Picture::description() const
{
return d->description;
}
void ASF::Picture::setDescription(const String &desc)
{
d->description = desc;
}
ByteVector ASF::Picture::picture() const
{
return d->picture;
}
void ASF::Picture::setPicture(const ByteVector &p)
{
d->picture = p;
}
int ASF::Picture::dataSize() const
{
return
9 + (d->mimeType.length() + d->description.length()) * 2 +
d->picture.size();
}
ASF::Picture& ASF::Picture::operator=(const ASF::Picture& other)
{
if(other.d != d) {
if(d->deref())
delete d;
d = other.d;
d->ref();
}
return *this;
}
ByteVector ASF::Picture::render() const
{
if(!isValid())
return ByteVector::null;
return
ByteVector((char)d->type) +
ByteVector::fromUInt(d->picture.size(), false) +
ASF::File::renderString(d->mimeType) +
ASF::File::renderString(d->description) +
d->picture;
}
void ASF::Picture::parse(const ByteVector& bytes)
{
d->valid = false;
if(bytes.size() < 9)
return;
int pos = 0;
d->type = (Type)bytes[0]; ++pos;
uint dataLen = bytes.mid(pos, 4).toUInt(false); pos+=4;
const ByteVector nullStringTerminator(2, 0);
int endPos = bytes.find(nullStringTerminator, pos, 2);
if(endPos < 0)
return;
d->mimeType = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
pos = endPos+2;
endPos = bytes.find(nullStringTerminator, pos, 2);
if(endPos < 0)
return;
d->description = String(bytes.mid(pos, endPos - pos), String::UTF16LE);
pos = endPos+2;
if(dataLen + pos != bytes.size())
return;
d->picture = bytes.mid(pos, dataLen);
d->valid = true;
return;
}
ASF::Picture ASF::Picture::fromInvalid()
{
Picture ret;
ret.d->valid = false;
return ret;
}

217
taglib/asf/asfpicture.h Normal file
View File

@@ -0,0 +1,217 @@
/**************************************************************************
copyright : (C) 2010 by Anton Sergunov
email : setosha@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef ASFPICTURE_H
#define ASFPICTURE_H
#include "tstring.h"
#include "tbytevector.h"
#include "taglib_export.h"
#include "attachedpictureframe.h"
namespace TagLib
{
namespace ASF
{
//! An ASF attached picture interface implementation
/*!
* This is an implementation of ASF attached pictures interface. Pictures may be
* included in attributes, one per WM/Picture attribute (but there may be multiple WM/Picture
* attribute in a single tag). These pictures are usually in either JPEG or
* PNG format.
* \see Attribute::toPicture()
* \see Attribute::Attribute(const Picture& picture)
*/
class TAGLIB_EXPORT Picture {
public:
/*!
* This describes the function or content of the picture.
*/
enum Type {
//! A type not enumerated below
Other = 0x00,
//! 32x32 PNG image that should be used as the file icon
FileIcon = 0x01,
//! File icon of a different size or format
OtherFileIcon = 0x02,
//! Front cover image of the album
FrontCover = 0x03,
//! Back cover image of the album
BackCover = 0x04,
//! Inside leaflet page of the album
LeafletPage = 0x05,
//! Image from the album itself
Media = 0x06,
//! Picture of the lead artist or soloist
LeadArtist = 0x07,
//! Picture of the artist or performer
Artist = 0x08,
//! Picture of the conductor
Conductor = 0x09,
//! Picture of the band or orchestra
Band = 0x0A,
//! Picture of the composer
Composer = 0x0B,
//! Picture of the lyricist or text writer
Lyricist = 0x0C,
//! Picture of the recording location or studio
RecordingLocation = 0x0D,
//! Picture of the artists during recording
DuringRecording = 0x0E,
//! Picture of the artists during performance
DuringPerformance = 0x0F,
//! Picture from a movie or video related to the track
MovieScreenCapture = 0x10,
//! Picture of a large, coloured fish
ColouredFish = 0x11,
//! Illustration related to the track
Illustration = 0x12,
//! Logo of the band or performer
BandLogo = 0x13,
//! Logo of the publisher (record company)
PublisherLogo = 0x14
};
/*!
* Constructs an empty picture.
*/
Picture();
/*!
* Construct an picture as a copy of \a other.
*/
Picture(const Picture& other);
/*!
* Destroys the picture.
*/
virtual ~Picture();
/*!
* Copies the contents of \a other into this picture.
*/
Picture& operator=(const Picture& other);
/*!
* Returns true if Picture stores valid picture
*/
bool isValid() const;
/*!
* Returns the mime type of the image. This should in most cases be
* "image/png" or "image/jpeg".
* \see setMimeType(const String &)
* \see picture()
* \see setPicture(const ByteArray&)
*/
String mimeType() const;
/*!
* Sets the mime type of the image. This should in most cases be
* "image/png" or "image/jpeg".
* \see setMimeType(const String &)
* \see picture()
* \see setPicture(const ByteArray&)
*/
void setMimeType(const String &value);
/*!
* Returns the type of the image.
*
* \see Type
* \see setType()
*/
Type type() const;
/*!
* Sets the type for the image.
*
* \see Type
* \see type()
*/
void setType(const ASF::Picture::Type& t);
/*!
* Returns a text description of the image.
*
* \see setDescription()
*/
String description() const;
/*!
* Sets a textual description of the image to \a desc.
*
* \see description()
*/
void setDescription(const String &desc);
/*!
* Returns the image data as a ByteVector.
*
* \note ByteVector has a data() method that returns a const char * which
* should make it easy to export this data to external programs.
*
* \see setPicture()
* \see mimeType()
*/
ByteVector picture() const;
/*!
* Sets the image data to \a p. \a p should be of the type specified in
* this frame's mime-type specification.
*
* \see picture()
* \see mimeType()
* \see setMimeType()
*/
void setPicture(const ByteVector &p);
/*!
* Returns picture as binary raw data \a value
*/
ByteVector render() const;
/*!
* Returns picture as binary raw data \a value
*/
int dataSize() const;
#ifndef DO_NOT_DOCUMENT
/* THIS IS PRIVATE, DON'T TOUCH IT! */
void parse(const ByteVector& );
static Picture fromInvalid();
friend class Attribute;
#endif
private:
class PicturePrivate;
PicturePrivate *d;
};
}
}
#endif // ASFPICTURE_H

View File

@@ -0,0 +1,115 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tdebug.h>
#include <tstring.h>
#include "asfproperties.h"
using namespace TagLib;
class ASF::Properties::PropertiesPrivate
{
public:
PropertiesPrivate(): length(0), bitrate(0), sampleRate(0), channels(0), encrypted(false) {}
int length;
int bitrate;
int sampleRate;
int channels;
bool encrypted;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
ASF::Properties::Properties() : AudioProperties(AudioProperties::Average)
{
d = new PropertiesPrivate;
}
ASF::Properties::~Properties()
{
if(d)
delete d;
}
int ASF::Properties::length() const
{
return d->length;
}
int ASF::Properties::bitrate() const
{
return d->bitrate;
}
int ASF::Properties::sampleRate() const
{
return d->sampleRate;
}
int ASF::Properties::channels() const
{
return d->channels;
}
bool ASF::Properties::isEncrypted() const
{
return d->encrypted;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void ASF::Properties::setLength(int length)
{
d->length = length;
}
void ASF::Properties::setBitrate(int length)
{
d->bitrate = length;
}
void ASF::Properties::setSampleRate(int length)
{
d->sampleRate = length;
}
void ASF::Properties::setChannels(int length)
{
d->channels = length;
}
void ASF::Properties::setEncrypted(bool encrypted)
{
d->encrypted = encrypted;
}

View File

@@ -0,0 +1,76 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_ASFPROPERTIES_H
#define TAGLIB_ASFPROPERTIES_H
#include "audioproperties.h"
#include "tstring.h"
#include "taglib_export.h"
namespace TagLib {
namespace ASF {
//! An implementation of ASF audio properties
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:
/*!
* Create an instance of ASF::Properties.
*/
Properties();
/*!
* Destroys this ASF::Properties instance.
*/
virtual ~Properties();
// Reimplementations.
virtual int length() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
bool isEncrypted() const;
#ifndef DO_NOT_DOCUMENT
void setLength(int value);
void setBitrate(int value);
void setSampleRate(int value);
void setChannels(int value);
void setEncrypted(bool value);
#endif
private:
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

198
taglib/asf/asftag.cpp Normal file
View File

@@ -0,0 +1,198 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include "asftag.h"
using namespace TagLib;
class ASF::Tag::TagPrivate
{
public:
String title;
String artist;
String copyright;
String comment;
String rating;
AttributeListMap attributeListMap;
};
ASF::Tag::Tag()
: TagLib::Tag()
{
d = new TagPrivate;
}
ASF::Tag::~Tag()
{
if(d)
delete d;
}
String ASF::Tag::title() const
{
return d->title;
}
String ASF::Tag::artist() const
{
return d->artist;
}
String ASF::Tag::album() const
{
if(d->attributeListMap.contains("WM/AlbumTitle"))
return d->attributeListMap["WM/AlbumTitle"][0].toString();
return String::null;
}
String ASF::Tag::copyright() const
{
return d->copyright;
}
String ASF::Tag::comment() const
{
return d->comment;
}
String ASF::Tag::rating() const
{
return d->rating;
}
unsigned int ASF::Tag::year() const
{
if(d->attributeListMap.contains("WM/Year"))
return d->attributeListMap["WM/Year"][0].toString().toInt();
return 0;
}
unsigned int ASF::Tag::track() const
{
if(d->attributeListMap.contains("WM/TrackNumber")) {
const ASF::Attribute attr = d->attributeListMap["WM/TrackNumber"][0];
if(attr.type() == ASF::Attribute::DWordType)
return attr.toUInt();
else
return attr.toString().toInt();
}
if(d->attributeListMap.contains("WM/Track"))
return d->attributeListMap["WM/Track"][0].toUInt();
return 0;
}
String ASF::Tag::genre() const
{
if(d->attributeListMap.contains("WM/Genre"))
return d->attributeListMap["WM/Genre"][0].toString();
return String::null;
}
void ASF::Tag::setTitle(const String &value)
{
d->title = value;
}
void ASF::Tag::setArtist(const String &value)
{
d->artist = value;
}
void ASF::Tag::setCopyright(const String &value)
{
d->copyright = value;
}
void ASF::Tag::setComment(const String &value)
{
d->comment = value;
}
void ASF::Tag::setRating(const String &value)
{
d->rating = value;
}
void ASF::Tag::setAlbum(const String &value)
{
setAttribute("WM/AlbumTitle", value);
}
void ASF::Tag::setGenre(const String &value)
{
setAttribute("WM/Genre", value);
}
void ASF::Tag::setYear(uint value)
{
setAttribute("WM/Year", String::number(value));
}
void ASF::Tag::setTrack(uint value)
{
setAttribute("WM/TrackNumber", String::number(value));
}
ASF::AttributeListMap& ASF::Tag::attributeListMap()
{
return d->attributeListMap;
}
void ASF::Tag::removeItem(const String &key)
{
AttributeListMap::Iterator it = d->attributeListMap.find(key);
if(it != d->attributeListMap.end())
d->attributeListMap.erase(it);
}
void ASF::Tag::setAttribute(const String &name, const Attribute &attribute)
{
AttributeList value;
value.append(attribute);
d->attributeListMap.insert(name, value);
}
void ASF::Tag::addAttribute(const String &name, const Attribute &attribute)
{
if(d->attributeListMap.contains(name)) {
d->attributeListMap[name].append(attribute);
}
else {
setAttribute(name, attribute);
}
}
bool ASF::Tag::isEmpty() const
{
return TagLib::Tag::isEmpty() &&
copyright().isEmpty() &&
rating().isEmpty() &&
d->attributeListMap.isEmpty();
}

186
taglib/asf/asftag.h Normal file
View File

@@ -0,0 +1,186 @@
/**************************************************************************
copyright : (C) 2005-2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_ASFTAG_H
#define TAGLIB_ASFTAG_H
#include "tag.h"
#include "tlist.h"
#include "tmap.h"
#include "taglib_export.h"
#include "asfattribute.h"
namespace TagLib {
namespace ASF {
typedef List<Attribute> AttributeList;
typedef Map<String, AttributeList> AttributeListMap;
class TAGLIB_EXPORT Tag : public TagLib::Tag {
friend class File;
public:
Tag();
virtual ~Tag();
/*!
* Returns the track name.
*/
virtual String title() const;
/*!
* Returns the artist name.
*/
virtual String artist() const;
/*!
* Returns the album name; if no album name is present in the tag
* String::null will be returned.
*/
virtual String album() const;
/*!
* Returns the track comment.
*/
virtual String comment() const;
/*!
* Returns the genre name; if no genre is present in the tag String::null
* will be returned.
*/
virtual String genre() const;
/*!
* Returns the rating.
*/
virtual String rating() const;
/*!
* Returns the genre name; if no genre is present in the tag String::null
* will be returned.
*/
virtual String copyright() const;
/*!
* Returns the year; if there is no year set, this will return 0.
*/
virtual uint year() const;
/*!
* Returns the track number; if there is no track number set, this will
* return 0.
*/
virtual uint track() const;
/*!
* Sets the title to \a s.
*/
virtual void setTitle(const String &s);
/*!
* Sets the artist to \a s.
*/
virtual void setArtist(const String &s);
/*!
* Sets the album to \a s. If \a s is String::null then this value will be
* cleared.
*/
virtual void setAlbum(const String &s);
/*!
* Sets the comment to \a s.
*/
virtual void setComment(const String &s);
/*!
* Sets the rating to \a s.
*/
virtual void setRating(const String &s);
/*!
* Sets the copyright to \a s.
*/
virtual void setCopyright(const String &s);
/*!
* Sets the genre to \a s.
*/
virtual void setGenre(const String &s);
/*!
* Sets the year to \a i. If \a s is 0 then this value will be cleared.
*/
virtual void setYear(uint i);
/*!
* Sets the track to \a i. If \a s is 0 then this value will be cleared.
*/
virtual void setTrack(uint i);
/*!
* Returns true if the tag does not contain any data. This should be
* reimplemented in subclasses that provide more than the basic tagging
* abilities in this class.
*/
virtual bool isEmpty() const;
/*!
* Returns a reference to the item list map. This is an AttributeListMap of
* all of the items in the tag.
*
* This is the most powerfull structure for accessing the items of the tag.
*/
AttributeListMap &attributeListMap();
/*!
* Removes the \a key attribute from the tag
*/
void removeItem(const String &name);
/*!
* Sets the \a key attribute to the value of \a attribute. If an attribute
* with the \a key is already present, it will be replaced.
*/
void setAttribute(const String &name, const Attribute &attribute);
/*!
* Sets the \a key attribute to the value of \a attribute. If an attribute
* with the \a key is already present, it will be added to the list.
*/
void addAttribute(const String &name, const Attribute &attribute);
private:
class TagPrivate;
TagPrivate *d;
};
}
}
#endif

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *

View File

@@ -1,6 +1,10 @@
/***************************************************************************
copyright : (C) 2002 - 2008 by Scott Wheeler
email : wheeler@kde.org
copyright : (C) 2010 by Alex Novichkov
email : novichko@atnet.ru
(added APE file support)
***************************************************************************/
/***************************************************************************
@@ -15,26 +19,40 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tfile.h>
#include <tstring.h>
#include <tdebug.h>
#include "fileref.h"
#include "asffile.h"
#include "mpegfile.h"
#include "vorbisfile.h"
#include "flacfile.h"
#include "oggflacfile.h"
#include "mpcfile.h"
#include "mp4file.h"
#include "wavpackfile.h"
#include "speexfile.h"
#include "trueaudiofile.h"
#include "aifffile.h"
#include "wavfile.h"
#include "apefile.h"
#include "modfile.h"
#include "s3mfile.h"
#include "itfile.h"
#include "xmfile.h"
using namespace TagLib;
@@ -58,7 +76,7 @@ List<const FileRef::FileTypeResolver *> FileRef::FileRefPrivate::fileTypeResolve
FileRef::FileRef()
{
d = new FileRefPrivate(0);
d = new FileRefPrivate(0);
}
FileRef::FileRef(FileName fileName, bool readAudioProperties,
@@ -85,11 +103,19 @@ FileRef::~FileRef()
Tag *FileRef::tag() const
{
if(isNull()) {
debug("FileRef::tag() - Called without a valid file.");
return 0;
}
return d->file->tag();
}
AudioProperties *FileRef::audioProperties() const
{
if(isNull()) {
debug("FileRef::audioProperties() - Called without a valid file.");
return 0;
}
return d->file->audioProperties();
}
@@ -100,6 +126,10 @@ File *FileRef::file() const
bool FileRef::save()
{
if(isNull()) {
debug("FileRef::save() - Called without a valid file.");
return false;
}
return d->file->save();
}
@@ -121,6 +151,25 @@ StringList FileRef::defaultFileExtensions()
l.append("wv");
l.append("spx");
l.append("tta");
l.append("m4a");
l.append("m4r");
l.append("m4b");
l.append("m4p");
l.append("3g2");
l.append("mp4");
l.append("wma");
l.append("asf");
l.append("aif");
l.append("aiff");
l.append("wav");
l.append("ape");
l.append("mod");
l.append("module"); // alias for "mod"
l.append("nst"); // alias for "mod"
l.append("wow"); // alias for "mod"
l.append("s3m");
l.append("it");
l.append("xm");
return l;
}
@@ -180,23 +229,50 @@ File *FileRef::create(FileName fileName, bool readAudioProperties,
// updated. However at some point that list should be created at the same time
// that a default file type resolver is created.
if(s.size() > 4) {
if(s.substr(s.size() - 4, 4).upper() == ".OGG")
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".MP3")
int pos = s.rfind(".");
if(pos != -1) {
String ext = s.substr(pos + 1).upper();
if(ext == "MP3")
return new MPEG::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".OGA")
return new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 5, 5).upper() == ".FLAC")
if(ext == "OGG")
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "OGA") {
/* .oga can be any audio in the Ogg container. First try FLAC, then Vorbis. */
File *file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if (file->isValid())
return file;
delete file;
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
}
if(ext == "FLAC")
return new FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".MPC")
if(ext == "MPC")
return new MPC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 3, 3).upper() == ".WV")
if(ext == "WV")
return new WavPack::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".SPX")
if(ext == "SPX")
return new Ogg::Speex::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".TTA")
if(ext == "TTA")
return new TrueAudio::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "M4A" || ext == "M4R" || ext == "M4B" || ext == "M4P" || ext == "MP4" || ext == "3G2")
return new MP4::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "WMA" || ext == "ASF")
return new ASF::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "AIF" || ext == "AIFF")
return new RIFF::AIFF::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "WAV")
return new RIFF::WAV::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "APE")
return new APE::File(fileName, readAudioProperties, audioPropertiesStyle);
// module, nst and wow are possible but uncommon extensions
if(ext == "MOD" || ext == "MODULE" || ext == "NST" || ext == "WOW")
return new Mod::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "S3M")
return new S3M::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "IT")
return new IT::File(fileName, readAudioProperties, audioPropertiesStyle);
if(ext == "XM")
return new XM::File(fileName, readAudioProperties, audioPropertiesStyle);
}
return 0;

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -26,8 +26,8 @@
#ifndef TAGLIB_FILEREF_H
#define TAGLIB_FILEREF_H
#include <tfile.h>
#include <tstringlist.h>
#include "tfile.h"
#include "tstringlist.h"
#include "taglib_export.h"
#include "audioproperties.h"
@@ -91,10 +91,8 @@ namespace TagLib {
class TAGLIB_EXPORT FileTypeResolver
{
TAGLIB_IGNORE_MISSING_DESTRUCTOR
public:
// do not fix compiler warning about missing virtual destructor
// since this would not be binary compatible
// let Scott fix it whenever he thinks BIC changes can next be applied
/*!
* This method must be overridden to provide an additional file type
* resolver. If the resolver is able to determine the file type it should
@@ -151,6 +149,9 @@ namespace TagLib {
* \warning This pointer will become invalid when this FileRef and all
* copies pass out of scope.
*
* \warning Do not cast it to any subclasses of \class Tag.
* Use tag returning methods of appropriate subclasses of \class File instead.
*
* \see File::tag()
*/
Tag *tag() const;

View File

@@ -1 +0,0 @@
INSTALL( FILES flacfile.h flacproperties.h DESTINATION ${INCLUDE_INSTALL_DIR}/taglib )

View File

@@ -1,14 +0,0 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
$(all_includes)
noinst_LTLIBRARIES = libflac.la
libflac_la_SOURCES = flacfile.cpp flacproperties.cpp
taglib_include_HEADERS = flacfile.h flacproperties.h
taglib_includedir = $(includedir)/taglib

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -28,20 +28,25 @@
#include <tlist.h>
#include <tdebug.h>
#include <tagunion.h>
#include <tpropertymap.h>
#include <id3v2header.h>
#include <id3v2tag.h>
#include <id3v1tag.h>
#include <xiphcomment.h>
#include "flacpicture.h"
#include "flacfile.h"
#include "flacmetadatablock.h"
#include "flacunknownmetadatablock.h"
using namespace TagLib;
namespace
{
enum { XiphIndex = 0, ID3v2Index = 1, ID3v1Index = 2 };
enum { StreamInfo = 0, Padding, Application, SeekTable, VorbisComment, CueSheet };
enum { FlacXiphIndex = 0, FlacID3v2Index = 1, FlacID3v1Index = 2 };
enum { MinPaddingLength = 4096 };
enum { LastBlockFlag = 0x80 };
}
class FLAC::File::FilePrivate
@@ -59,10 +64,15 @@ public:
scanned(false),
hasXiphComment(false),
hasID3v2(false),
hasID3v1(false) {}
hasID3v1(false)
{
}
~FilePrivate()
{
for(uint i = 0; i < blocks.size(); i++) {
delete blocks[i];
}
delete properties;
}
@@ -77,6 +87,7 @@ public:
Properties *properties;
ByteVector streamInfoData;
ByteVector xiphCommentData;
List<MetadataBlock *> blocks;
long flacStart;
long streamStart;
@@ -109,6 +120,15 @@ FLAC::File::File(FileName file, ID3v2::FrameFactory *frameFactory,
read(readProperties, propertiesStyle);
}
FLAC::File::File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
bool readProperties, Properties::ReadStyle propertiesStyle) :
TagLib::File(stream)
{
d = new FilePrivate;
d->ID3v2FrameFactory = frameFactory;
read(readProperties, propertiesStyle);
}
FLAC::File::~File()
{
delete d;
@@ -119,6 +139,41 @@ TagLib::Tag *FLAC::File::tag() const
return &d->tag;
}
PropertyMap FLAC::File::properties() const
{
// once Tag::properties() is virtual, this case distinction could actually be done
// within TagUnion.
if(d->hasXiphComment)
return d->tag.access<Ogg::XiphComment>(FlacXiphIndex, false)->properties();
if(d->hasID3v2)
return d->tag.access<ID3v2::Tag>(FlacID3v2Index, false)->properties();
if(d->hasID3v1)
return d->tag.access<ID3v1::Tag>(FlacID3v1Index, false)->properties();
return PropertyMap();
}
void FLAC::File::removeUnsupportedProperties(const StringList &unsupported)
{
if(d->hasXiphComment)
d->tag.access<Ogg::XiphComment>(FlacXiphIndex, false)->removeUnsupportedProperties(unsupported);
if(d->hasID3v2)
d->tag.access<ID3v2::Tag>(FlacID3v2Index, false)->removeUnsupportedProperties(unsupported);
if(d->hasID3v1)
d->tag.access<ID3v1::Tag>(FlacID3v1Index, false)->removeUnsupportedProperties(unsupported);
}
PropertyMap FLAC::File::setProperties(const PropertyMap &properties)
{
if(d->hasXiphComment)
return d->tag.access<Ogg::XiphComment>(FlacXiphIndex, false)->setProperties(properties);
else if(d->hasID3v2)
return d->tag.access<ID3v2::Tag>(FlacID3v2Index, false)->setProperties(properties);
else if(d->hasID3v1)
return d->tag.access<ID3v1::Tag>(FlacID3v1Index, false)->setProperties(properties);
else
return d->tag.access<Ogg::XiphComment>(FlacXiphIndex, true)->setProperties(properties);
}
FLAC::Properties *FLAC::File::audioProperties() const
{
return d->properties;
@@ -132,73 +187,69 @@ bool FLAC::File::save()
return false;
}
if(!isValid()) {
debug("FLAC::File::save() -- Trying to save invalid file.");
return false;
}
// Create new vorbis comments
Tag::duplicate(&d->tag, xiphComment(true), true);
Tag::duplicate(&d->tag, xiphComment(true), false);
d->xiphCommentData = xiphComment()->render(false);
// A Xiph comment portion of the data stream starts with a 4-byte descriptor.
// The first byte indicates the frame type. The last three bytes are used
// to give the length of the data segment. Here we start
// Replace metadata blocks
ByteVector data = ByteVector::fromUInt(d->xiphCommentData.size());
data[0] = char(VorbisComment);
data.append(d->xiphCommentData);
// If file already have comment => find and update it
// if not => insert one
// TODO: Search for padding and use that
if(d->hasXiphComment) {
long nextBlockOffset = d->flacStart;
bool isLastBlock = false;
while(!isLastBlock) {
seek(nextBlockOffset);
ByteVector header = readBlock(4);
char blockType = header[0] & 0x7f;
isLastBlock = (header[0] & 0x80) != 0;
uint blockLength = header.mid(1, 3).toUInt();
if(blockType == VorbisComment) {
data[0] = header[0];
insert(data, nextBlockOffset, blockLength + 4);
break;
}
nextBlockOffset += blockLength + 4;
bool foundVorbisCommentBlock = false;
List<MetadataBlock *> newBlocks;
for(uint i = 0; i < d->blocks.size(); i++) {
MetadataBlock *block = d->blocks[i];
if(block->code() == MetadataBlock::VorbisComment) {
// Set the new Vorbis Comment block
delete block;
block = new UnknownMetadataBlock(MetadataBlock::VorbisComment, d->xiphCommentData);
foundVorbisCommentBlock = true;
}
}
else {
const long firstBlockOffset = d->flacStart;
seek(firstBlockOffset);
ByteVector header = readBlock(4);
bool isLastBlock = (header[0] & 0x80) != 0;
uint blockLength = header.mid(1, 3).toUInt();
if(isLastBlock) {
// If the first block was previously also the last block, then we want to
// mark it as no longer being the first block (the writeBlock() call) and
// then set the data for the block that we're about to write to mark our
// new block as the last block.
seek(firstBlockOffset);
writeBlock(static_cast<char>(header[0] & 0x7F));
data[0] |= 0x80;
if(block->code() == MetadataBlock::Padding) {
delete block;
continue;
}
insert(data, firstBlockOffset + blockLength + 4, 0);
d->hasXiphComment = true;
newBlocks.append(block);
}
if(!foundVorbisCommentBlock) {
newBlocks.append(new UnknownMetadataBlock(MetadataBlock::VorbisComment, d->xiphCommentData));
foundVorbisCommentBlock = true;
}
d->blocks = newBlocks;
// Render data for the metadata blocks
ByteVector data;
for(uint i = 0; i < newBlocks.size(); i++) {
FLAC::MetadataBlock *block = newBlocks[i];
ByteVector blockData = block->render();
ByteVector blockHeader = ByteVector::fromUInt(blockData.size());
blockHeader[0] = block->code();
data.append(blockHeader);
data.append(blockData);
}
// Adjust the padding block(s)
long originalLength = d->streamStart - d->flacStart;
int paddingLength = originalLength - data.size() - 4;
if (paddingLength < 0) {
paddingLength = MinPaddingLength;
}
ByteVector padding = ByteVector::fromUInt(paddingLength);
padding.resize(paddingLength + 4);
padding[0] = (char)(FLAC::MetadataBlock::Padding | LastBlockFlag);
data.append(padding);
// Write the data to the file
insert(data, d->flacStart, originalLength);
d->hasXiphComment = true;
// Update ID3 tags
@@ -224,21 +275,21 @@ bool FLAC::File::save()
ID3v2::Tag *FLAC::File::ID3v2Tag(bool create)
{
if(!create || d->tag[ID3v2Index])
return static_cast<ID3v2::Tag *>(d->tag[ID3v2Index]);
if(!create || d->tag[FlacID3v2Index])
return static_cast<ID3v2::Tag *>(d->tag[FlacID3v2Index]);
d->tag.set(ID3v2Index, new ID3v2::Tag);
return static_cast<ID3v2::Tag *>(d->tag[ID3v2Index]);
d->tag.set(FlacID3v2Index, new ID3v2::Tag);
return static_cast<ID3v2::Tag *>(d->tag[FlacID3v2Index]);
}
ID3v1::Tag *FLAC::File::ID3v1Tag(bool create)
{
return d->tag.access<ID3v1::Tag>(ID3v1Index, create);
return d->tag.access<ID3v1::Tag>(FlacID3v1Index, create);
}
Ogg::XiphComment *FLAC::File::xiphComment(bool create)
{
return d->tag.access<Ogg::XiphComment>(XiphIndex, create);
return d->tag.access<Ogg::XiphComment>(FlacXiphIndex, create);
}
void FLAC::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
@@ -259,12 +310,12 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle
if(d->ID3v2Location >= 0) {
d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory));
d->tag.set(FlacID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory));
d->ID3v2OriginalSize = ID3v2Tag()->header()->completeTagSize();
if(ID3v2Tag()->header()->tagSize() <= 0)
d->tag.set(ID3v2Index, 0);
d->tag.set(FlacID3v2Index, 0);
else
d->hasID3v2 = true;
}
@@ -274,7 +325,7 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
d->tag.set(FlacID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
d->hasID3v1 = true;
}
@@ -286,9 +337,9 @@ void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle
return;
if(d->hasXiphComment)
d->tag.set(XiphIndex, new Ogg::XiphComment(xiphCommentData()));
d->tag.set(FlacXiphIndex, new Ogg::XiphComment(xiphCommentData()));
else
d->tag.set(XiphIndex, new Ogg::XiphComment);
d->tag.set(FlacXiphIndex, new Ogg::XiphComment);
if(readProperties)
d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle);
@@ -355,17 +406,17 @@ void FLAC::File::scan()
// First block should be the stream_info metadata
if(blockType != StreamInfo) {
if(blockType != MetadataBlock::StreamInfo) {
debug("FLAC::File::scan() -- invalid FLAC stream");
setValid(false);
return;
}
d->streamInfoData = readBlock(length);
d->blocks.append(new UnknownMetadataBlock(blockType, d->streamInfoData));
nextBlockOffset += length + 4;
// Search through the remaining metadata
while(!isLastBlock) {
header = readBlock(4);
@@ -373,13 +424,44 @@ void FLAC::File::scan()
isLastBlock = (header[0] & 0x80) != 0;
length = header.mid(1, 3).toUInt();
if(blockType == Padding) {
// debug("FLAC::File::scan() -- Padding found");
ByteVector data = readBlock(length);
if(data.size() != length) {
debug("FLAC::File::scan() -- FLAC stream corrupted");
setValid(false);
return;
}
MetadataBlock *block = 0;
// Found the vorbis-comment
else if(blockType == VorbisComment) {
d->xiphCommentData = readBlock(length);
d->hasXiphComment = true;
if(blockType == MetadataBlock::VorbisComment) {
if(!d->hasXiphComment) {
d->xiphCommentData = data;
d->hasXiphComment = true;
}
else {
debug("FLAC::File::scan() -- multiple Vorbis Comment blocks found, using the first one");
}
}
else if(blockType == MetadataBlock::Picture) {
FLAC::Picture *picture = new FLAC::Picture();
if(picture->parse(data)) {
block = picture;
}
else {
debug("FLAC::File::scan() -- invalid picture found, discarting");
delete picture;
}
}
if(!block) {
block = new UnknownMetadataBlock(blockType, data);
}
if(block->code() != MetadataBlock::Padding) {
d->blocks.append(block);
}
else {
delete block;
}
nextBlockOffset += length + 4;
@@ -429,3 +511,47 @@ long FLAC::File::findID3v2()
return -1;
}
List<FLAC::Picture *> FLAC::File::pictureList()
{
List<Picture *> pictures;
for(uint i = 0; i < d->blocks.size(); i++) {
Picture *picture = dynamic_cast<Picture *>(d->blocks[i]);
if(picture) {
pictures.append(picture);
}
}
return pictures;
}
void FLAC::File::addPicture(Picture *picture)
{
d->blocks.append(picture);
}
void FLAC::File::removePicture(Picture *picture, bool del)
{
MetadataBlock *block = picture;
List<MetadataBlock *>::Iterator it = d->blocks.find(block);
if(it != d->blocks.end())
d->blocks.erase(it);
if(del)
delete picture;
}
void FLAC::File::removePictures()
{
List<MetadataBlock *> newBlocks;
for(uint i = 0; i < d->blocks.size(); i++) {
Picture *picture = dynamic_cast<Picture *>(d->blocks[i]);
if(picture) {
delete picture;
}
else {
newBlocks.append(d->blocks[i]);
}
}
d->blocks = newBlocks;
}

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -28,13 +28,15 @@
#include "taglib_export.h"
#include "tfile.h"
#include "tlist.h"
#include "tag.h"
#include "flacpicture.h"
#include "flacproperties.h"
namespace TagLib {
class Tag;
namespace ID3v2 { class FrameFactory; class Tag; }
namespace ID3v1 { class Tag; }
namespace Ogg { class XiphComment; }
@@ -88,6 +90,22 @@ namespace TagLib {
bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Contructs a FLAC file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
* If this file contains and ID3v2 tag the frames will be created using
* \a frameFactory.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
// BIC: merge with the above constructor
File(IOStream *stream, ID3v2::FrameFactory *frameFactory,
bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Destroys this instance of the File.
*/
@@ -103,6 +121,23 @@ namespace TagLib {
*/
virtual TagLib::Tag *tag() const;
/*!
* Implements the unified property interface -- export function.
* If the file contains more than one tag (e.g. XiphComment and ID3v1),
* only the first one (in the order XiphComment, ID3v2, ID3v1) will be
* converted to the PropertyMap.
*/
PropertyMap properties() const;
void removeUnsupportedProperties(const StringList &);
/*!
* Implements the unified property interface -- import function.
* As with the export, only one tag is taken into account. If the file
* has no tag at all, a XiphComment will be created.
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Returns the FLAC::Properties for this file. If no audio properties
* were read then this will return a null pointer.
@@ -182,6 +217,30 @@ namespace TagLib {
*/
long streamLength(); // BIC: remove
/*!
* Returns a list of pictures attached to the FLAC file.
*/
List<Picture *> pictureList();
/*!
* Removes an attached picture. If \a del is true the picture's memory
* will be freed; if it is false, it must be deleted by the user.
*/
void removePicture(Picture *picture, bool del = true);
/*!
* Remove all attached images.
*/
void removePictures();
/*!
* Add a new picture to the file. The file takes ownership of the
* picture and will handle freeing its memory.
*
* \note The file will be saved only after calling save().
*/
void addPicture(Picture *picture);
private:
File(const File &);
File &operator=(const File &);
@@ -191,6 +250,7 @@ namespace TagLib {
long findID3v2();
long findID3v1();
ByteVector xiphCommentData() const;
long findPaddingBreak(long nextPageOffset, long targetOffset, bool *isLast);
class FilePrivate;
FilePrivate *d;

View File

@@ -0,0 +1,51 @@
/**************************************************************************
copyright : (C) 2010 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <taglib.h>
#include <tdebug.h>
#include "flacmetadatablock.h"
using namespace TagLib;
class FLAC::MetadataBlock::MetadataBlockPrivate
{
public:
MetadataBlockPrivate() {}
};
FLAC::MetadataBlock::MetadataBlock()
{
d = 0;
}
FLAC::MetadataBlock::~MetadataBlock()
{
}

View File

@@ -0,0 +1,75 @@
/**************************************************************************
copyright : (C) 2010 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_FLACMETADATABLOCK_H
#define TAGLIB_FLACMETADATABLOCK_H
#include "tlist.h"
#include "tbytevector.h"
#include "taglib_export.h"
namespace TagLib {
namespace FLAC {
class TAGLIB_EXPORT MetadataBlock
{
public:
MetadataBlock();
virtual ~MetadataBlock();
enum BlockType {
StreamInfo = 0,
Padding,
Application,
SeekTable,
VorbisComment,
CueSheet,
Picture
};
/*!
* Returns the FLAC metadata block type.
*/
virtual int code() const = 0;
/*!
* Render the content of the block.
*/
virtual ByteVector render() const = 0;
private:
MetadataBlock(const MetadataBlock &item);
MetadataBlock &operator=(const MetadataBlock &item);
class MetadataBlockPrivate;
MetadataBlockPrivate *d;
};
}
}
#endif

221
taglib/flac/flacpicture.cpp Normal file
View File

@@ -0,0 +1,221 @@
/**************************************************************************
copyright : (C) 2010 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <taglib.h>
#include <tdebug.h>
#include "flacpicture.h"
using namespace TagLib;
class FLAC::Picture::PicturePrivate
{
public:
PicturePrivate() :
type(FLAC::Picture::Other),
width(0),
height(0),
colorDepth(0),
numColors(0)
{}
Type type;
String mimeType;
String description;
int width;
int height;
int colorDepth;
int numColors;
ByteVector data;
};
FLAC::Picture::Picture()
{
d = new PicturePrivate;
}
FLAC::Picture::Picture(const ByteVector &data)
{
d = new PicturePrivate;
parse(data);
}
FLAC::Picture::~Picture()
{
delete d;
}
int FLAC::Picture::code() const
{
return FLAC::MetadataBlock::Picture;
}
bool FLAC::Picture::parse(const ByteVector &data)
{
if(data.size() < 32) {
debug("A picture block must contain at least 5 bytes.");
return false;
}
int pos = 0;
d->type = FLAC::Picture::Type(data.mid(pos, 4).toUInt());
pos += 4;
uint mimeTypeLength = data.mid(pos, 4).toUInt();
pos += 4;
if(pos + mimeTypeLength + 24 > data.size()) {
debug("Invalid picture block.");
return false;
}
d->mimeType = String(data.mid(pos, mimeTypeLength), String::UTF8);
pos += mimeTypeLength;
uint descriptionLength = data.mid(pos, 4).toUInt();
pos += 4;
if(pos + descriptionLength + 20 > data.size()) {
debug("Invalid picture block.");
return false;
}
d->description = String(data.mid(pos, descriptionLength), String::UTF8);
pos += descriptionLength;
d->width = data.mid(pos, 4).toUInt();
pos += 4;
d->height = data.mid(pos, 4).toUInt();
pos += 4;
d->colorDepth = data.mid(pos, 4).toUInt();
pos += 4;
d->numColors = data.mid(pos, 4).toUInt();
pos += 4;
uint dataLength = data.mid(pos, 4).toUInt();
pos += 4;
if(pos + dataLength > data.size()) {
debug("Invalid picture block.");
return false;
}
d->data = data.mid(pos, dataLength);
return true;
}
ByteVector FLAC::Picture::render() const
{
ByteVector result;
result.append(ByteVector::fromUInt(d->type));
ByteVector mimeTypeData = d->mimeType.data(String::UTF8);
result.append(ByteVector::fromUInt(mimeTypeData.size()));
result.append(mimeTypeData);
ByteVector descriptionData = d->description.data(String::UTF8);
result.append(ByteVector::fromUInt(descriptionData.size()));
result.append(descriptionData);
result.append(ByteVector::fromUInt(d->width));
result.append(ByteVector::fromUInt(d->height));
result.append(ByteVector::fromUInt(d->colorDepth));
result.append(ByteVector::fromUInt(d->numColors));
result.append(ByteVector::fromUInt(d->data.size()));
result.append(d->data);
return result;
}
FLAC::Picture::Type FLAC::Picture::type() const
{
return d->type;
}
void FLAC::Picture::setType(FLAC::Picture::Type type)
{
d->type = type;
}
String FLAC::Picture::mimeType() const
{
return d->mimeType;
}
void FLAC::Picture::setMimeType(const String &mimeType)
{
d->mimeType = mimeType;
}
String FLAC::Picture::description() const
{
return d->description;
}
void FLAC::Picture::setDescription(const String &description)
{
d->description = description;
}
int FLAC::Picture::width() const
{
return d->width;
}
void FLAC::Picture::setWidth(int width)
{
d->width = width;
}
int FLAC::Picture::height() const
{
return d->height;
}
void FLAC::Picture::setHeight(int height)
{
d->height = height;
}
int FLAC::Picture::colorDepth() const
{
return d->colorDepth;
}
void FLAC::Picture::setColorDepth(int colorDepth)
{
d->colorDepth = colorDepth;
}
int FLAC::Picture::numColors() const
{
return d->numColors;
}
void FLAC::Picture::setNumColors(int numColors)
{
d->numColors = numColors;
}
ByteVector FLAC::Picture::data() const
{
return d->data;
}
void FLAC::Picture::setData(const ByteVector &data)
{
d->data = data;
}

208
taglib/flac/flacpicture.h Normal file
View File

@@ -0,0 +1,208 @@
/**************************************************************************
copyright : (C) 2010 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_FLACPICTURE_H
#define TAGLIB_FLACPICTURE_H
#include "tlist.h"
#include "tstring.h"
#include "tbytevector.h"
#include "taglib_export.h"
#include "flacmetadatablock.h"
namespace TagLib {
namespace FLAC {
class TAGLIB_EXPORT Picture : public MetadataBlock
{
public:
/*!
* This describes the function or content of the picture.
*/
enum Type {
//! A type not enumerated below
Other = 0x00,
//! 32x32 PNG image that should be used as the file icon
FileIcon = 0x01,
//! File icon of a different size or format
OtherFileIcon = 0x02,
//! Front cover image of the album
FrontCover = 0x03,
//! Back cover image of the album
BackCover = 0x04,
//! Inside leaflet page of the album
LeafletPage = 0x05,
//! Image from the album itself
Media = 0x06,
//! Picture of the lead artist or soloist
LeadArtist = 0x07,
//! Picture of the artist or performer
Artist = 0x08,
//! Picture of the conductor
Conductor = 0x09,
//! Picture of the band or orchestra
Band = 0x0A,
//! Picture of the composer
Composer = 0x0B,
//! Picture of the lyricist or text writer
Lyricist = 0x0C,
//! Picture of the recording location or studio
RecordingLocation = 0x0D,
//! Picture of the artists during recording
DuringRecording = 0x0E,
//! Picture of the artists during performance
DuringPerformance = 0x0F,
//! Picture from a movie or video related to the track
MovieScreenCapture = 0x10,
//! Picture of a large, coloured fish
ColouredFish = 0x11,
//! Illustration related to the track
Illustration = 0x12,
//! Logo of the band or performer
BandLogo = 0x13,
//! Logo of the publisher (record company)
PublisherLogo = 0x14
};
Picture();
Picture(const ByteVector &data);
~Picture();
/*!
* Returns the type of the image.
*/
Type type() const;
/*!
* Sets the type of the image.
*/
void setType(Type type);
/*!
* Returns the mime type of the image. This should in most cases be
* "image/png" or "image/jpeg".
*/
String mimeType() const;
/*!
* Sets the mime type of the image. This should in most cases be
* "image/png" or "image/jpeg".
*/
void setMimeType(const String &m);
/*!
* Returns a text description of the image.
*/
String description() const;
/*!
* Sets a textual description of the image to \a desc.
*/
void setDescription(const String &desc);
/*!
* Returns the width of the image.
*/
int width() const;
/*!
* Sets the width of the image.
*/
void setWidth(int w);
/*!
* Returns the height of the image.
*/
int height() const;
/*!
* Sets the height of the image.
*/
void setHeight(int h);
/*!
* Returns the color depth (in bits-per-pixel) of the image.
*/
int colorDepth() const;
/*!
* Sets the color depth (in bits-per-pixel) of the image.
*/
void setColorDepth(int depth);
/*!
* Returns the number of colors used on the image..
*/
int numColors() const;
/*!
* Sets the number of colors used on the image (for indexed images).
*/
void setNumColors(int numColors);
/*!
* Returns the image data.
*/
ByteVector data() const;
/*!
* Sets the image data.
*/
void setData(const ByteVector &data);
/*!
* Returns the FLAC metadata block type.
*/
int code() const;
/*!
* Render the content to the FLAC picture block format.
*/
ByteVector render() const;
/*!
* Parse the picture data in the FLAC picture block format.
*/
bool parse(const ByteVector &rawData);
private:
Picture(const Picture &item);
Picture &operator=(const Picture &item);
class PicturePrivate;
PicturePrivate *d;
};
typedef List<Picture> PictureList;
}
}
#endif

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -42,7 +42,8 @@ public:
bitrate(0),
sampleRate(0),
sampleWidth(0),
channels(0) {}
channels(0),
sampleFrames(0) {}
ByteVector data;
long streamLength;
@@ -52,6 +53,8 @@ public:
int sampleRate;
int sampleWidth;
int channels;
unsigned long long sampleFrames;
ByteVector signature;
};
////////////////////////////////////////////////////////////////////////////////
@@ -100,6 +103,16 @@ int FLAC::Properties::channels() const
return d->channels;
}
unsigned long long FLAC::Properties::sampleFrames() const
{
return d->sampleFrames;
}
ByteVector FLAC::Properties::signature() const
{
return d->signature;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
@@ -126,6 +139,8 @@ void FLAC::Properties::read()
pos += 3;
uint flags = d->data.mid(pos, 4).toUInt(true);
pos += 4;
d->sampleRate = flags >> 12;
d->channels = ((flags >> 9) & 7) + 1;
d->sampleWidth = ((flags >> 4) & 31) + 1;
@@ -133,12 +148,14 @@ void FLAC::Properties::read()
// The last 4 bits are the most significant 4 bits for the 36 bit
// stream length in samples. (Audio files measured in days)
uint highLength =d->sampleRate > 0 ? (((flags & 0xf) << 28) / d->sampleRate) << 4 : 0;
unsigned long long hi = flags & 0xf;
unsigned long long lo = d->data.mid(pos, 4).toUInt(true);
pos += 4;
d->length = d->sampleRate > 0 ?
(d->data.mid(pos, 4).toUInt(true)) / d->sampleRate + highLength : 0;
pos += 4;
d->sampleFrames = (hi << 32) | lo;
if(d->sampleRate > 0)
d->length = int(d->sampleFrames / d->sampleRate);
// Uncompressed bitrate:
@@ -146,5 +163,7 @@ void FLAC::Properties::read()
// Real bitrate:
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
d->bitrate = d->length > 0 ? ((d->streamLength * 8UL) / d->length) / 1000 : 0;
d->signature = d->data.mid(pos, 32);
}

View File

@@ -15,8 +15,8 @@
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
* USA *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
@@ -77,6 +77,17 @@ namespace TagLib {
*/
int sampleWidth() const;
/*!
* Return the number of sample frames
*/
unsigned long long sampleFrames() const;
/*!
* Returns the MD5 signature of the uncompressed audio stream as read
* from the stream info header header.
*/
ByteVector signature() const;
private:
Properties(const Properties &);
Properties &operator=(const Properties &);

View File

@@ -0,0 +1,83 @@
/**************************************************************************
copyright : (C) 2010 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <taglib.h>
#include <tdebug.h>
#include <tstring.h>
#include "flacunknownmetadatablock.h"
using namespace TagLib;
class FLAC::UnknownMetadataBlock::UnknownMetadataBlockPrivate
{
public:
UnknownMetadataBlockPrivate() : code(0) {}
int code;
ByteVector data;
};
FLAC::UnknownMetadataBlock::UnknownMetadataBlock(int code, const ByteVector &data)
{
d = new UnknownMetadataBlockPrivate;
d->code = code;
//debug(String(data.toHex()));
d->data = data;
}
FLAC::UnknownMetadataBlock::~UnknownMetadataBlock()
{
delete d;
}
int FLAC::UnknownMetadataBlock::code() const
{
return d->code;
}
void FLAC::UnknownMetadataBlock::setCode(int code)
{
d->code = code;
}
ByteVector FLAC::UnknownMetadataBlock::data() const
{
return d->data;
}
void FLAC::UnknownMetadataBlock::setData(const ByteVector &data)
{
d->data = data;
}
ByteVector FLAC::UnknownMetadataBlock::render() const
{
return d->data;
}

View File

@@ -0,0 +1,81 @@
/**************************************************************************
copyright : (C) 2010 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_FLACUNKNOWNMETADATABLOCK_H
#define TAGLIB_FLACUNKNOWNMETADATABLOCK_H
#include "tlist.h"
#include "tbytevector.h"
#include "taglib_export.h"
#include "flacmetadatablock.h"
namespace TagLib {
namespace FLAC {
class TAGLIB_EXPORT UnknownMetadataBlock : public MetadataBlock
{
public:
UnknownMetadataBlock(int blockType, const ByteVector &data);
~UnknownMetadataBlock();
/*!
* Returns the FLAC metadata block type.
*/
int code() const;
/*!
* Sets the FLAC metadata block type.
*/
void setCode(int code);
/*!
* Returns the FLAC metadata block type.
*/
ByteVector data() const;
/*!
* Sets the FLAC metadata block type.
*/
void setData(const ByteVector &data);
/*!
* Render the content of the block.
*/
ByteVector render() const;
private:
UnknownMetadataBlock(const MetadataBlock &item);
UnknownMetadataBlock &operator=(const MetadataBlock &item);
class UnknownMetadataBlockPrivate;
UnknownMetadataBlockPrivate *d;
};
}
}
#endif

328
taglib/it/itfile.cpp Normal file
View File

@@ -0,0 +1,328 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#include "tstringlist.h"
#include "itfile.h"
#include "tdebug.h"
#include "modfileprivate.h"
#include "tpropertymap.h"
using namespace TagLib;
using namespace IT;
class IT::File::FilePrivate
{
public:
FilePrivate(AudioProperties::ReadStyle propertiesStyle)
: tag(), properties(propertiesStyle)
{
}
Mod::Tag tag;
IT::Properties properties;
};
IT::File::File(FileName file, bool readProperties,
AudioProperties::ReadStyle propertiesStyle) :
Mod::FileBase(file),
d(new FilePrivate(propertiesStyle))
{
read(readProperties);
}
IT::File::File(IOStream *stream, bool readProperties,
AudioProperties::ReadStyle propertiesStyle) :
Mod::FileBase(stream),
d(new FilePrivate(propertiesStyle))
{
read(readProperties);
}
IT::File::~File()
{
delete d;
}
Mod::Tag *IT::File::tag() const
{
return &d->tag;
}
PropertyMap IT::File::properties() const
{
return d->tag.properties();
}
PropertyMap IT::File::setProperties(const PropertyMap &properties)
{
return d->tag.setProperties(properties);
}
IT::Properties *IT::File::audioProperties() const
{
return &d->properties;
}
bool IT::File::save()
{
if(readOnly())
{
debug("IT::File::save() - Cannot save to a read only file.");
return false;
}
seek(4);
writeString(d->tag.title(), 25);
writeByte(0);
seek(2, Current);
ushort length = 0;
ushort instrumentCount = 0;
ushort sampleCount = 0;
if(!readU16L(length) || !readU16L(instrumentCount) || !readU16L(sampleCount))
return false;
seek(15, Current);
// write comment as instrument and sample names:
StringList lines = d->tag.comment().split("\n");
for(ushort i = 0; i < instrumentCount; ++ i) {
seek(192L + length + ((long)i << 2));
ulong instrumentOffset = 0;
if(!readU32L(instrumentOffset))
return false;
seek(instrumentOffset + 32);
if(i < lines.size())
writeString(lines[i], 25);
else
writeString(String::null, 25);
writeByte(0);
}
for(ushort i = 0; i < sampleCount; ++ i) {
seek(192L + length + ((long)instrumentCount << 2) + ((long)i << 2));
ulong sampleOffset = 0;
if(!readU32L(sampleOffset))
return false;
seek(sampleOffset + 20);
if((TagLib::uint)(i + instrumentCount) < lines.size())
writeString(lines[i + instrumentCount], 25);
else
writeString(String::null, 25);
writeByte(0);
}
// write rest as message:
StringList messageLines;
for(uint i = instrumentCount + sampleCount; i < lines.size(); ++ i)
messageLines.append(lines[i]);
ByteVector message = messageLines.toString("\r").data(String::Latin1);
// it's actually not really stated if the message needs a
// terminating NUL but it does not hurt to add one:
if(message.size() > 7999)
message.resize(7999);
message.append((char)0);
ushort special = 0;
ushort messageLength = 0;
ulong messageOffset = 0;
seek(46);
if(!readU16L(special))
return false;
ulong fileSize = File::length();
if(special & Properties::MessageAttached) {
seek(54);
if(!readU16L(messageLength) || !readU32L(messageOffset))
return false;
if(messageLength == 0)
messageOffset = fileSize;
}
else
{
messageOffset = fileSize;
seek(46);
writeU16L(special | 0x1);
}
if(messageOffset + messageLength >= fileSize) {
// append new message
seek(54);
writeU16L(message.size());
writeU32L(messageOffset);
seek(messageOffset);
writeBlock(message);
truncate(messageOffset + message.size());
}
else {
// Only overwrite existing message.
// I'd need to parse (understand!) the whole file for more.
// Although I could just move the message to the end of file
// and let the existing one be, but that would waste space.
message.resize(messageLength, 0);
seek(messageOffset);
writeBlock(message);
}
return true;
}
void IT::File::read(bool)
{
if(!isOpen())
return;
seek(0);
READ_ASSERT(readBlock(4) == "IMPM");
READ_STRING(d->tag.setTitle, 26);
seek(2, Current);
READ_U16L_AS(length);
READ_U16L_AS(instrumentCount);
READ_U16L_AS(sampleCount);
d->properties.setInstrumentCount(instrumentCount);
d->properties.setSampleCount(sampleCount);
READ_U16L(d->properties.setPatternCount);
READ_U16L(d->properties.setVersion);
READ_U16L(d->properties.setCompatibleVersion);
READ_U16L(d->properties.setFlags);
READ_U16L_AS(special);
d->properties.setSpecial(special);
READ_BYTE(d->properties.setGlobalVolume);
READ_BYTE(d->properties.setMixVolume);
READ_BYTE(d->properties.setBpmSpeed);
READ_BYTE(d->properties.setTempo);
READ_BYTE(d->properties.setPanningSeparation);
READ_BYTE(d->properties.setPitchWheelDepth);
// IT supports some kind of comment tag. Still, the
// sample/instrument names are abused as comments so
// I just add all together.
String message;
if(special & Properties::MessageAttached) {
READ_U16L_AS(messageLength);
READ_U32L_AS(messageOffset);
seek(messageOffset);
ByteVector messageBytes = readBlock(messageLength);
READ_ASSERT(messageBytes.size() == messageLength);
int index = messageBytes.find((char) 0);
if(index > -1)
messageBytes.resize(index, 0);
messageBytes.replace('\r', '\n');
message = messageBytes;
}
seek(64);
ByteVector pannings = readBlock(64);
ByteVector volumes = readBlock(64);
READ_ASSERT(pannings.size() == 64 && volumes.size() == 64);
int channels = 0;
for(int i = 0; i < 64; ++ i) {
// Strictly speaking an IT file has always 64 channels, but
// I don't count disabled and muted channels.
// But this always gives 64 channels for all my files anyway.
// Strangely VLC does report other values. I wonder how VLC
// gets it's values.
if((unsigned char) pannings[i] < 128 && volumes[i] > 0)
++channels;
}
d->properties.setChannels(channels);
// real length might be shorter because of skips and terminator
ushort realLength = 0;
for(ushort i = 0; i < length; ++ i) {
READ_BYTE_AS(order);
if(order == 255) break;
if(order != 254) ++ realLength;
}
d->properties.setLengthInPatterns(realLength);
StringList comment;
// Note: I found files that have nil characters somewhere
// in the instrument/sample names and more characters
// afterwards. The spec does not mention such a case.
// Currently I just discard anything after a nil, but
// e.g. VLC seems to interprete a nil as a space. I
// don't know what is the proper behaviour.
for(ushort i = 0; i < instrumentCount; ++ i) {
seek(192L + length + ((long)i << 2));
READ_U32L_AS(instrumentOffset);
seek(instrumentOffset);
ByteVector instrumentMagic = readBlock(4);
READ_ASSERT(instrumentMagic == "IMPI");
READ_STRING_AS(dosFileName, 13);
seek(15, Current);
READ_STRING_AS(instrumentName, 26);
comment.append(instrumentName);
}
for(ushort i = 0; i < sampleCount; ++ i) {
seek(192L + length + ((long)instrumentCount << 2) + ((long)i << 2));
READ_U32L_AS(sampleOffset);
seek(sampleOffset);
ByteVector sampleMagic = readBlock(4);
READ_ASSERT(sampleMagic == "IMPS");
READ_STRING_AS(dosFileName, 13);
READ_BYTE_AS(globalVolume);
READ_BYTE_AS(sampleFlags);
READ_BYTE_AS(sampleVolume);
READ_STRING_AS(sampleName, 26);
/*
READ_BYTE_AS(sampleCvt);
READ_BYTE_AS(samplePanning);
READ_U32L_AS(sampleLength);
READ_U32L_AS(loopStart);
READ_U32L_AS(loopStop);
READ_U32L_AS(c5speed);
READ_U32L_AS(sustainLoopStart);
READ_U32L_AS(sustainLoopEnd);
READ_U32L_AS(sampleDataOffset);
READ_BYTE_AS(vibratoSpeed);
READ_BYTE_AS(vibratoDepth);
READ_BYTE_AS(vibratoRate);
READ_BYTE_AS(vibratoType);
*/
comment.append(sampleName);
}
if(message.size() > 0)
comment.append(message);
d->tag.setComment(comment.toString("\n"));
d->tag.setTrackerName("Impulse Tracker");
}

105
taglib/it/itfile.h Normal file
View File

@@ -0,0 +1,105 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#ifndef TAGLIB_ITFILE_H
#define TAGLIB_ITFILE_H
#include "tfile.h"
#include "audioproperties.h"
#include "taglib_export.h"
#include "modfilebase.h"
#include "modtag.h"
#include "itproperties.h"
namespace TagLib {
namespace IT {
class TAGLIB_EXPORT File : public Mod::FileBase {
public:
/*!
* Contructs a Impulse Tracker file from \a file. If \a readProperties
* is true the file's audio properties will also be read using
* \a propertiesStyle. If false, \a propertiesStyle is ignored.
*/
File(FileName file, bool readProperties = true,
AudioProperties::ReadStyle propertiesStyle =
AudioProperties::Average);
/*!
* Contructs a Impulse Tracker file from \a stream. If \a readProperties
* is true the file's audio properties will also be read using
* \a propertiesStyle. If false, \a propertiesStyle is ignored.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
File(IOStream *stram, bool readProperties = true,
AudioProperties::ReadStyle propertiesStyle =
AudioProperties::Average);
/*!
* Destroys this instance of the File.
*/
virtual ~File();
Mod::Tag *tag() const;
/*!
* Forwards to Mod::Tag::properties().
* BIC: will be removed once File::toDict() is made virtual
*/
PropertyMap properties() const;
/*!
* Forwards to Mod::Tag::setProperties().
* BIC: will be removed once File::setProperties() is made virtual
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Returns the IT::Properties for this file. If no audio properties
* were read then this will return a null pointer.
*/
IT::Properties *audioProperties() const;
/*!
* Save the file.
* This is the same as calling save(AllTags);
*
* \note Saving Impulse Tracker tags is not supported.
*/
bool save();
private:
File(const File &);
File &operator=(const File &);
void read(bool readProperties);
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

245
taglib/it/itproperties.cpp Normal file
View File

@@ -0,0 +1,245 @@
/***************************************************************************
copyright :(C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#include "itproperties.h"
using namespace TagLib;
using namespace IT;
class IT::Properties::PropertiesPrivate
{
public:
PropertiesPrivate() :
channels(0),
lengthInPatterns(0),
instrumentCount(0),
sampleCount(0),
patternCount(0),
version(0),
compatibleVersion(0),
flags(0),
special(0),
globalVolume(0),
mixVolume(0),
tempo(0),
bpmSpeed(0),
panningSeparation(0),
pitchWheelDepth(0)
{
}
int channels;
ushort lengthInPatterns;
ushort instrumentCount;
ushort sampleCount;
ushort patternCount;
ushort version;
ushort compatibleVersion;
ushort flags;
ushort special;
uchar globalVolume;
uchar mixVolume;
uchar tempo;
uchar bpmSpeed;
uchar panningSeparation;
uchar pitchWheelDepth;
};
IT::Properties::Properties(AudioProperties::ReadStyle propertiesStyle) :
AudioProperties(propertiesStyle),
d(new PropertiesPrivate)
{
}
IT::Properties::~Properties()
{
delete d;
}
int IT::Properties::length() const
{
return 0;
}
int IT::Properties::bitrate() const
{
return 0;
}
int IT::Properties::sampleRate() const
{
return 0;
}
int IT::Properties::channels() const
{
return d->channels;
}
TagLib::ushort IT::Properties::lengthInPatterns() const
{
return d->lengthInPatterns;
}
bool IT::Properties::stereo() const
{
return d->flags & Stereo;
}
TagLib::ushort IT::Properties::instrumentCount() const
{
return d->instrumentCount;
}
TagLib::ushort IT::Properties::sampleCount() const
{
return d->sampleCount;
}
TagLib::ushort IT::Properties::patternCount() const
{
return d->patternCount;
}
TagLib::ushort IT::Properties::version() const
{
return d->version;
}
TagLib::ushort IT::Properties::compatibleVersion() const
{
return d->compatibleVersion;
}
TagLib::ushort IT::Properties::flags() const
{
return d->flags;
}
TagLib::ushort IT::Properties::special() const
{
return d->special;
}
uchar IT::Properties::globalVolume() const
{
return d->globalVolume;
}
uchar IT::Properties::mixVolume() const
{
return d->mixVolume;
}
uchar IT::Properties::tempo() const
{
return d->tempo;
}
uchar IT::Properties::bpmSpeed() const
{
return d->bpmSpeed;
}
uchar IT::Properties::panningSeparation() const
{
return d->panningSeparation;
}
uchar IT::Properties::pitchWheelDepth() const
{
return d->pitchWheelDepth;
}
void IT::Properties::setChannels(int channels)
{
d->channels = channels;
}
void IT::Properties::setLengthInPatterns(ushort lengthInPatterns)
{
d->lengthInPatterns = lengthInPatterns;
}
void IT::Properties::setInstrumentCount(ushort instrumentCount)
{
d->instrumentCount = instrumentCount;
}
void IT::Properties::setSampleCount(ushort sampleCount)
{
d->sampleCount = sampleCount;
}
void IT::Properties::setPatternCount(ushort patternCount)
{
d->patternCount = patternCount;
}
void IT::Properties::setFlags(ushort flags)
{
d->flags = flags;
}
void IT::Properties::setSpecial(ushort special)
{
d->special = special;
}
void IT::Properties::setCompatibleVersion(ushort compatibleVersion)
{
d->compatibleVersion = compatibleVersion;
}
void IT::Properties::setVersion(ushort version)
{
d->version = version;
}
void IT::Properties::setGlobalVolume(uchar globalVolume)
{
d->globalVolume = globalVolume;
}
void IT::Properties::setMixVolume(uchar mixVolume)
{
d->mixVolume = mixVolume;
}
void IT::Properties::setTempo(uchar tempo)
{
d->tempo = tempo;
}
void IT::Properties::setBpmSpeed(uchar bpmSpeed)
{
d->bpmSpeed = bpmSpeed;
}
void IT::Properties::setPanningSeparation(uchar panningSeparation)
{
d->panningSeparation = panningSeparation;
}
void IT::Properties::setPitchWheelDepth(uchar pitchWheelDepth)
{
d->pitchWheelDepth = pitchWheelDepth;
}

101
taglib/it/itproperties.h Normal file
View File

@@ -0,0 +1,101 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#ifndef TAGLIB_ITPROPERTIES_H
#define TAGLIB_ITPROPERTIES_H
#include "taglib.h"
#include "audioproperties.h"
namespace TagLib {
namespace IT {
class TAGLIB_EXPORT Properties : public AudioProperties {
friend class File;
public:
/*! Flag bits. */
enum {
Stereo = 1,
Vol0MixOptimizations = 2,
UseInstruments = 4,
LinearSlides = 8,
OldEffects = 16,
LinkEffects = 32,
UseMidiPitchController = 64,
RequestEmbeddedMidiConf = 128
};
/*! Special bits. */
enum {
MessageAttached = 1,
MidiConfEmbedded = 8
};
Properties(AudioProperties::ReadStyle propertiesStyle);
virtual ~Properties();
int length() const;
int bitrate() const;
int sampleRate() const;
int channels() const;
ushort lengthInPatterns() const;
bool stereo() const;
ushort instrumentCount() const;
ushort sampleCount() const;
ushort patternCount() const;
ushort version() const;
ushort compatibleVersion() const;
ushort flags() const;
ushort special() const;
uchar globalVolume() const;
uchar mixVolume() const;
uchar tempo() const;
uchar bpmSpeed() const;
uchar panningSeparation() const;
uchar pitchWheelDepth() const;
void setChannels(int channels);
void setLengthInPatterns(ushort lengthInPatterns);
void setInstrumentCount(ushort instrumentCount);
void setSampleCount (ushort sampleCount);
void setPatternCount(ushort patternCount);
void setVersion (ushort version);
void setCompatibleVersion(ushort compatibleVersion);
void setFlags (ushort flags);
void setSpecial (ushort special);
void setGlobalVolume(uchar globalVolume);
void setMixVolume (uchar mixVolume);
void setTempo (uchar tempo);
void setBpmSpeed (uchar bpmSpeed);
void setPanningSeparation(uchar panningSeparation);
void setPitchWheelDepth (uchar pitchWheelDepth);
private:
Properties(const Properties&);
Properties &operator=(const Properties&);
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

185
taglib/mod/modfile.cpp Normal file
View File

@@ -0,0 +1,185 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#include "modfile.h"
#include "tstringlist.h"
#include "tdebug.h"
#include "modfileprivate.h"
#include "tpropertymap.h"
using namespace TagLib;
using namespace Mod;
class Mod::File::FilePrivate
{
public:
FilePrivate(AudioProperties::ReadStyle propertiesStyle)
: properties(propertiesStyle)
{
}
Mod::Tag tag;
Mod::Properties properties;
};
Mod::File::File(FileName file, bool readProperties,
AudioProperties::ReadStyle propertiesStyle) :
Mod::FileBase(file),
d(new FilePrivate(propertiesStyle))
{
read(readProperties);
}
Mod::File::File(IOStream *stream, bool readProperties,
AudioProperties::ReadStyle propertiesStyle) :
Mod::FileBase(stream),
d(new FilePrivate(propertiesStyle))
{
read(readProperties);
}
Mod::File::~File()
{
delete d;
}
Mod::Tag *Mod::File::tag() const
{
return &d->tag;
}
Mod::Properties *Mod::File::audioProperties() const
{
return &d->properties;
}
PropertyMap Mod::File::properties() const
{
return d->tag.properties();
}
PropertyMap Mod::File::setProperties(const PropertyMap &properties)
{
return d->tag.setProperties(properties);
}
bool Mod::File::save()
{
if(readOnly()) {
debug("Mod::File::save() - Cannot save to a read only file.");
return false;
}
seek(0);
writeString(d->tag.title(), 20);
StringList lines = d->tag.comment().split("\n");
uint n = std::min(lines.size(), d->properties.instrumentCount());
for(uint i = 0; i < n; ++ i) {
writeString(lines[i], 22);
seek(8, Current);
}
for(uint i = n; i < d->properties.instrumentCount(); ++ i) {
writeString(String::null, 22);
seek(8, Current);
}
return true;
}
void Mod::File::read(bool)
{
if(!isOpen())
return;
seek(1080);
ByteVector modId = readBlock(4);
READ_ASSERT(modId.size() == 4);
int channels = 4;
uint instruments = 31;
if(modId == "M.K." || modId == "M!K!" || modId == "M&K!" || modId == "N.T.") {
d->tag.setTrackerName("ProTracker");
channels = 4;
}
else if(modId.startsWith("FLT") || modId.startsWith("TDZ")) {
d->tag.setTrackerName("StarTrekker");
char digit = modId[3];
READ_ASSERT(digit >= '0' && digit <= '9');
channels = digit - '0';
}
else if(modId.endsWith("CHN")) {
d->tag.setTrackerName("StarTrekker");
char digit = modId[0];
READ_ASSERT(digit >= '0' && digit <= '9');
channels = digit - '0';
}
else if(modId == "CD81" || modId == "OKTA") {
d->tag.setTrackerName("Atari Oktalyzer");
channels = 8;
}
else if(modId.endsWith("CH") || modId.endsWith("CN")) {
d->tag.setTrackerName("TakeTracker");
char digit = modId[0];
READ_ASSERT(digit >= '0' && digit <= '9');
channels = (digit - '0') * 10;
digit = modId[1];
READ_ASSERT(digit >= '0' && digit <= '9');
channels += digit - '0';
}
else {
// Not sure if this is correct. I'd need a file
// created with NoiseTracker to check this.
d->tag.setTrackerName("NoiseTracker"); // probably
channels = 4;
instruments = 15;
}
d->properties.setChannels(channels);
d->properties.setInstrumentCount(instruments);
seek(0);
READ_STRING(d->tag.setTitle, 20);
StringList comment;
for(uint i = 0; i < instruments; ++ i) {
READ_STRING_AS(instrumentName, 22);
// value in words, * 2 (<< 1) for bytes:
READ_U16B_AS(sampleLength);
READ_BYTE_AS(fineTuneByte);
int fineTune = fineTuneByte & 0xF;
// > 7 means negative value
if(fineTune > 7) fineTune -= 16;
READ_BYTE_AS(volume);
if(volume > 64) volume = 64;
// volume in decibels: 20 * log10(volume / 64)
// value in words, * 2 (<< 1) for bytes:
READ_U16B_AS(repeatStart);
// value in words, * 2 (<< 1) for bytes:
READ_U16B_AS(repatLength);
comment.append(instrumentName);
}
READ_BYTE(d->properties.setLengthInPatterns);
d->tag.setComment(comment.toString("\n"));
}

106
taglib/mod/modfile.h Normal file
View File

@@ -0,0 +1,106 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#ifndef TAGLIB_MODFILE_H
#define TAGLIB_MODFILE_H
#include "tfile.h"
#include "audioproperties.h"
#include "taglib_export.h"
#include "modfilebase.h"
#include "modtag.h"
#include "modproperties.h"
namespace TagLib {
namespace Mod {
class TAGLIB_EXPORT File : public TagLib::Mod::FileBase
{
public:
/*!
* Contructs a Protracker file from \a file. If \a readProperties
* is true the file's audio properties will also be read using
* \a propertiesStyle. If false, \a propertiesStyle is ignored.
*/
File(FileName file, bool readProperties = true,
AudioProperties::ReadStyle propertiesStyle =
AudioProperties::Average);
/*!
* Contructs a Protracker file from \a stream. If \a readProperties
* is true the file's audio properties will also be read using
* \a propertiesStyle. If false, \a propertiesStyle is ignored.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
File(IOStream *stream, bool readProperties = true,
AudioProperties::ReadStyle propertiesStyle =
AudioProperties::Average);
/*!
* Destroys this instance of the File.
*/
virtual ~File();
Mod::Tag *tag() const;
/*!
* Implements the unified property interface -- export function.
* Forwards to Mod::Tag::properties().
*/
PropertyMap properties() const;
/*!
* Implements the unified property interface -- import function.
* Forwards to Mod::Tag::setProperties().
*/
PropertyMap setProperties(const PropertyMap &);
/*!
* Returns the Mod::Properties for this file. If no audio properties
* were read then this will return a null pointer.
*/
Mod::Properties *audioProperties() const;
/*!
* Save the file.
* This is the same as calling save(AllTags);
*
* \note Saving Protracker tags is not supported.
*/
bool save();
private:
File(const File &);
File &operator=(const File &);
void read(bool readProperties);
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

120
taglib/mod/modfilebase.cpp Normal file
View File

@@ -0,0 +1,120 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#include "tdebug.h"
#include "modfilebase.h"
using namespace TagLib;
using namespace Mod;
Mod::FileBase::FileBase(FileName file) : TagLib::File(file)
{
}
Mod::FileBase::FileBase(IOStream *stream) : TagLib::File(stream)
{
}
void Mod::FileBase::writeString(const String &s, ulong size, char padding)
{
ByteVector data(s.data(String::Latin1));
data.resize(size, padding);
writeBlock(data);
}
bool Mod::FileBase::readString(String &s, ulong size)
{
ByteVector data(readBlock(size));
if(data.size() < size) return false;
int index = data.find((char) 0);
if(index > -1)
{
data.resize(index);
}
data.replace((char) 0xff, ' ');
s = data;
return true;
}
void Mod::FileBase::writeByte(uchar byte)
{
ByteVector data(1, byte);
writeBlock(data);
}
void Mod::FileBase::writeU16L(ushort number)
{
writeBlock(ByteVector::fromShort(number, false));
}
void Mod::FileBase::writeU32L(ulong number)
{
writeBlock(ByteVector::fromUInt(number, false));
}
void Mod::FileBase::writeU16B(ushort number)
{
writeBlock(ByteVector::fromShort(number, true));
}
void Mod::FileBase::writeU32B(ulong number)
{
writeBlock(ByteVector::fromUInt(number, true));
}
bool Mod::FileBase::readByte(uchar &byte)
{
ByteVector data(readBlock(1));
if(data.size() < 1) return false;
byte = data[0];
return true;
}
bool Mod::FileBase::readU16L(ushort &number)
{
ByteVector data(readBlock(2));
if(data.size() < 2) return false;
number = data.toUShort(false);
return true;
}
bool Mod::FileBase::readU32L(ulong &number) {
ByteVector data(readBlock(4));
if(data.size() < 4) return false;
number = data.toUInt(false);
return true;
}
bool Mod::FileBase::readU16B(ushort &number)
{
ByteVector data(readBlock(2));
if(data.size() < 2) return false;
number = data.toUShort(true);
return true;
}
bool Mod::FileBase::readU32B(ulong &number) {
ByteVector data(readBlock(4));
if(data.size() < 4) return false;
number = data.toUInt(true);
return true;
}

62
taglib/mod/modfilebase.h Normal file
View File

@@ -0,0 +1,62 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#ifndef TAGLIB_MODFILEBASE_H
#define TAGLIB_MODFILEBASE_H
#include "taglib.h"
#include "tfile.h"
#include "tstring.h"
#include "tlist.h"
#include "taglib_export.h"
#include <algorithm>
namespace TagLib {
namespace Mod {
class TAGLIB_EXPORT FileBase : public TagLib::File
{
protected:
FileBase(FileName file);
FileBase(IOStream *stream);
void writeString(const String &s, ulong size, char padding = 0);
void writeByte(uchar byte);
void writeU16L(ushort number);
void writeU32L(ulong number);
void writeU16B(ushort number);
void writeU32B(ulong number);
bool readString(String &s, ulong size);
bool readByte(uchar &byte);
bool readU16L(ushort &number);
bool readU32L(ulong &number);
bool readU16B(ushort &number);
bool readU32B(ulong &number);
};
}
}
#endif

View File

@@ -0,0 +1,67 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#ifndef TAGLIB_MODFILEPRIVATE_H
#define TAGLIB_MODFILEPRIVATE_H
// some helper-macros only used internally by (s3m|it|xm)file.cpp
#define READ_ASSERT(cond) \
if(!(cond)) \
{ \
setValid(false); \
return; \
}
#define READ(setter,type,read) \
{ \
type number; \
READ_ASSERT(read(number)); \
setter(number); \
}
#define READ_BYTE(setter) READ(setter,uchar,readByte)
#define READ_U16L(setter) READ(setter,ushort,readU16L)
#define READ_U32L(setter) READ(setter,ulong,readU32L)
#define READ_U16B(setter) READ(setter,ushort,readU16B)
#define READ_U32B(setter) READ(setter,ulong,readU32B)
#define READ_STRING(setter,size) \
{ \
String s; \
READ_ASSERT(readString(s, size)); \
setter(s); \
}
#define READ_AS(type,name,read) \
type name = 0; \
READ_ASSERT(read(name));
#define READ_BYTE_AS(name) READ_AS(uchar,name,readByte)
#define READ_U16L_AS(name) READ_AS(ushort,name,readU16L)
#define READ_U32L_AS(name) READ_AS(ulong,name,readU32L)
#define READ_U16B_AS(name) READ_AS(ushort,name,readU16B)
#define READ_U32B_AS(name) READ_AS(ulong,name,readU32B)
#define READ_STRING_AS(name,size) \
String name; \
READ_ASSERT(readString(name, size));
#endif

View File

@@ -0,0 +1,96 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#include "modproperties.h"
using namespace TagLib;
using namespace Mod;
class Mod::Properties::PropertiesPrivate
{
public:
PropertiesPrivate() :
channels(0),
instrumentCount(0),
lengthInPatterns(0)
{
}
int channels;
uint instrumentCount;
uchar lengthInPatterns;
};
Mod::Properties::Properties(AudioProperties::ReadStyle propertiesStyle) :
AudioProperties(propertiesStyle),
d(new PropertiesPrivate)
{
}
Mod::Properties::~Properties()
{
delete d;
}
int Mod::Properties::length() const
{
return 0;
}
int Mod::Properties::bitrate() const
{
return 0;
}
int Mod::Properties::sampleRate() const
{
return 0;
}
int Mod::Properties::channels() const
{
return d->channels;
}
TagLib::uint Mod::Properties::instrumentCount() const
{
return d->instrumentCount;
}
uchar Mod::Properties::lengthInPatterns() const
{
return d->lengthInPatterns;
}
void Mod::Properties::setChannels(int channels)
{
d->channels = channels;
}
void Mod::Properties::setInstrumentCount(uint instrumentCount)
{
d->instrumentCount = instrumentCount;
}
void Mod::Properties::setLengthInPatterns(uchar lengthInPatterns)
{
d->lengthInPatterns = lengthInPatterns;
}

View File

@@ -0,0 +1,65 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#ifndef TAGLIB_MODPROPERTIES_H
#define TAGLIB_MODPROPERTIES_H
#include "taglib.h"
#include "audioproperties.h"
namespace TagLib {
namespace Mod {
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:
Properties(AudioProperties::ReadStyle propertiesStyle);
virtual ~Properties();
int length() const;
int bitrate() const;
int sampleRate() const;
int channels() const;
uint instrumentCount() const;
uchar lengthInPatterns() const;
void setChannels(int channels);
void setInstrumentCount(uint sampleCount);
void setLengthInPatterns(uchar lengthInPatterns);
private:
friend class File;
Properties(const Properties&);
Properties &operator=(const Properties&);
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

168
taglib/mod/modtag.cpp Normal file
View File

@@ -0,0 +1,168 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#include "modtag.h"
#include "tstringlist.h"
#include "tpropertymap.h"
using namespace TagLib;
using namespace Mod;
class Mod::Tag::TagPrivate
{
public:
TagPrivate()
{
}
String title;
String comment;
String trackerName;
};
Mod::Tag::Tag() : TagLib::Tag()
{
d = new TagPrivate;
}
Mod::Tag::~Tag()
{
delete d;
}
String Mod::Tag::title() const
{
return d->title;
}
String Mod::Tag::artist() const
{
return String::null;
}
String Mod::Tag::album() const
{
return String::null;
}
String Mod::Tag::comment() const
{
return d->comment;
}
String Mod::Tag::genre() const
{
return String::null;
}
TagLib::uint Mod::Tag::year() const
{
return 0;
}
TagLib::uint Mod::Tag::track() const
{
return 0;
}
String Mod::Tag::trackerName() const
{
return d->trackerName;
}
void Mod::Tag::setTitle(const String &title)
{
d->title = title;
}
void Mod::Tag::setArtist(const String &)
{
}
void Mod::Tag::setAlbum(const String &)
{
}
void Mod::Tag::setComment(const String &comment)
{
d->comment = comment;
}
void Mod::Tag::setGenre(const String &)
{
}
void Mod::Tag::setYear(uint)
{
}
void Mod::Tag::setTrack(uint)
{
}
void Mod::Tag::setTrackerName(const String &trackerName)
{
d->trackerName = trackerName;
}
PropertyMap Mod::Tag::properties() const
{
PropertyMap properties;
properties["TITLE"] = d->title;
properties["COMMENT"] = d->comment;
if(!(d->trackerName.isNull()))
properties["TRACKERNAME"] = d->trackerName;
return properties;
}
PropertyMap Mod::Tag::setProperties(const PropertyMap &origProps)
{
PropertyMap properties(origProps);
properties.removeEmpty();
StringList oneValueSet;
if(properties.contains("TITLE")) {
d->title = properties["TITLE"].front();
oneValueSet.append("TITLE");
} else
d->title = String::null;
if(properties.contains("COMMENT")) {
d->comment = properties["COMMENT"].front();
oneValueSet.append("COMMENT");
} else
d->comment = String::null;
if(properties.contains("TRACKERNAME")) {
d->trackerName = properties["TRACKERNAME"].front();
oneValueSet.append("TRACKERNAME");
} else
d->trackerName = String::null;
// for each tag that has been set above, remove the first entry in the corresponding
// value list. The others will be returned as unsupported by this format.
for(StringList::Iterator it = oneValueSet.begin(); it != oneValueSet.end(); ++it) {
if(properties[*it].size() == 1)
properties.erase(*it);
else
properties[*it].erase( properties[*it].begin() );
}
return properties;
}

190
taglib/mod/modtag.h Normal file
View File

@@ -0,0 +1,190 @@
/***************************************************************************
copyright : (C) 2011 by Mathias Panzenböck
email : grosser.meister.morti@gmx.net
***************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, *
* MA 02110-1301 USA *
***************************************************************************/
#ifndef TAGLIB_MODTAG_H
#define TAGLIB_MODTAG_H
#include "tag.h"
namespace TagLib {
namespace Mod {
/*!
* Tags for module files (Mod, S3M, IT, XM).
*
* Note that only the \a title is supported as such by most
* module file formats. Except for XM files the \a trackerName
* is derived from the file format or the flavour of the file
* format. For XM files it is stored in the file.
*
* The \a comment tag is not strictly supported by module files,
* but it is common practice to abuse instrument/sample/pattern
* names as multiline comments. TagLib does so as well.
*/
class TAGLIB_EXPORT Tag : public TagLib::Tag
{
public:
Tag();
virtual ~Tag();
/*!
* Returns the track name; if no track name is present in the tag
* String::null will be returned.
*/
String title() const;
/*!
* Not supported by module files. Therefore always returns String::null.
*/
String artist() const;
/*!
* Not supported by module files. Therefore always returns String::null.
*/
String album() const;
/*!
* Returns the track comment derived from the instrument/sample/pattern
* names; if no comment is present in the tag String::null will be
* returned.
*/
String comment() const;
/*!
* Not supported by module files. Therefore always returns String::null.
*/
String genre() const;
/*!
* Not supported by module files. Therefore always returns 0.
*/
uint year() const;
/*!
* Not supported by module files. Therefore always returns 0.
*/
uint track() const;
/*!
* Returns the name of the tracker used to create/edit the module file.
* Only XM files store this tag to the file as such, for other formats
* (Mod, S3M, IT) this is derived from the file type or the flavour of
* the file type. Therefore only XM files might have an empty
* (String::null) tracker name.
*/
String trackerName() const;
/*!
* Sets the title to \a title. If \a title is String::null then this
* value will be cleared.
*
* The length limits per file type are (1 characetr = 1 byte):
* Mod 20 characters, S3M 27 characters, IT 25 characters and XM 20
* characters.
*/
void setTitle(const String &title);
/*!
* Not supported by module files and therefore ignored.
*/
void setArtist(const String &artist);
/*!
* Not supported by module files and therefore ignored.
*/
void setAlbum(const String &album);
/*!
* Sets the comment to \a comment. If \a comment is String::null then
* this value will be cleared.
*
* Note that module file formats don't actually support a comment tag.
* Instead the names of instruments/patterns/samples are abused as
* a multiline comment. Because of this the number of lines in a
* module file is fixed to the number of instruments/patterns/samples.
*
* Also note that the instrument/pattern/sample name length is limited
* an thus the line length in comments are limited. Too big comments
* will be truncated.
*
* The line length limits per file type are (1 characetr = 1 byte):
* Mod 22 characters, S3M 27 characters, IT 25 characters and XM 22
* characters.
*/
void setComment(const String &comment);
/*!
* Not supported by module files and therefore ignored.
*/
void setGenre(const String &genre);
/*!
* Not supported by module files and therefore ignored.
*/
void setYear(uint year);
/*!
* Not supported by module files and therefore ignored.
*/
void setTrack(uint track);
/*!
* Sets the tracker name to \a trackerName. If \a trackerName is
* String::null then this value will be cleared.
*
* Note that only XM files support this tag. Setting the
* tracker name for other module file formats will be ignored.
*
* The length of this tag is limited to 20 characters (1 character
* = 1 byte).
*/
void setTrackerName(const String &trackerName);
/*!
* Implements the unified property interface -- export function.
* Since the module tag is very limited, the exported map is as well.
*/
PropertyMap properties() const;
/*!
* Implements the unified property interface -- import function.
* Because of the limitations of the module file tag, any tags besides
* COMMENT, TITLE and, if it is an XM file, TRACKERNAME, will be
* returened. Additionally, if the map contains tags with multiple values,
* all but the first will be contained in the returned map of unsupported
* properties.
*/
PropertyMap setProperties(const PropertyMap &);
private:
Tag(const Tag &);
Tag &operator=(const Tag &);
class TagPrivate;
TagPrivate *d;
};
}
}
#endif

198
taglib/mp4/mp4atom.cpp Normal file
View File

@@ -0,0 +1,198 @@
/**************************************************************************
copyright : (C) 2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tdebug.h>
#include <tstring.h>
#include "mp4atom.h"
using namespace TagLib;
const char *MP4::Atom::containers[11] = {
"moov", "udta", "mdia", "meta", "ilst",
"stbl", "minf", "moof", "traf", "trak",
"stsd"
};
MP4::Atom::Atom(File *file)
{
offset = file->tell();
ByteVector header = file->readBlock(8);
if (header.size() != 8) {
// The atom header must be 8 bytes long, otherwise there is either
// trailing garbage or the file is truncated
debug("MP4: Couldn't read 8 bytes of data for atom header");
length = 0;
file->seek(0, File::End);
return;
}
length = header.mid(0, 4).toUInt();
if (length == 1) {
long long longLength = file->readBlock(8).toLongLong();
if (longLength >= 8 && longLength <= 0xFFFFFFFF) {
// The atom has a 64-bit length, but it's actually a 32-bit value
length = (long)longLength;
}
else {
debug("MP4: 64-bit atoms are not supported");
length = 0;
file->seek(0, File::End);
return;
}
}
if (length < 8) {
debug("MP4: Invalid atom size");
length = 0;
file->seek(0, File::End);
return;
}
name = header.mid(4, 4);
for(int i = 0; i < numContainers; i++) {
if(name == containers[i]) {
if(name == "meta") {
file->seek(4, File::Current);
}
else if(name == "stsd") {
file->seek(8, File::Current);
}
while(file->tell() < offset + length) {
MP4::Atom *child = new MP4::Atom(file);
children.append(child);
if (child->length == 0)
return;
}
return;
}
}
file->seek(offset + length);
}
MP4::Atom::~Atom()
{
for(unsigned int i = 0; i < children.size(); i++) {
delete children[i];
}
children.clear();
}
MP4::Atom *
MP4::Atom::find(const char *name1, const char *name2, const char *name3, const char *name4)
{
if(name1 == 0) {
return this;
}
for(unsigned int i = 0; i < children.size(); i++) {
if(children[i]->name == name1) {
return children[i]->find(name2, name3, name4);
}
}
return 0;
}
MP4::AtomList
MP4::Atom::findall(const char *name, bool recursive)
{
MP4::AtomList result;
for(unsigned int i = 0; i < children.size(); i++) {
if(children[i]->name == name) {
result.append(children[i]);
}
if(recursive) {
result.append(children[i]->findall(name, recursive));
}
}
return result;
}
bool
MP4::Atom::path(MP4::AtomList &path, const char *name1, const char *name2, const char *name3)
{
path.append(this);
if(name1 == 0) {
return true;
}
for(unsigned int i = 0; i < children.size(); i++) {
if(children[i]->name == name1) {
return children[i]->path(path, name2, name3);
}
}
return false;
}
MP4::Atoms::Atoms(File *file)
{
file->seek(0, File::End);
long end = file->tell();
file->seek(0);
while(file->tell() + 8 <= end) {
MP4::Atom *atom = new MP4::Atom(file);
atoms.append(atom);
if (atom->length == 0)
break;
}
}
MP4::Atoms::~Atoms()
{
for(unsigned int i = 0; i < atoms.size(); i++) {
delete atoms[i];
}
atoms.clear();
}
MP4::Atom *
MP4::Atoms::find(const char *name1, const char *name2, const char *name3, const char *name4)
{
for(unsigned int i = 0; i < atoms.size(); i++) {
if(atoms[i]->name == name1) {
return atoms[i]->find(name2, name3, name4);
}
}
return 0;
}
MP4::AtomList
MP4::Atoms::path(const char *name1, const char *name2, const char *name3, const char *name4)
{
MP4::AtomList path;
for(unsigned int i = 0; i < atoms.size(); i++) {
if(atoms[i]->name == name1) {
if(!atoms[i]->path(path, name2, name3, name4)) {
path.clear();
}
return path;
}
}
return path;
}

111
taglib/mp4/mp4atom.h Normal file
View File

@@ -0,0 +1,111 @@
/**************************************************************************
copyright : (C) 2007,2011 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
// This file is not part of the public API!
#ifndef DO_NOT_DOCUMENT
#ifndef TAGLIB_MP4ATOM_H
#define TAGLIB_MP4ATOM_H
#include "tfile.h"
#include "tlist.h"
namespace TagLib {
namespace MP4 {
class Atom;
typedef TagLib::List<Atom *> AtomList;
enum AtomDataType
{
TypeImplicit = 0, // for use with tags for which no type needs to be indicated because only one type is allowed
TypeUTF8 = 1, // without any count or null terminator
TypeUTF16 = 2, // also known as UTF-16BE
TypeSJIS = 3, // deprecated unless it is needed for special Japanese characters
TypeHTML = 6, // the HTML file header specifies which HTML version
TypeXML = 7, // the XML header must identify the DTD or schemas
TypeUUID = 8, // also known as GUID; stored as 16 bytes in binary (valid as an ID)
TypeISRC = 9, // stored as UTF-8 text (valid as an ID)
TypeMI3P = 10, // stored as UTF-8 text (valid as an ID)
TypeGIF = 12, // (deprecated) a GIF image
TypeJPEG = 13, // a JPEG image
TypePNG = 14, // a PNG image
TypeURL = 15, // absolute, in UTF-8 characters
TypeDuration = 16, // in milliseconds, 32-bit integer
TypeDateTime = 17, // in UTC, counting seconds since midnight, January 1, 1904; 32 or 64-bits
TypeGenred = 18, // a list of enumerated values
TypeInteger = 21, // a signed big-endian integer with length one of { 1,2,3,4,8 } bytes
TypeRIAAPA = 24, // RIAA parental advisory; { -1=no, 1=yes, 0=unspecified }, 8-bit ingteger
TypeUPC = 25, // Universal Product Code, in text UTF-8 format (valid as an ID)
TypeBMP = 27, // Windows bitmap image
TypeUndefined = 255 // undefined
};
struct AtomData {
AtomData(AtomDataType type, ByteVector data) : type(type), locale(0), data(data) {}
AtomDataType type;
int locale;
ByteVector data;
};
typedef TagLib::List<AtomData> AtomDataList;
class Atom
{
public:
Atom(File *file);
~Atom();
Atom *find(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
bool path(AtomList &path, const char *name1, const char *name2 = 0, const char *name3 = 0);
AtomList findall(const char *name, bool recursive = false);
long offset;
long length;
TagLib::ByteVector name;
AtomList children;
private:
static const int numContainers = 11;
static const char *containers[11];
};
//! Root-level atoms
class Atoms
{
public:
Atoms(File *file);
~Atoms();
Atom *find(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
AtomList path(const char *name1, const char *name2 = 0, const char *name3 = 0, const char *name4 = 0);
AtomList atoms;
};
}
}
#endif
#endif

View File

@@ -0,0 +1,86 @@
/**************************************************************************
copyright : (C) 2009 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <taglib.h>
#include <tdebug.h>
#include "mp4coverart.h"
using namespace TagLib;
class MP4::CoverArt::CoverArtPrivate : public RefCounter
{
public:
CoverArtPrivate() : RefCounter(), format(MP4::CoverArt::JPEG) {}
Format format;
ByteVector data;
};
MP4::CoverArt::CoverArt(Format format, const ByteVector &data)
{
d = new CoverArtPrivate;
d->format = format;
d->data = data;
}
MP4::CoverArt::CoverArt(const CoverArt &item) : d(item.d)
{
d->ref();
}
MP4::CoverArt &
MP4::CoverArt::operator=(const CoverArt &item)
{
if(d->deref()) {
delete d;
}
d = item.d;
d->ref();
return *this;
}
MP4::CoverArt::~CoverArt()
{
if(d->deref()) {
delete d;
}
}
MP4::CoverArt::Format
MP4::CoverArt::format() const
{
return d->format;
}
ByteVector
MP4::CoverArt::data() const
{
return d->data;
}

74
taglib/mp4/mp4coverart.h Normal file
View File

@@ -0,0 +1,74 @@
/**************************************************************************
copyright : (C) 2009 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_MP4COVERART_H
#define TAGLIB_MP4COVERART_H
#include "tlist.h"
#include "tbytevector.h"
#include "taglib_export.h"
#include "mp4atom.h"
namespace TagLib {
namespace MP4 {
class TAGLIB_EXPORT CoverArt
{
public:
/*!
* This describes the image type.
*/
enum Format {
JPEG = TypeJPEG,
PNG = TypePNG,
BMP = TypeBMP,
GIF = TypeGIF
};
CoverArt(Format format, const ByteVector &data);
~CoverArt();
CoverArt(const CoverArt &item);
CoverArt &operator=(const CoverArt &item);
//! Format of the image
Format format() const;
//! The image data
ByteVector data() const;
private:
class CoverArtPrivate;
CoverArtPrivate *d;
};
typedef List<CoverArt> CoverArtList;
}
}
#endif

149
taglib/mp4/mp4file.cpp Normal file
View File

@@ -0,0 +1,149 @@
/**************************************************************************
copyright : (C) 2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tdebug.h>
#include <tstring.h>
#include "mp4atom.h"
#include "mp4tag.h"
#include "mp4file.h"
using namespace TagLib;
class MP4::File::FilePrivate
{
public:
FilePrivate() : tag(0), atoms(0), properties(0)
{
}
~FilePrivate()
{
if(atoms) {
delete atoms;
atoms = 0;
}
if(tag) {
delete tag;
tag = 0;
}
if(properties) {
delete properties;
properties = 0;
}
}
MP4::Tag *tag;
MP4::Atoms *atoms;
MP4::Properties *properties;
};
MP4::File::File(FileName file, bool readProperties, AudioProperties::ReadStyle audioPropertiesStyle)
: TagLib::File(file)
{
d = new FilePrivate;
read(readProperties, audioPropertiesStyle);
}
MP4::File::File(IOStream *stream, bool readProperties, AudioProperties::ReadStyle audioPropertiesStyle)
: TagLib::File(stream)
{
d = new FilePrivate;
read(readProperties, audioPropertiesStyle);
}
MP4::File::~File()
{
delete d;
}
MP4::Tag *
MP4::File::tag() const
{
return d->tag;
}
MP4::Properties *
MP4::File::audioProperties() const
{
return d->properties;
}
bool
MP4::File::checkValid(const MP4::AtomList &list)
{
for(uint i = 0; i < list.size(); i++) {
if(list[i]->length == 0)
return false;
if(!checkValid(list[i]->children))
return false;
}
return true;
}
void
MP4::File::read(bool readProperties, Properties::ReadStyle audioPropertiesStyle)
{
if(!isValid())
return;
d->atoms = new Atoms(this);
if (!checkValid(d->atoms->atoms)) {
setValid(false);
return;
}
// must have a moov atom, otherwise consider it invalid
MP4::Atom *moov = d->atoms->find("moov");
if(!moov) {
setValid(false);
return;
}
d->tag = new Tag(this, d->atoms);
if(readProperties) {
d->properties = new Properties(this, d->atoms, audioPropertiesStyle);
}
}
bool
MP4::File::save()
{
if(readOnly()) {
debug("MP4::File::save() -- File is read only.");
return false;
}
if(!isValid()) {
debug("MP4::File::save() -- Trying to save invalid file.");
return false;
}
return d->tag->save();
}

116
taglib/mp4/mp4file.h Normal file
View File

@@ -0,0 +1,116 @@
/**************************************************************************
copyright : (C) 2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_MP4FILE_H
#define TAGLIB_MP4FILE_H
#include "tag.h"
#include "tfile.h"
#include "taglib_export.h"
#include "mp4properties.h"
#include "mp4tag.h"
namespace TagLib {
//! An implementation of MP4 (AAC, ALAC, ...) metadata
namespace MP4 {
class Atoms;
/*!
* This implements and provides an interface for MP4 files to the
* TagLib::Tag and TagLib::AudioProperties interfaces by way of implementing
* the abstract TagLib::File API as well as providing some additional
* information specific to MP4 files.
*/
class TAGLIB_EXPORT File : public TagLib::File
{
public:
/*!
* Contructs a MP4 file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored.
*/
File(FileName file, bool readProperties = true, Properties::ReadStyle audioPropertiesStyle = Properties::Average);
/*!
* Contructs a MP4 file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
* \note In the current implementation, both \a readProperties and
* \a propertiesStyle are ignored.
*
* \note TagLib will *not* take ownership of the stream, the caller is
* responsible for deleting it after the File object.
*/
File(IOStream *stream, bool readProperties = true, Properties::ReadStyle audioPropertiesStyle = Properties::Average);
/*!
* Destroys this instance of the File.
*/
virtual ~File();
/*!
* Returns a pointer to the MP4 tag of the file.
*
* MP4::Tag implements the tag interface, so this serves as the
* reimplementation of TagLib::File::tag().
*
* \note The Tag <b>is still</b> owned by the MP4::File and should not be
* deleted by the user. It will be deleted when the file (object) is
* destroyed.
*/
Tag *tag() const;
/*!
* Returns the MP4 audio properties for this file.
*/
Properties *audioProperties() const;
/*!
* Save the file.
*
* This returns true if the save was successful.
*/
bool save();
private:
void read(bool readProperties, Properties::ReadStyle audioPropertiesStyle);
bool checkValid(const MP4::AtomList &list);
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

209
taglib/mp4/mp4item.cpp Normal file
View File

@@ -0,0 +1,209 @@
/**************************************************************************
copyright : (C) 2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <taglib.h>
#include <tdebug.h>
#include "mp4item.h"
using namespace TagLib;
class MP4::Item::ItemPrivate : public RefCounter
{
public:
ItemPrivate() : RefCounter(), valid(true), atomDataType(TypeUndefined) {}
bool valid;
AtomDataType atomDataType;
union {
bool m_bool;
int m_int;
IntPair m_intPair;
uchar m_byte;
uint m_uint;
long long m_longlong;
};
StringList m_stringList;
ByteVectorList m_byteVectorList;
MP4::CoverArtList m_coverArtList;
};
MP4::Item::Item()
{
d = new ItemPrivate;
d->valid = false;
}
MP4::Item::Item(const Item &item) : d(item.d)
{
d->ref();
}
MP4::Item &
MP4::Item::operator=(const Item &item)
{
if(d->deref()) {
delete d;
}
d = item.d;
d->ref();
return *this;
}
MP4::Item::~Item()
{
if(d->deref()) {
delete d;
}
}
MP4::Item::Item(bool value)
{
d = new ItemPrivate;
d->m_bool = value;
}
MP4::Item::Item(int value)
{
d = new ItemPrivate;
d->m_int = value;
}
MP4::Item::Item(uchar value)
{
d = new ItemPrivate;
d->m_byte = value;
}
MP4::Item::Item(uint value)
{
d = new ItemPrivate;
d->m_uint = value;
}
MP4::Item::Item(long long value)
{
d = new ItemPrivate;
d->m_longlong = value;
}
MP4::Item::Item(int value1, int value2)
{
d = new ItemPrivate;
d->m_intPair.first = value1;
d->m_intPair.second = value2;
}
MP4::Item::Item(const ByteVectorList &value)
{
d = new ItemPrivate;
d->m_byteVectorList = value;
}
MP4::Item::Item(const StringList &value)
{
d = new ItemPrivate;
d->m_stringList = value;
}
MP4::Item::Item(const MP4::CoverArtList &value)
{
d = new ItemPrivate;
d->m_coverArtList = value;
}
void MP4::Item::setAtomDataType(MP4::AtomDataType type)
{
d->atomDataType = type;
}
MP4::AtomDataType MP4::Item::atomDataType() const
{
return d->atomDataType;
}
bool
MP4::Item::toBool() const
{
return d->m_bool;
}
int
MP4::Item::toInt() const
{
return d->m_int;
}
uchar
MP4::Item::toByte() const
{
return d->m_byte;
}
TagLib::uint
MP4::Item::toUInt() const
{
return d->m_uint;
}
long long
MP4::Item::toLongLong() const
{
return d->m_longlong;
}
MP4::Item::IntPair
MP4::Item::toIntPair() const
{
return d->m_intPair;
}
StringList
MP4::Item::toStringList() const
{
return d->m_stringList;
}
ByteVectorList
MP4::Item::toByteVectorList() const
{
return d->m_byteVectorList;
}
MP4::CoverArtList
MP4::Item::toCoverArtList() const
{
return d->m_coverArtList;
}
bool
MP4::Item::isValid() const
{
return d->valid;
}

83
taglib/mp4/mp4item.h Normal file
View File

@@ -0,0 +1,83 @@
/**************************************************************************
copyright : (C) 2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_MP4ITEM_H
#define TAGLIB_MP4ITEM_H
#include "tstringlist.h"
#include "mp4coverart.h"
#include "taglib_export.h"
namespace TagLib {
namespace MP4 {
class TAGLIB_EXPORT Item
{
public:
struct IntPair {
int first, second;
};
Item();
Item(const Item &item);
Item &operator=(const Item &item);
~Item();
Item(int value);
Item(uchar value);
Item(uint value);
Item(long long value);
Item(bool value);
Item(int first, int second);
Item(const StringList &value);
Item(const ByteVectorList &value);
Item(const CoverArtList &value);
void setAtomDataType(AtomDataType type);
AtomDataType atomDataType() const;
int toInt() const;
uchar toByte() const;
uint toUInt() const;
long long toLongLong() const;
bool toBool() const;
IntPair toIntPair() const;
StringList toStringList() const;
ByteVectorList toByteVectorList() const;
CoverArtList toCoverArtList() const;
bool isValid() const;
private:
class ItemPrivate;
ItemPrivate *d;
};
}
}
#endif

View File

@@ -0,0 +1,195 @@
/**************************************************************************
copyright : (C) 2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tdebug.h>
#include <tstring.h>
#include "mp4file.h"
#include "mp4atom.h"
#include "mp4properties.h"
using namespace TagLib;
class MP4::Properties::PropertiesPrivate
{
public:
PropertiesPrivate() : length(0), bitrate(0), sampleRate(0), channels(0), bitsPerSample(0), encrypted(false) {}
int length;
int bitrate;
int sampleRate;
int channels;
int bitsPerSample;
bool encrypted;
};
MP4::Properties::Properties(File *file, MP4::Atoms *atoms, ReadStyle style)
: AudioProperties(style)
{
d = new PropertiesPrivate;
MP4::Atom *moov = atoms->find("moov");
if(!moov) {
debug("MP4: Atom 'moov' not found");
return;
}
MP4::Atom *trak = 0;
ByteVector data;
MP4::AtomList trakList = moov->findall("trak");
for (unsigned int i = 0; i < trakList.size(); i++) {
trak = trakList[i];
MP4::Atom *hdlr = trak->find("mdia", "hdlr");
if(!hdlr) {
debug("MP4: Atom 'trak.mdia.hdlr' not found");
return;
}
file->seek(hdlr->offset);
data = file->readBlock(hdlr->length);
if(data.mid(16, 4) == "soun") {
break;
}
trak = 0;
}
if (!trak) {
debug("MP4: No audio tracks");
return;
}
MP4::Atom *mdhd = trak->find("mdia", "mdhd");
if(!mdhd) {
debug("MP4: Atom 'trak.mdia.mdhd' not found");
return;
}
file->seek(mdhd->offset);
data = file->readBlock(mdhd->length);
uint version = data[8];
if(version == 1) {
if (data.size() < 36 + 8) {
debug("MP4: Atom 'trak.mdia.mdhd' is smaller than expected");
return;
}
long long unit = data.mid(28, 8).toLongLong();
long long length = data.mid(36, 8).toLongLong();
d->length = unit ? int(length / unit) : 0;
}
else {
if (data.size() < 24 + 4) {
debug("MP4: Atom 'trak.mdia.mdhd' is smaller than expected");
return;
}
unsigned int unit = data.mid(20, 4).toUInt();
unsigned int length = data.mid(24, 4).toUInt();
d->length = unit ? length / unit : 0;
}
MP4::Atom *atom = trak->find("mdia", "minf", "stbl", "stsd");
if(!atom) {
return;
}
file->seek(atom->offset);
data = file->readBlock(atom->length);
if(data.mid(20, 4) == "mp4a") {
d->channels = data.mid(40, 2).toShort();
d->bitsPerSample = data.mid(42, 2).toShort();
d->sampleRate = data.mid(46, 4).toUInt();
if(data.mid(56, 4) == "esds" && data[64] == 0x03) {
long pos = 65;
if(data.mid(pos, 3) == "\x80\x80\x80") {
pos += 3;
}
pos += 4;
if(data[pos] == 0x04) {
pos += 1;
if(data.mid(pos, 3) == "\x80\x80\x80") {
pos += 3;
}
pos += 10;
d->bitrate = (data.mid(pos, 4).toUInt() + 500) / 1000;
}
}
}
else if (data.mid(20, 4) == "alac") {
if (atom->length == 88 && data.mid(56, 4) == "alac") {
d->bitsPerSample = data.at(69);
d->channels = data.at(73);
d->bitrate = data.mid(80, 4).toUInt() / 1000;
d->sampleRate = data.mid(84, 4).toUInt();
}
}
MP4::Atom *drms = atom->find("drms");
if(drms) {
d->encrypted = true;
}
}
MP4::Properties::~Properties()
{
delete d;
}
int
MP4::Properties::channels() const
{
return d->channels;
}
int
MP4::Properties::sampleRate() const
{
return d->sampleRate;
}
int
MP4::Properties::length() const
{
return d->length;
}
int
MP4::Properties::bitrate() const
{
return d->bitrate;
}
int
MP4::Properties::bitsPerSample() const
{
return d->bitsPerSample;
}
bool
MP4::Properties::isEncrypted() const
{
return d->encrypted;
}

View File

@@ -0,0 +1,62 @@
/**************************************************************************
copyright : (C) 2007 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_MP4PROPERTIES_H
#define TAGLIB_MP4PROPERTIES_H
#include "taglib_export.h"
#include "audioproperties.h"
namespace TagLib {
namespace MP4 {
class Atoms;
class File;
//! An implementation of MP4 audio properties
class TAGLIB_EXPORT Properties : public AudioProperties
{
public:
Properties(File *file, Atoms *atoms, ReadStyle style = Average);
virtual ~Properties();
virtual int length() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
virtual int bitsPerSample() const;
bool isEncrypted() const;
private:
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

758
taglib/mp4/mp4tag.cpp Normal file
View File

@@ -0,0 +1,758 @@
/**************************************************************************
copyright : (C) 2007,2011 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <tdebug.h>
#include <tstring.h>
#include "mp4atom.h"
#include "mp4tag.h"
#include "id3v1genres.h"
using namespace TagLib;
class MP4::Tag::TagPrivate
{
public:
TagPrivate() : file(0), atoms(0) {}
~TagPrivate() {}
TagLib::File *file;
Atoms *atoms;
ItemListMap items;
};
MP4::Tag::Tag()
{
d = new TagPrivate;
}
MP4::Tag::Tag(TagLib::File *file, MP4::Atoms *atoms)
{
d = new TagPrivate;
d->file = file;
d->atoms = atoms;
MP4::Atom *ilst = atoms->find("moov", "udta", "meta", "ilst");
if(!ilst) {
//debug("Atom moov.udta.meta.ilst not found.");
return;
}
for(unsigned int i = 0; i < ilst->children.size(); i++) {
MP4::Atom *atom = ilst->children[i];
file->seek(atom->offset + 8);
if(atom->name == "----") {
parseFreeForm(atom, file);
}
else if(atom->name == "trkn" || atom->name == "disk") {
parseIntPair(atom, file);
}
else if(atom->name == "cpil" || atom->name == "pgap" || atom->name == "pcst" ||
atom->name == "hdvd") {
parseBool(atom, file);
}
else if(atom->name == "tmpo") {
parseInt(atom, file);
}
else if(atom->name == "tvsn" || atom->name == "tves" || atom->name == "cnID" ||
atom->name == "sfID" || atom->name == "atID" || atom->name == "geID") {
parseUInt(atom, file);
}
else if(atom->name == "plID") {
parseLongLong(atom, file);
}
else if(atom->name == "stik" || atom->name == "rtng" || atom->name == "akID") {
parseByte(atom, file);
}
else if(atom->name == "gnre") {
parseGnre(atom, file);
}
else if(atom->name == "covr") {
parseCovr(atom, file);
}
else {
parseText(atom, file);
}
}
}
MP4::Tag::~Tag()
{
delete d;
}
MP4::AtomDataList
MP4::Tag::parseData2(MP4::Atom *atom, TagLib::File *file, int expectedFlags, bool freeForm)
{
AtomDataList result;
ByteVector data = file->readBlock(atom->length - 8);
int i = 0;
unsigned int pos = 0;
while(pos < data.size()) {
int length = data.mid(pos, 4).toUInt();
ByteVector name = data.mid(pos + 4, 4);
int flags = data.mid(pos + 8, 4).toUInt();
if(freeForm && i < 2) {
if(i == 0 && name != "mean") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"mean\"");
return result;
}
else if(i == 1 && name != "name") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"name\"");
return result;
}
result.append(AtomData(AtomDataType(flags), data.mid(pos + 12, length - 12)));
}
else {
if(name != "data") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\"");
return result;
}
if(expectedFlags == -1 || flags == expectedFlags) {
result.append(AtomData(AtomDataType(flags), data.mid(pos + 16, length - 16)));
}
}
pos += length;
i++;
}
return result;
}
ByteVectorList
MP4::Tag::parseData(MP4::Atom *atom, TagLib::File *file, int expectedFlags, bool freeForm)
{
AtomDataList data = parseData2(atom, file, expectedFlags, freeForm);
ByteVectorList result;
for(uint i = 0; i < data.size(); i++) {
result.append(data[i].data);
}
return result;
}
void
MP4::Tag::parseInt(MP4::Atom *atom, TagLib::File *file)
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
d->items.insert(atom->name, (int)data[0].toShort());
}
}
void
MP4::Tag::parseUInt(MP4::Atom *atom, TagLib::File *file)
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
d->items.insert(atom->name, data[0].toUInt());
}
}
void
MP4::Tag::parseLongLong(MP4::Atom *atom, TagLib::File *file)
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
d->items.insert(atom->name, data[0].toLongLong());
}
}
void
MP4::Tag::parseByte(MP4::Atom *atom, TagLib::File *file)
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
d->items.insert(atom->name, (uchar)data[0].at(0));
}
}
void
MP4::Tag::parseGnre(MP4::Atom *atom, TagLib::File *file)
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
int idx = (int)data[0].toShort();
if(!d->items.contains("\251gen") && idx > 0) {
d->items.insert("\251gen", StringList(ID3v1::genre(idx - 1)));
}
}
}
void
MP4::Tag::parseIntPair(MP4::Atom *atom, TagLib::File *file)
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
int a = data[0].mid(2, 2).toShort();
int b = data[0].mid(4, 2).toShort();
d->items.insert(atom->name, MP4::Item(a, b));
}
}
void
MP4::Tag::parseBool(MP4::Atom *atom, TagLib::File *file)
{
ByteVectorList data = parseData(atom, file);
if(data.size()) {
bool value = data[0].size() ? data[0][0] != '\0' : false;
d->items.insert(atom->name, value);
}
}
void
MP4::Tag::parseText(MP4::Atom *atom, TagLib::File *file, int expectedFlags)
{
ByteVectorList data = parseData(atom, file, expectedFlags);
if(data.size()) {
StringList value;
for(unsigned int i = 0; i < data.size(); i++) {
value.append(String(data[i], String::UTF8));
}
d->items.insert(atom->name, value);
}
}
void
MP4::Tag::parseFreeForm(MP4::Atom *atom, TagLib::File *file)
{
AtomDataList data = parseData2(atom, file, -1, true);
if(data.size() > 2) {
String name = "----:" + String(data[0].data, String::UTF8) + ':' + String(data[1].data, String::UTF8);
AtomDataType type = data[2].type;
for(uint i = 2; i < data.size(); i++) {
if(data[i].type != type) {
debug("MP4: We currently don't support values with multiple types");
break;
}
}
if(type == TypeUTF8) {
StringList value;
for(uint i = 2; i < data.size(); i++) {
value.append(String(data[i].data, String::UTF8));
}
Item item(value);
item.setAtomDataType(type);
d->items.insert(name, item);
}
else {
ByteVectorList value;
for(uint i = 2; i < data.size(); i++) {
value.append(data[i].data);
}
Item item(value);
item.setAtomDataType(type);
d->items.insert(name, item);
}
}
}
void
MP4::Tag::parseCovr(MP4::Atom *atom, TagLib::File *file)
{
MP4::CoverArtList value;
ByteVector data = file->readBlock(atom->length - 8);
unsigned int pos = 0;
while(pos < data.size()) {
int length = data.mid(pos, 4).toUInt();
ByteVector name = data.mid(pos + 4, 4);
int flags = data.mid(pos + 8, 4).toUInt();
if(name != "data") {
debug("MP4: Unexpected atom \"" + name + "\", expecting \"data\"");
break;
}
if(flags == TypeJPEG || flags == TypePNG || flags == TypeBMP || flags == TypeGIF) {
value.append(MP4::CoverArt(MP4::CoverArt::Format(flags),
data.mid(pos + 16, length - 16)));
}
pos += length;
}
if(value.size() > 0)
d->items.insert(atom->name, value);
}
ByteVector
MP4::Tag::padIlst(const ByteVector &data, int length)
{
if (length == -1) {
length = ((data.size() + 1023) & ~1023) - data.size();
}
return renderAtom("free", ByteVector(length, '\1'));
}
ByteVector
MP4::Tag::renderAtom(const ByteVector &name, const ByteVector &data)
{
return ByteVector::fromUInt(data.size() + 8) + name + data;
}
ByteVector
MP4::Tag::renderData(const ByteVector &name, int flags, const ByteVectorList &data)
{
ByteVector result;
for(unsigned int i = 0; i < data.size(); i++) {
result.append(renderAtom("data", ByteVector::fromUInt(flags) + ByteVector(4, '\0') + data[i]));
}
return renderAtom(name, result);
}
ByteVector
MP4::Tag::renderBool(const ByteVector &name, MP4::Item &item)
{
ByteVectorList data;
data.append(ByteVector(1, item.toBool() ? '\1' : '\0'));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderInt(const ByteVector &name, MP4::Item &item)
{
ByteVectorList data;
data.append(ByteVector::fromShort(item.toInt()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderUInt(const ByteVector &name, MP4::Item &item)
{
ByteVectorList data;
data.append(ByteVector::fromUInt(item.toUInt()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderLongLong(const ByteVector &name, MP4::Item &item)
{
ByteVectorList data;
data.append(ByteVector::fromLongLong(item.toLongLong()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderByte(const ByteVector &name, MP4::Item &item)
{
ByteVectorList data;
data.append(ByteVector(1, item.toByte()));
return renderData(name, TypeInteger, data);
}
ByteVector
MP4::Tag::renderIntPair(const ByteVector &name, MP4::Item &item)
{
ByteVectorList data;
data.append(ByteVector(2, '\0') +
ByteVector::fromShort(item.toIntPair().first) +
ByteVector::fromShort(item.toIntPair().second) +
ByteVector(2, '\0'));
return renderData(name, TypeImplicit, data);
}
ByteVector
MP4::Tag::renderIntPairNoTrailing(const ByteVector &name, MP4::Item &item)
{
ByteVectorList data;
data.append(ByteVector(2, '\0') +
ByteVector::fromShort(item.toIntPair().first) +
ByteVector::fromShort(item.toIntPair().second));
return renderData(name, TypeImplicit, data);
}
ByteVector
MP4::Tag::renderText(const ByteVector &name, MP4::Item &item, int flags)
{
ByteVectorList data;
StringList value = item.toStringList();
for(unsigned int i = 0; i < value.size(); i++) {
data.append(value[i].data(String::UTF8));
}
return renderData(name, flags, data);
}
ByteVector
MP4::Tag::renderCovr(const ByteVector &name, MP4::Item &item)
{
ByteVector data;
MP4::CoverArtList value = item.toCoverArtList();
for(unsigned int i = 0; i < value.size(); i++) {
data.append(renderAtom("data", ByteVector::fromUInt(value[i].format()) +
ByteVector(4, '\0') + value[i].data()));
}
return renderAtom(name, data);
}
ByteVector
MP4::Tag::renderFreeForm(const String &name, MP4::Item &item)
{
StringList header = StringList::split(name, ":");
if (header.size() != 3) {
debug("MP4: Invalid free-form item name \"" + name + "\"");
return ByteVector::null;
}
ByteVector data;
data.append(renderAtom("mean", ByteVector::fromUInt(0) + header[1].data(String::UTF8)));
data.append(renderAtom("name", ByteVector::fromUInt(0) + header[2].data(String::UTF8)));
AtomDataType type = item.atomDataType();
if(type == TypeUndefined) {
if(!item.toStringList().isEmpty()) {
type = TypeUTF8;
}
else {
type = TypeImplicit;
}
}
if(type == TypeUTF8) {
StringList value = item.toStringList();
for(unsigned int i = 0; i < value.size(); i++) {
data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + value[i].data(String::UTF8)));
}
}
else {
ByteVectorList value = item.toByteVectorList();
for(unsigned int i = 0; i < value.size(); i++) {
data.append(renderAtom("data", ByteVector::fromUInt(type) + ByteVector(4, '\0') + value[i]));
}
}
return renderAtom("----", data);
}
bool
MP4::Tag::save()
{
ByteVector data;
for(MP4::ItemListMap::Iterator i = d->items.begin(); i != d->items.end(); i++) {
const String name = i->first;
if(name.startsWith("----")) {
data.append(renderFreeForm(name, i->second));
}
else if(name == "trkn") {
data.append(renderIntPair(name.data(String::Latin1), i->second));
}
else if(name == "disk") {
data.append(renderIntPairNoTrailing(name.data(String::Latin1), i->second));
}
else if(name == "cpil" || name == "pgap" || name == "pcst" || name == "hdvd") {
data.append(renderBool(name.data(String::Latin1), i->second));
}
else if(name == "tmpo") {
data.append(renderInt(name.data(String::Latin1), i->second));
}
else if(name == "tvsn" || name == "tves" || name == "cnID" ||
name == "sfID" || name == "atID" || name == "geID") {
data.append(renderUInt(name.data(String::Latin1), i->second));
}
else if(name == "plID") {
data.append(renderLongLong(name.data(String::Latin1), i->second));
}
else if(name == "stik" || name == "rtng" || name == "akID") {
data.append(renderByte(name.data(String::Latin1), i->second));
}
else if(name == "covr") {
data.append(renderCovr(name.data(String::Latin1), i->second));
}
else if(name.size() == 4){
data.append(renderText(name.data(String::Latin1), i->second));
}
else {
debug("MP4: Unknown item name \"" + name + "\"");
}
}
data = renderAtom("ilst", data);
AtomList path = d->atoms->path("moov", "udta", "meta", "ilst");
if(path.size() == 4) {
saveExisting(data, path);
}
else {
saveNew(data);
}
return true;
}
void
MP4::Tag::updateParents(AtomList &path, long delta, int ignore)
{
for(unsigned int i = 0; i < path.size() - ignore; i++) {
d->file->seek(path[i]->offset);
long size = d->file->readBlock(4).toUInt();
// 64-bit
if (size == 1) {
d->file->seek(4, File::Current); // Skip name
long long longSize = d->file->readBlock(8).toLongLong();
// Seek the offset of the 64-bit size
d->file->seek(path[i]->offset + 8);
d->file->writeBlock(ByteVector::fromLongLong(longSize + delta));
}
// 32-bit
else {
d->file->seek(path[i]->offset);
d->file->writeBlock(ByteVector::fromUInt(size + delta));
}
}
}
void
MP4::Tag::updateOffsets(long delta, long offset)
{
MP4::Atom *moov = d->atoms->find("moov");
if(moov) {
MP4::AtomList stco = moov->findall("stco", true);
for(unsigned int i = 0; i < stco.size(); i++) {
MP4::Atom *atom = stco[i];
if(atom->offset > offset) {
atom->offset += delta;
}
d->file->seek(atom->offset + 12);
ByteVector data = d->file->readBlock(atom->length - 12);
unsigned int count = data.mid(0, 4).toUInt();
d->file->seek(atom->offset + 16);
int pos = 4;
while(count--) {
long o = data.mid(pos, 4).toUInt();
if(o > offset) {
o += delta;
}
d->file->writeBlock(ByteVector::fromUInt(o));
pos += 4;
}
}
MP4::AtomList co64 = moov->findall("co64", true);
for(unsigned int i = 0; i < co64.size(); i++) {
MP4::Atom *atom = co64[i];
if(atom->offset > offset) {
atom->offset += delta;
}
d->file->seek(atom->offset + 12);
ByteVector data = d->file->readBlock(atom->length - 12);
unsigned int count = data.mid(0, 4).toUInt();
d->file->seek(atom->offset + 16);
int pos = 4;
while(count--) {
long long o = data.mid(pos, 8).toLongLong();
if(o > offset) {
o += delta;
}
d->file->writeBlock(ByteVector::fromLongLong(o));
pos += 8;
}
}
}
MP4::Atom *moof = d->atoms->find("moof");
if(moof) {
MP4::AtomList tfhd = moof->findall("tfhd", true);
for(unsigned int i = 0; i < tfhd.size(); i++) {
MP4::Atom *atom = tfhd[i];
if(atom->offset > offset) {
atom->offset += delta;
}
d->file->seek(atom->offset + 9);
ByteVector data = d->file->readBlock(atom->offset - 9);
unsigned int flags = (ByteVector(1, '\0') + data.mid(0, 3)).toUInt();
if(flags & 1) {
long long o = data.mid(7, 8).toLongLong();
if(o > offset) {
o += delta;
}
d->file->seek(atom->offset + 16);
d->file->writeBlock(ByteVector::fromLongLong(o));
}
}
}
}
void
MP4::Tag::saveNew(ByteVector &data)
{
data = renderAtom("meta", TagLib::ByteVector(4, '\0') +
renderAtom("hdlr", TagLib::ByteVector(8, '\0') + TagLib::ByteVector("mdirappl") + TagLib::ByteVector(9, '\0')) +
data + padIlst(data));
AtomList path = d->atoms->path("moov", "udta");
if(path.size() != 2) {
path = d->atoms->path("moov");
data = renderAtom("udta", data);
}
long offset = path[path.size() - 1]->offset + 8;
d->file->insert(data, offset, 0);
updateParents(path, data.size());
updateOffsets(data.size(), offset);
}
void
MP4::Tag::saveExisting(ByteVector &data, AtomList &path)
{
MP4::Atom *ilst = path[path.size() - 1];
long offset = ilst->offset;
long length = ilst->length;
MP4::Atom *meta = path[path.size() - 2];
AtomList::Iterator index = meta->children.find(ilst);
// check if there is an atom before 'ilst', and possibly use it as padding
if(index != meta->children.begin()) {
AtomList::Iterator prevIndex = index;
prevIndex--;
MP4::Atom *prev = *prevIndex;
if(prev->name == "free") {
offset = prev->offset;
length += prev->length;
}
}
// check if there is an atom after 'ilst', and possibly use it as padding
AtomList::Iterator nextIndex = index;
nextIndex++;
if(nextIndex != meta->children.end()) {
MP4::Atom *next = *nextIndex;
if(next->name == "free") {
length += next->length;
}
}
long delta = data.size() - length;
if(delta > 0 || (delta < 0 && delta > -8)) {
data.append(padIlst(data));
delta = data.size() - length;
}
else if(delta < 0) {
data.append(padIlst(data, -delta - 8));
delta = 0;
}
d->file->insert(data, offset, length);
if(delta) {
updateParents(path, delta, 1);
updateOffsets(delta, offset);
}
}
String
MP4::Tag::title() const
{
if(d->items.contains("\251nam"))
return d->items["\251nam"].toStringList().toString(", ");
return String::null;
}
String
MP4::Tag::artist() const
{
if(d->items.contains("\251ART"))
return d->items["\251ART"].toStringList().toString(", ");
return String::null;
}
String
MP4::Tag::album() const
{
if(d->items.contains("\251alb"))
return d->items["\251alb"].toStringList().toString(", ");
return String::null;
}
String
MP4::Tag::comment() const
{
if(d->items.contains("\251cmt"))
return d->items["\251cmt"].toStringList().toString(", ");
return String::null;
}
String
MP4::Tag::genre() const
{
if(d->items.contains("\251gen"))
return d->items["\251gen"].toStringList().toString(", ");
return String::null;
}
unsigned int
MP4::Tag::year() const
{
if(d->items.contains("\251day"))
return d->items["\251day"].toStringList().toString().toInt();
return 0;
}
unsigned int
MP4::Tag::track() const
{
if(d->items.contains("trkn"))
return d->items["trkn"].toIntPair().first;
return 0;
}
void
MP4::Tag::setTitle(const String &value)
{
d->items["\251nam"] = StringList(value);
}
void
MP4::Tag::setArtist(const String &value)
{
d->items["\251ART"] = StringList(value);
}
void
MP4::Tag::setAlbum(const String &value)
{
d->items["\251alb"] = StringList(value);
}
void
MP4::Tag::setComment(const String &value)
{
d->items["\251cmt"] = StringList(value);
}
void
MP4::Tag::setGenre(const String &value)
{
d->items["\251gen"] = StringList(value);
}
void
MP4::Tag::setYear(uint value)
{
d->items["\251day"] = StringList(String::number(value));
}
void
MP4::Tag::setTrack(uint value)
{
d->items["trkn"] = MP4::Item(value, 0);
}
MP4::ItemListMap &
MP4::Tag::itemListMap()
{
return d->items;
}

112
taglib/mp4/mp4tag.h Normal file
View File

@@ -0,0 +1,112 @@
/**************************************************************************
copyright : (C) 2007,2011 by Lukáš Lalinský
email : lalinsky@gmail.com
**************************************************************************/
/***************************************************************************
* This library is free software; you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License version *
* 2.1 as published by the Free Software Foundation. *
* *
* This library is distributed in the hope that it will be useful, but *
* WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public *
* License along with this library; if not, write to the Free Software *
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
* 02110-1301 USA *
* *
* Alternatively, this file is available under the Mozilla Public *
* License Version 1.1. You may obtain a copy of the License at *
* http://www.mozilla.org/MPL/ *
***************************************************************************/
#ifndef TAGLIB_MP4TAG_H
#define TAGLIB_MP4TAG_H
#include "tag.h"
#include "tbytevectorlist.h"
#include "tfile.h"
#include "tmap.h"
#include "tstringlist.h"
#include "taglib_export.h"
#include "mp4atom.h"
#include "mp4item.h"
namespace TagLib {
namespace MP4 {
typedef TagLib::Map<String, Item> ItemListMap;
class TAGLIB_EXPORT Tag: public TagLib::Tag
{
public:
Tag();
Tag(TagLib::File *file, Atoms *atoms);
~Tag();
bool save();
String title() const;
String artist() const;
String album() const;
String comment() const;
String genre() const;
uint year() const;
uint track() const;
void setTitle(const String &value);
void setArtist(const String &value);
void setAlbum(const String &value);
void setComment(const String &value);
void setGenre(const String &value);
void setYear(uint value);
void setTrack(uint value);
ItemListMap &itemListMap();
private:
AtomDataList parseData2(Atom *atom, TagLib::File *file, int expectedFlags = -1, bool freeForm = false);
TagLib::ByteVectorList parseData(Atom *atom, TagLib::File *file, int expectedFlags = -1, bool freeForm = false);
void parseText(Atom *atom, TagLib::File *file, int expectedFlags = 1);
void parseFreeForm(Atom *atom, TagLib::File *file);
void parseInt(Atom *atom, TagLib::File *file);
void parseByte(Atom *atom, TagLib::File *file);
void parseUInt(Atom *atom, TagLib::File *file);
void parseLongLong(Atom *atom, TagLib::File *file);
void parseGnre(Atom *atom, TagLib::File *file);
void parseIntPair(Atom *atom, TagLib::File *file);
void parseBool(Atom *atom, TagLib::File *file);
void parseCovr(Atom *atom, TagLib::File *file);
TagLib::ByteVector padIlst(const ByteVector &data, int length = -1);
TagLib::ByteVector renderAtom(const ByteVector &name, const TagLib::ByteVector &data);
TagLib::ByteVector renderData(const ByteVector &name, int flags, const TagLib::ByteVectorList &data);
TagLib::ByteVector renderText(const ByteVector &name, Item &item, int flags = TypeUTF8);
TagLib::ByteVector renderFreeForm(const String &name, Item &item);
TagLib::ByteVector renderBool(const ByteVector &name, Item &item);
TagLib::ByteVector renderInt(const ByteVector &name, Item &item);
TagLib::ByteVector renderByte(const ByteVector &name, Item &item);
TagLib::ByteVector renderUInt(const ByteVector &name, Item &item);
TagLib::ByteVector renderLongLong(const ByteVector &name, Item &item);
TagLib::ByteVector renderIntPair(const ByteVector &name, Item &item);
TagLib::ByteVector renderIntPairNoTrailing(const ByteVector &name, Item &item);
TagLib::ByteVector renderCovr(const ByteVector &name, Item &item);
void updateParents(AtomList &path, long delta, int ignore = 0);
void updateOffsets(long delta, long offset);
void saveNew(TagLib::ByteVector &data);
void saveExisting(TagLib::ByteVector &data, AtomList &path);
class TagPrivate;
TagPrivate *d;
};
}
}
#endif

Some files were not shown because too many files have changed in this diff Show More