Updated TagLib
parent
697ed357a9
commit
97e94c0330
Binary file not shown.
|
@ -1,26 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>${EXECUTABLE_NAME}</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>${PRODUCT_NAME}</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>org.cogx.lib.taglib</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string></string>
|
||||
</dict>
|
||||
</plist>
|
File diff suppressed because it is too large
Load Diff
|
@ -1,11 +0,0 @@
|
|||
Scott Wheeler <wheeler@kde.org>
|
||||
Author, 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
|
||||
|
||||
Please send all patches and questions to taglib-devel@kde.org rather than to
|
||||
individual developers!
|
|
@ -1,481 +0,0 @@
|
|||
GNU LIBRARY GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, 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.]
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
GNU LIBRARY 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".
|
||||
|
||||
A "library" means a collection of software functions and/or data
|
||||
prepared so as to be conveniently linked with application programs
|
||||
(which use some of those functions and data) to form executables.
|
||||
|
||||
The "Library", below, refers to any such software library or work
|
||||
which has been distributed under these terms. A "work based on the
|
||||
Library" means either the Library or any derivative work under
|
||||
copyright law: that is to say, a work containing the Library or a
|
||||
portion of it, either verbatim or with modifications and/or translated
|
||||
straightforwardly into another language. (Hereinafter, translation is
|
||||
included without limitation in the term "modification".)
|
||||
|
||||
"Source code" for a work means the preferred form of the work for
|
||||
making modifications to it. For a library, complete source code means
|
||||
all the source code for all modules it contains, plus any associated
|
||||
interface definition files, plus the scripts used to control compilation
|
||||
and installation of the library.
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running a program using the Library is not restricted, and output from
|
||||
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
|
||||
appropriate copyright notice and disclaimer of warranty; keep intact
|
||||
all the notices that refer to this License and to the absence of any
|
||||
warranty; and distribute a copy of this License along with the
|
||||
Library.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy,
|
||||
and you may at your option offer warranty protection in exchange for a
|
||||
fee.
|
||||
|
||||
2. You may modify your copy or copies of the Library or any portion
|
||||
of it, thus forming a work based on the Library, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) The modified work must itself be a software library.
|
||||
|
||||
b) You must cause the files modified to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
c) You must cause the whole of the work to be licensed at no
|
||||
charge to all third parties under the terms of this License.
|
||||
|
||||
d) If a facility in the modified Library refers to a function or a
|
||||
table of data to be supplied by an application program that uses
|
||||
the facility, other than as an argument passed when the facility
|
||||
is invoked, then you must make a good faith effort to ensure that,
|
||||
in the event an application does not supply such function or
|
||||
table, the facility still operates, and performs whatever part of
|
||||
its purpose remains meaningful.
|
||||
|
||||
(For example, a function in a library to compute square roots has
|
||||
a purpose that is entirely well-defined independent of the
|
||||
application. Therefore, Subsection 2d requires that any
|
||||
application-supplied function or table used by this function must
|
||||
be optional: if the application does not supply it, the square
|
||||
root function must still compute square roots.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Library,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Library, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote
|
||||
it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Library.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Library
|
||||
with the Library (or with a work based on the Library) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may opt to apply the terms of the ordinary GNU General Public
|
||||
License instead of this License to a given copy of the Library. To do
|
||||
this, you must alter all the notices that refer to this License, so
|
||||
that they refer to the ordinary GNU General Public License, version 2,
|
||||
instead of to this License. (If a newer version than version 2 of the
|
||||
ordinary GNU General Public License has appeared, then you can specify
|
||||
that version instead if you wish.) Do not make any other change in
|
||||
these notices.
|
||||
|
||||
Once this change is made in a given copy, it is irreversible for
|
||||
that copy, so the ordinary GNU General Public License applies to all
|
||||
subsequent copies and derivative works made from that copy.
|
||||
|
||||
This option is useful when you wish to copy part of the code of
|
||||
the Library into a program that is not a library.
|
||||
|
||||
4. You may copy and distribute the Library (or a portion or
|
||||
derivative of it, under Section 2) in object code or executable form
|
||||
under the terms of Sections 1 and 2 above provided that you accompany
|
||||
it with the complete corresponding machine-readable source code, which
|
||||
must be distributed under the terms of Sections 1 and 2 above on a
|
||||
medium customarily used for software interchange.
|
||||
|
||||
If distribution of object code is made by offering access to copy
|
||||
from a designated place, then offering equivalent access to copy the
|
||||
source code from the same place satisfies the requirement to
|
||||
distribute the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
5. A program that contains no derivative of any portion of the
|
||||
Library, but is designed to work with the Library by being compiled or
|
||||
linked with it, is called a "work that uses the Library". Such a
|
||||
work, in isolation, is not a derivative work of the Library, and
|
||||
therefore falls outside the scope of this License.
|
||||
|
||||
However, linking a "work that uses the Library" with the Library
|
||||
creates an executable that is a derivative of the Library (because it
|
||||
contains portions of the Library), rather than a "work that uses the
|
||||
library". The executable is therefore covered by this License.
|
||||
Section 6 states terms for distribution of such executables.
|
||||
|
||||
When a "work that uses the Library" uses material from a header file
|
||||
that is part of the Library, the object code for the work may be a
|
||||
derivative work of the Library even though the source code is not.
|
||||
Whether this is true is especially significant if the work can be
|
||||
linked without the Library, or if the work is itself a library. The
|
||||
threshold for this to be true is not precisely defined by law.
|
||||
|
||||
If such an object file uses only numerical parameters, data
|
||||
structure layouts and accessors, and small macros and small inline
|
||||
functions (ten lines or less in length), then the use of the object
|
||||
file is unrestricted, regardless of whether it is legally a derivative
|
||||
work. (Executables containing this object code plus portions of the
|
||||
Library will still fall under Section 6.)
|
||||
|
||||
Otherwise, if the work is a derivative of the Library, you may
|
||||
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
|
||||
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
|
||||
modification of the work for the customer's own use and reverse
|
||||
engineering for debugging such modifications.
|
||||
|
||||
You must give prominent notice with each copy of the work that the
|
||||
Library is used in it and that the Library and its use are covered by
|
||||
this License. You must supply a copy of this License. If the work
|
||||
during execution displays copyright notices, you must include the
|
||||
copyright notice for the Library among them, as well as a reference
|
||||
directing the user to the copy of this License. Also, you must do one
|
||||
of these things:
|
||||
|
||||
a) Accompany the work with the complete corresponding
|
||||
machine-readable source code for the Library including whatever
|
||||
changes were used in the work (which must be distributed under
|
||||
Sections 1 and 2 above); and, if the work is an executable linked
|
||||
with the Library, with the complete machine-readable "work that
|
||||
uses the Library", as object code and/or source code, so that the
|
||||
user can modify the Library and then relink to produce a modified
|
||||
executable containing the modified Library. (It is understood
|
||||
that the user who changes the contents of definitions files in the
|
||||
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
|
||||
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
|
||||
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
|
||||
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
|
||||
components (compiler, kernel, and so on) of the operating system on
|
||||
which the executable runs, unless that component itself accompanies
|
||||
the executable.
|
||||
|
||||
It may happen that this requirement contradicts the license
|
||||
restrictions of other proprietary libraries that do not normally
|
||||
accompany the operating system. Such a contradiction means you cannot
|
||||
use both them and the Library together in an executable that you
|
||||
distribute.
|
||||
|
||||
7. You may place library facilities that are a work based on the
|
||||
Library side-by-side in a single library together with other library
|
||||
facilities not covered by this License, and distribute such a combined
|
||||
library, provided that the separate distribution of the work based on
|
||||
the Library and of the other library facilities is otherwise
|
||||
permitted, and provided that you do these two things:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work
|
||||
based on the Library, uncombined with any other library
|
||||
facilities. This must be distributed under the terms of the
|
||||
Sections above.
|
||||
|
||||
b) Give prominent notice with the combined library of the fact
|
||||
that part of it is a work based on the Library, and explaining
|
||||
where to find the accompanying uncombined form of the same work.
|
||||
|
||||
8. You may not copy, modify, sublicense, link with, or distribute
|
||||
the Library except as expressly provided under this License. Any
|
||||
attempt otherwise to copy, modify, sublicense, link with, or
|
||||
distribute the Library is void, and will automatically terminate your
|
||||
rights under this License. However, parties who have received copies,
|
||||
or rights, from you under this License will not have their licenses
|
||||
terminated so long as such parties remain in full compliance.
|
||||
|
||||
9. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Library or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Library (or any work based on the
|
||||
Library), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Library or works based on it.
|
||||
|
||||
10. Each time you redistribute the Library (or any work based on the
|
||||
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
|
||||
this License.
|
||||
|
||||
11. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Library at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Library by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Library.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under any
|
||||
particular circumstance, the balance of the section is intended to apply,
|
||||
and the section as a whole is intended to apply in other circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
12. If the distribution and/or use of the Library is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Library under this License may add
|
||||
an explicit geographical distribution limitation excluding those countries,
|
||||
so that distribution is permitted only in or among countries not thus
|
||||
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.
|
||||
Such new versions will be similar in spirit to the present version,
|
||||
but may differ in detail to address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Library
|
||||
specifies a version number of this License which applies to it and
|
||||
"any later version", you have the option of following the terms and
|
||||
conditions either of that version or of any later version published by
|
||||
the Free Software Foundation. If the Library does not specify a
|
||||
license version number, you may choose any version ever published by
|
||||
the Free Software Foundation.
|
||||
|
||||
14. If you wish to incorporate parts of the Library into other free
|
||||
programs whose distribution conditions are incompatible with these,
|
||||
write to the author to ask for permission. For software which is
|
||||
copyrighted by the Free Software Foundation, write to the Free
|
||||
Software Foundation; we sometimes make exceptions for this. Our
|
||||
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
|
||||
|
||||
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
|
||||
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
|
||||
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
|
||||
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
|
||||
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
|
||||
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
|
||||
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
|
||||
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
|
||||
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
|
||||
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
|
||||
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
|
||||
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
|
||||
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
|
||||
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
|
||||
|
||||
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
|
||||
everyone can redistribute and change. You can do so by permitting
|
||||
redistribution under these terms (or, alternatively, under the terms of the
|
||||
ordinary General Public License).
|
||||
|
||||
To apply these terms, attach the following notices to the library. It is
|
||||
safest to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least the
|
||||
"copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the library, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||
library `Frob' (a library for tweaking knobs) written by James Random Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
|
@ -1,470 +0,0 @@
|
|||
MOZILLA PUBLIC LICENSE
|
||||
Version 1.1
|
||||
|
||||
---------------
|
||||
|
||||
1. Definitions.
|
||||
|
||||
1.0.1. "Commercial Use" means distribution or otherwise making the
|
||||
Covered Code available to a third party.
|
||||
|
||||
1.1. "Contributor" means each entity that creates or contributes to
|
||||
the creation of Modifications.
|
||||
|
||||
1.2. "Contributor Version" means the combination of the Original
|
||||
Code, prior Modifications used by a Contributor, and the Modifications
|
||||
made by that particular Contributor.
|
||||
|
||||
1.3. "Covered Code" means the Original Code or Modifications or the
|
||||
combination of the Original Code and Modifications, in each case
|
||||
including portions thereof.
|
||||
|
||||
1.4. "Electronic Distribution Mechanism" means a mechanism generally
|
||||
accepted in the software development community for the electronic
|
||||
transfer of data.
|
||||
|
||||
1.5. "Executable" means Covered Code in any form other than Source
|
||||
Code.
|
||||
|
||||
1.6. "Initial Developer" means the individual or entity identified
|
||||
as the Initial Developer in the Source Code notice required by Exhibit
|
||||
A.
|
||||
|
||||
1.7. "Larger Work" means a work which combines Covered Code or
|
||||
portions thereof with code not governed by the terms of this License.
|
||||
|
||||
1.8. "License" means this document.
|
||||
|
||||
1.8.1. "Licensable" means having the right to grant, to the maximum
|
||||
extent possible, whether at the time of the initial grant or
|
||||
subsequently acquired, any and all of the rights conveyed herein.
|
||||
|
||||
1.9. "Modifications" means any addition to or deletion from the
|
||||
substance or structure of either the Original Code or any previous
|
||||
Modifications. When Covered Code is released as a series of files, a
|
||||
Modification is:
|
||||
A. Any addition to or deletion from the contents of a file
|
||||
containing Original Code or previous Modifications.
|
||||
|
||||
B. Any new file that contains any part of the Original Code or
|
||||
previous Modifications.
|
||||
|
||||
1.10. "Original Code" means Source Code of computer software code
|
||||
which is described in the Source Code notice required by Exhibit A as
|
||||
Original Code, and which, at the time of its release under this
|
||||
License is not already Covered Code governed by this License.
|
||||
|
||||
1.10.1. "Patent Claims" means any patent claim(s), now owned or
|
||||
hereafter acquired, including without limitation, method, process,
|
||||
and apparatus claims, in any patent Licensable by grantor.
|
||||
|
||||
1.11. "Source Code" means the preferred form of the Covered Code for
|
||||
making modifications to it, including all modules it contains, plus
|
||||
any associated interface definition files, scripts used to control
|
||||
compilation and installation of an Executable, or source code
|
||||
differential comparisons against either the Original Code or another
|
||||
well known, available Covered Code of the Contributor's choice. The
|
||||
Source Code can be in a compressed or archival form, provided the
|
||||
appropriate decompression or de-archiving software is widely available
|
||||
for no charge.
|
||||
|
||||
1.12. "You" (or "Your") means an individual or a legal entity
|
||||
exercising rights under, and complying with all of the terms of, this
|
||||
License or a future version of this License issued under Section 6.1.
|
||||
For legal entities, "You" includes any entity which controls, is
|
||||
controlled by, or is under common control with You. For purposes of
|
||||
this definition, "control" means (a) the power, direct or indirect,
|
||||
to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (b) ownership of more than fifty percent
|
||||
(50%) of the outstanding shares or beneficial ownership of such
|
||||
entity.
|
||||
|
||||
2. Source Code License.
|
||||
|
||||
2.1. The Initial Developer Grant.
|
||||
The Initial Developer hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license, subject to third party intellectual property
|
||||
claims:
|
||||
(a) under intellectual property rights (other than patent or
|
||||
trademark) Licensable by Initial Developer to use, reproduce,
|
||||
modify, display, perform, sublicense and distribute the Original
|
||||
Code (or portions thereof) with or without Modifications, and/or
|
||||
as part of a Larger Work; and
|
||||
|
||||
(b) under Patents Claims infringed by the making, using or
|
||||
selling of Original Code, to make, have made, use, practice,
|
||||
sell, and offer for sale, and/or otherwise dispose of the
|
||||
Original Code (or portions thereof).
|
||||
|
||||
(c) the licenses granted in this Section 2.1(a) and (b) are
|
||||
effective on the date Initial Developer first distributes
|
||||
Original Code under the terms of this License.
|
||||
|
||||
(d) Notwithstanding Section 2.1(b) above, no patent license is
|
||||
granted: 1) for code that You delete from the Original Code; 2)
|
||||
separate from the Original Code; or 3) for infringements caused
|
||||
by: i) the modification of the Original Code or ii) the
|
||||
combination of the Original Code with other software or devices.
|
||||
|
||||
2.2. Contributor Grant.
|
||||
Subject to third party intellectual property claims, each Contributor
|
||||
hereby grants You a world-wide, royalty-free, non-exclusive license
|
||||
|
||||
(a) under intellectual property rights (other than patent or
|
||||
trademark) Licensable by Contributor, to use, reproduce, modify,
|
||||
display, perform, sublicense and distribute the Modifications
|
||||
created by such Contributor (or portions thereof) either on an
|
||||
unmodified basis, with other Modifications, as Covered Code
|
||||
and/or as part of a Larger Work; and
|
||||
|
||||
(b) under Patent Claims infringed by the making, using, or
|
||||
selling of Modifications made by that Contributor either alone
|
||||
and/or in combination with its Contributor Version (or portions
|
||||
of such combination), to make, use, sell, offer for sale, have
|
||||
made, and/or otherwise dispose of: 1) Modifications made by that
|
||||
Contributor (or portions thereof); and 2) the combination of
|
||||
Modifications made by that Contributor with its Contributor
|
||||
Version (or portions of such combination).
|
||||
|
||||
(c) the licenses granted in Sections 2.2(a) and 2.2(b) are
|
||||
effective on the date Contributor first makes Commercial Use of
|
||||
the Covered Code.
|
||||
|
||||
(d) Notwithstanding Section 2.2(b) above, no patent license is
|
||||
granted: 1) for any code that Contributor has deleted from the
|
||||
Contributor Version; 2) separate from the Contributor Version;
|
||||
3) for infringements caused by: i) third party modifications of
|
||||
Contributor Version or ii) the combination of Modifications made
|
||||
by that Contributor with other software (except as part of the
|
||||
Contributor Version) or other devices; or 4) under Patent Claims
|
||||
infringed by Covered Code in the absence of Modifications made by
|
||||
that Contributor.
|
||||
|
||||
3. Distribution Obligations.
|
||||
|
||||
3.1. Application of License.
|
||||
The Modifications which You create or to which You contribute are
|
||||
governed by the terms of this License, including without limitation
|
||||
Section 2.2. The Source Code version of Covered Code may be
|
||||
distributed only under the terms of this License or a future version
|
||||
of this License released under Section 6.1, and You must include a
|
||||
copy of this License with every copy of the Source Code You
|
||||
distribute. You may not offer or impose any terms on any Source Code
|
||||
version that alters or restricts the applicable version of this
|
||||
License or the recipients' rights hereunder. However, You may include
|
||||
an additional document offering the additional rights described in
|
||||
Section 3.5.
|
||||
|
||||
3.2. Availability of Source Code.
|
||||
Any Modification which You create or to which You contribute must be
|
||||
made available in Source Code form under the terms of this License
|
||||
either on the same media as an Executable version or via an accepted
|
||||
Electronic Distribution Mechanism to anyone to whom you made an
|
||||
Executable version available; and if made available via Electronic
|
||||
Distribution Mechanism, must remain available for at least twelve (12)
|
||||
months after the date it initially became available, or at least six
|
||||
(6) months after a subsequent version of that particular Modification
|
||||
has been made available to such recipients. You are responsible for
|
||||
ensuring that the Source Code version remains available even if the
|
||||
Electronic Distribution Mechanism is maintained by a third party.
|
||||
|
||||
3.3. Description of Modifications.
|
||||
You must cause all Covered Code to which You contribute to contain a
|
||||
file documenting the changes You made to create that Covered Code and
|
||||
the date of any change. You must include a prominent statement that
|
||||
the Modification is derived, directly or indirectly, from Original
|
||||
Code provided by the Initial Developer and including the name of the
|
||||
Initial Developer in (a) the Source Code, and (b) in any notice in an
|
||||
Executable version or related documentation in which You describe the
|
||||
origin or ownership of the Covered Code.
|
||||
|
||||
3.4. Intellectual Property Matters
|
||||
(a) Third Party Claims.
|
||||
If Contributor has knowledge that a license under a third party's
|
||||
intellectual property rights is required to exercise the rights
|
||||
granted by such Contributor under Sections 2.1 or 2.2,
|
||||
Contributor must include a text file with the Source Code
|
||||
distribution titled "LEGAL" which describes the claim and the
|
||||
party making the claim in sufficient detail that a recipient will
|
||||
know whom to contact. If Contributor obtains such knowledge after
|
||||
the Modification is made available as described in Section 3.2,
|
||||
Contributor shall promptly modify the LEGAL file in all copies
|
||||
Contributor makes available thereafter and shall take other steps
|
||||
(such as notifying appropriate mailing lists or newsgroups)
|
||||
reasonably calculated to inform those who received the Covered
|
||||
Code that new knowledge has been obtained.
|
||||
|
||||
(b) Contributor APIs.
|
||||
If Contributor's Modifications include an application programming
|
||||
interface and Contributor has knowledge of patent licenses which
|
||||
are reasonably necessary to implement that API, Contributor must
|
||||
also include this information in the LEGAL file.
|
||||
|
||||
(c) Representations.
|
||||
Contributor represents that, except as disclosed pursuant to
|
||||
Section 3.4(a) above, Contributor believes that Contributor's
|
||||
Modifications are Contributor's original creation(s) and/or
|
||||
Contributor has sufficient rights to grant the rights conveyed by
|
||||
this License.
|
||||
|
||||
3.5. Required Notices.
|
||||
You must duplicate the notice in Exhibit A in each file of the Source
|
||||
Code. If it is not possible to put such notice in a particular Source
|
||||
Code file due to its structure, then You must include such notice in a
|
||||
location (such as a relevant directory) where a user would be likely
|
||||
to look for such a notice. If You created one or more Modification(s)
|
||||
You may add your name as a Contributor to the notice described in
|
||||
Exhibit A. You must also duplicate this License in any documentation
|
||||
for the Source Code where You describe recipients' rights or ownership
|
||||
rights relating to Covered Code. You may choose to offer, and to
|
||||
charge a fee for, warranty, support, indemnity or liability
|
||||
obligations to one or more recipients of Covered Code. However, You
|
||||
may do so only on Your own behalf, and not on behalf of the Initial
|
||||
Developer or any Contributor. You must make it absolutely clear than
|
||||
any such warranty, support, indemnity or liability obligation is
|
||||
offered by You alone, and You hereby agree to indemnify the Initial
|
||||
Developer and every Contributor for any liability incurred by the
|
||||
Initial Developer or such Contributor as a result of warranty,
|
||||
support, indemnity or liability terms You offer.
|
||||
|
||||
3.6. Distribution of Executable Versions.
|
||||
You may distribute Covered Code in Executable form only if the
|
||||
requirements of Section 3.1-3.5 have been met for that Covered Code,
|
||||
and if You include a notice stating that the Source Code version of
|
||||
the Covered Code is available under the terms of this License,
|
||||
including a description of how and where You have fulfilled the
|
||||
obligations of Section 3.2. The notice must be conspicuously included
|
||||
in any notice in an Executable version, related documentation or
|
||||
collateral in which You describe recipients' rights relating to the
|
||||
Covered Code. You may distribute the Executable version of Covered
|
||||
Code or ownership rights under a license of Your choice, which may
|
||||
contain terms different from this License, provided that You are in
|
||||
compliance with the terms of this License and that the license for the
|
||||
Executable version does not attempt to limit or alter the recipient's
|
||||
rights in the Source Code version from the rights set forth in this
|
||||
License. If You distribute the Executable version under a different
|
||||
license You must make it absolutely clear that any terms which differ
|
||||
from this License are offered by You alone, not by the Initial
|
||||
Developer or any Contributor. You hereby agree to indemnify the
|
||||
Initial Developer and every Contributor for any liability incurred by
|
||||
the Initial Developer or such Contributor as a result of any such
|
||||
terms You offer.
|
||||
|
||||
3.7. Larger Works.
|
||||
You may create a Larger Work by combining Covered Code with other code
|
||||
not governed by the terms of this License and distribute the Larger
|
||||
Work as a single product. In such a case, You must make sure the
|
||||
requirements of this License are fulfilled for the Covered Code.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation.
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this
|
||||
License with respect to some or all of the Covered Code due to
|
||||
statute, judicial order, or regulation then You must: (a) comply with
|
||||
the terms of this License to the maximum extent possible; and (b)
|
||||
describe the limitations and the code they affect. Such description
|
||||
must be included in the LEGAL file described in Section 3.4 and must
|
||||
be included with all distributions of the Source Code. Except to the
|
||||
extent prohibited by statute or regulation, such description must be
|
||||
sufficiently detailed for a recipient of ordinary skill to be able to
|
||||
understand it.
|
||||
|
||||
5. Application of this License.
|
||||
|
||||
This License applies to code to which the Initial Developer has
|
||||
attached the notice in Exhibit A and to related Covered Code.
|
||||
|
||||
6. Versions of the License.
|
||||
|
||||
6.1. New Versions.
|
||||
Netscape Communications Corporation ("Netscape") may publish revised
|
||||
and/or new versions of the License from time to time. Each version
|
||||
will be given a distinguishing version number.
|
||||
|
||||
6.2. Effect of New Versions.
|
||||
Once Covered Code has been published under a particular version of the
|
||||
License, You may always continue to use it under the terms of that
|
||||
version. You may also choose to use such Covered Code under the terms
|
||||
of any subsequent version of the License published by Netscape. No one
|
||||
other than Netscape has the right to modify the terms applicable to
|
||||
Covered Code created under this License.
|
||||
|
||||
6.3. Derivative Works.
|
||||
If You create or use a modified version of this License (which you may
|
||||
only do in order to apply it to code which is not already Covered Code
|
||||
governed by this License), You must (a) rename Your license so that
|
||||
the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
|
||||
"MPL", "NPL" or any confusingly similar phrase do not appear in your
|
||||
license (except to note that your license differs from this License)
|
||||
and (b) otherwise make it clear that Your version of the license
|
||||
contains terms which differ from the Mozilla Public License and
|
||||
Netscape Public License. (Filling in the name of the Initial
|
||||
Developer, Original Code or Contributor in the notice described in
|
||||
Exhibit A shall not of themselves be deemed to be modifications of
|
||||
this License.)
|
||||
|
||||
7. DISCLAIMER OF WARRANTY.
|
||||
|
||||
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
|
||||
WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
|
||||
DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
|
||||
THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
|
||||
IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
|
||||
YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
|
||||
COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
|
||||
OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
|
||||
ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
|
||||
|
||||
8. TERMINATION.
|
||||
|
||||
8.1. This License and the rights granted hereunder will terminate
|
||||
automatically if You fail to comply with terms herein and fail to cure
|
||||
such breach within 30 days of becoming aware of the breach. All
|
||||
sublicenses to the Covered Code which are properly granted shall
|
||||
survive any termination of this License. Provisions which, by their
|
||||
nature, must remain in effect beyond the termination of this License
|
||||
shall survive.
|
||||
|
||||
8.2. If You initiate litigation by asserting a patent infringement
|
||||
claim (excluding declatory judgment actions) against Initial Developer
|
||||
or a Contributor (the Initial Developer or Contributor against whom
|
||||
You file such action is referred to as "Participant") alleging that:
|
||||
|
||||
(a) such Participant's Contributor Version directly or indirectly
|
||||
infringes any patent, then any and all rights granted by such
|
||||
Participant to You under Sections 2.1 and/or 2.2 of this License
|
||||
shall, upon 60 days notice from Participant terminate prospectively,
|
||||
unless if within 60 days after receipt of notice You either: (i)
|
||||
agree in writing to pay Participant a mutually agreeable reasonable
|
||||
royalty for Your past and future use of Modifications made by such
|
||||
Participant, or (ii) withdraw Your litigation claim with respect to
|
||||
the Contributor Version against such Participant. If within 60 days
|
||||
of notice, a reasonable royalty and payment arrangement are not
|
||||
mutually agreed upon in writing by the parties or the litigation claim
|
||||
is not withdrawn, the rights granted by Participant to You under
|
||||
Sections 2.1 and/or 2.2 automatically terminate at the expiration of
|
||||
the 60 day notice period specified above.
|
||||
|
||||
(b) any software, hardware, or device, other than such Participant's
|
||||
Contributor Version, directly or indirectly infringes any patent, then
|
||||
any rights granted to You by such Participant under Sections 2.1(b)
|
||||
and 2.2(b) are revoked effective as of the date You first made, used,
|
||||
sold, distributed, or had made, Modifications made by that
|
||||
Participant.
|
||||
|
||||
8.3. If You assert a patent infringement claim against Participant
|
||||
alleging that such Participant's Contributor Version directly or
|
||||
indirectly infringes any patent where such claim is resolved (such as
|
||||
by license or settlement) prior to the initiation of patent
|
||||
infringement litigation, then the reasonable value of the licenses
|
||||
granted by such Participant under Sections 2.1 or 2.2 shall be taken
|
||||
into account in determining the amount or value of any payment or
|
||||
license.
|
||||
|
||||
8.4. In the event of termination under Sections 8.1 or 8.2 above,
|
||||
all end user license agreements (excluding distributors and resellers)
|
||||
which have been validly granted by You or any distributor hereunder
|
||||
prior to termination shall survive termination.
|
||||
|
||||
9. LIMITATION OF LIABILITY.
|
||||
|
||||
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
|
||||
(INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
|
||||
DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
|
||||
OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
|
||||
ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
|
||||
CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
|
||||
WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
|
||||
COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
|
||||
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
|
||||
LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
|
||||
RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
|
||||
PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
|
||||
EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
|
||||
THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
|
||||
|
||||
10. U.S. GOVERNMENT END USERS.
|
||||
|
||||
The Covered Code is a "commercial item," as that term is defined in
|
||||
48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
|
||||
software" and "commercial computer software documentation," as such
|
||||
terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
|
||||
C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
|
||||
all U.S. Government End Users acquire Covered Code with only those
|
||||
rights set forth herein.
|
||||
|
||||
11. MISCELLANEOUS.
|
||||
|
||||
This License represents the complete agreement concerning subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. This License shall be governed by
|
||||
California law provisions (except to the extent applicable law, if
|
||||
any, provides otherwise), excluding its conflict-of-law provisions.
|
||||
With respect to disputes in which at least one party is a citizen of,
|
||||
or an entity chartered or registered to do business in the United
|
||||
States of America, any litigation relating to this License shall be
|
||||
subject to the jurisdiction of the Federal Courts of the Northern
|
||||
District of California, with venue lying in Santa Clara County,
|
||||
California, with the losing party responsible for costs, including
|
||||
without limitation, court costs and reasonable attorneys' fees and
|
||||
expenses. The application of the United Nations Convention on
|
||||
Contracts for the International Sale of Goods is expressly excluded.
|
||||
Any law or regulation which provides that the language of a contract
|
||||
shall be construed against the drafter shall not apply to this
|
||||
License.
|
||||
|
||||
12. RESPONSIBILITY FOR CLAIMS.
|
||||
|
||||
As between Initial Developer and the Contributors, each party is
|
||||
responsible for claims and damages arising, directly or indirectly,
|
||||
out of its utilization of rights under this License and You agree to
|
||||
work with Initial Developer and Contributors to distribute such
|
||||
responsibility on an equitable basis. Nothing herein is intended or
|
||||
shall be deemed to constitute any admission of liability.
|
||||
|
||||
13. MULTIPLE-LICENSED CODE.
|
||||
|
||||
Initial Developer may designate portions of the Covered Code as
|
||||
"Multiple-Licensed". "Multiple-Licensed" means that the Initial
|
||||
Developer permits you to utilize portions of the Covered Code under
|
||||
Your choice of the NPL or the alternative licenses, if any, specified
|
||||
by the Initial Developer in the file described in Exhibit A.
|
||||
|
||||
EXHIBIT A -Mozilla Public License.
|
||||
|
||||
``The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in
|
||||
compliance with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS"
|
||||
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing rights and limitations
|
||||
under the License.
|
||||
|
||||
The Original Code is ______________________________________.
|
||||
|
||||
The Initial Developer of the Original Code is ________________________.
|
||||
Portions created by ______________________ are Copyright (C) ______
|
||||
_______________________. All Rights Reserved.
|
||||
|
||||
Contributor(s): ______________________________________.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms
|
||||
of the _____ license (the "[___] License"), in which case the
|
||||
provisions of [______] License are applicable instead of those
|
||||
above. If you wish to allow use of your version of this file only
|
||||
under the terms of the [____] License and not to allow others to use
|
||||
your version of this file under the MPL, indicate your decision by
|
||||
deleting the provisions above and replace them with the notice and
|
||||
other provisions required by the [___] License. If you do not delete
|
||||
the provisions above, a recipient may use your version of this file
|
||||
under either the MPL or the [___] License."
|
||||
|
||||
[NOTE: The text of this Exhibit A may differ slightly from the text of
|
||||
the notices in the Source Code files of the Original Code. You should
|
||||
use the text of this Exhibit A rather than the text found in the
|
||||
Original Code Source Code for Your Modifications.]
|
||||
|
|
@ -1,167 +0,0 @@
|
|||
Basic Installation
|
||||
==================
|
||||
|
||||
These are generic installation instructions.
|
||||
|
||||
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').
|
||||
|
||||
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.
|
||||
|
||||
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'.
|
||||
|
||||
The simplest way to compile this package is:
|
||||
|
||||
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.
|
||||
|
||||
Running `configure' takes a while. While running, it prints some
|
||||
messages telling which features it is checking for.
|
||||
|
||||
2. Type `make' to compile the package.
|
||||
|
||||
3. Type `make install' to install the programs and any data files and
|
||||
documentation.
|
||||
|
||||
4. You can remove the program binaries and object files from the
|
||||
source code directory by typing `make clean'.
|
||||
|
||||
Compilers and Options
|
||||
=====================
|
||||
|
||||
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
|
||||
|
||||
Or on systems that have the `env' program, you can do it like this:
|
||||
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
|
||||
|
||||
Compiling For Multiple Architectures
|
||||
====================================
|
||||
|
||||
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 `..'.
|
||||
|
||||
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.
|
||||
|
||||
Installation Names
|
||||
==================
|
||||
|
||||
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.
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/* config.h. Generated from config.h.in by configure. */
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* have cppunit */
|
||||
#define HAVE_CPPUNIT 0
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#define HAVE_DLFCN_H 1
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#define HAVE_INTTYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#define HAVE_MEMORY_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H 1
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#define HAVE_STDLIB_H 1
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#define HAVE_STRINGS_H 1
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#define HAVE_STRING_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#define HAVE_SYS_STAT_H 1
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#define HAVE_SYS_TYPES_H 1
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#define HAVE_UNISTD_H 1
|
||||
|
||||
/* have zlib */
|
||||
#define HAVE_ZLIB 1
|
||||
|
||||
/* Suffix for lib directories */
|
||||
#define KDELIBSUFF ""
|
||||
|
||||
/* Name of package */
|
||||
#define PACKAGE "taglib"
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#define PACKAGE_BUGREPORT ""
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#define PACKAGE_NAME ""
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#define PACKAGE_STRING ""
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#define PACKAGE_TARNAME ""
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#define PACKAGE_VERSION ""
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Version number of package */
|
||||
#define VERSION "1.5"
|
|
@ -1,170 +0,0 @@
|
|||
================================================================================
|
||||
= APE Tag Specification, Version 2.000
|
||||
================================================================================
|
||||
|
||||
Original Content (C) 2004, Frank Klemm <frank.klemm@elster.offl.uni-jena.de>
|
||||
Formatting / Editing (C) 2004, Scott Wheeler <wheeler@kde.org>
|
||||
|
||||
================================================================================
|
||||
= Contents
|
||||
================================================================================
|
||||
|
||||
1 - APE Tag General Structure
|
||||
2 - APE Tag Header / Footer Format
|
||||
3 - APE Tag Flags
|
||||
4 - APE Tag Item Format
|
||||
5 - APE Tag Item Supported Keys
|
||||
6 - APE Tag Item Content
|
||||
7 - Data Types
|
||||
7.1 - Data Types / UTF-8
|
||||
7.2 - Data Types / Dates
|
||||
7.3 - Data Types / Timestamps
|
||||
|
||||
================================================================================
|
||||
= 1 - APE Tag General Structure
|
||||
================================================================================
|
||||
|
||||
Member of Basic Components of SV8 Stream Note:
|
||||
|
||||
It is strongly recommended that the data size be stored in the tags. The size
|
||||
should normally be in the roughly one kilobyte, never more than 8 kilobytes.
|
||||
|
||||
Larger data should be stored externally using link entries. Linked data is much
|
||||
easier to process by normal programs, so for instance JPEG data should not be
|
||||
included inside the audio file.
|
||||
|
||||
APE Tag Version 2.000 (with header, recommended):
|
||||
|
||||
/================================\
|
||||
| APE Tag Header | 32 bytes |
|
||||
|-------------------|------------|
|
||||
| APE Tag Item 1 | > 10 bytes |
|
||||
| APE Tag Item 2 | > 10 bytes |
|
||||
| APE Tag Item n-1 | > 10 bytes |
|
||||
| APE Tag Item n | > 10 bytes |
|
||||
|-------------------|------------|
|
||||
| APE Tag Footer | 32 bytes |
|
||||
\================================/
|
||||
|
||||
|
||||
APE tag items should be sorted ascending by size. When streaming, parts of the
|
||||
APE tag may be dropped to reduce the danger of drop outs between tracks. This
|
||||
is not required, but is strongly recommended. It would be desirable for the i
|
||||
tems to be sorted by importance / size, but this is not feasible. This
|
||||
convention should only be broken when adding less important small items and it
|
||||
is not desirable to rewrite the entire tag. An APE tag at the end of a file
|
||||
(the recommended location) must have at least a footer; an APE tag at the
|
||||
beginning of a file (strongly discouraged) must have at least a header.
|
||||
|
||||
APE Tag Version 1.000 (without header, deprecated)
|
||||
|
||||
/================================\
|
||||
| APE Tag Item 1 | > 10 bytes |
|
||||
| APE Tag Item 2 | > 10 bytes |
|
||||
| APE Tag Item n-1 | > 10 bytes |
|
||||
| APE Tag Item n | > 10 bytes |
|
||||
|-------------------|------------|
|
||||
| APE Tag Footer | 32 bytes |
|
||||
\================================/
|
||||
|
||||
================================================================================
|
||||
= 2 - APE Tag Header / Footer Format
|
||||
================================================================================
|
||||
|
||||
Contains number, length and attributes of all tag items
|
||||
|
||||
Header and Footer are different in 1 bit in the Tags Flags to distinguish
|
||||
between them.
|
||||
|
||||
Member of APE Tag 2.0
|
||||
|
||||
/===========================================================================\
|
||||
| Preamble | 8 bytes | { 'A', 'P', 'E', 'T', 'A', 'G', 'E', 'X' } |
|
||||
|----------------|---------|------------------------------------------------|
|
||||
| Version Number | 4 bytes | 1000 = Version 1.000, 2000 = Version 2.000 |
|
||||
|----------------|---------|------------------------------------------------|
|
||||
| Tag Size | 4 bytes | Tag size in bytes including footer and all tag |
|
||||
| | | items excluding the header (for 1.000 |
|
||||
| | | compatibility) |
|
||||
|----------------|---------|------------------------------------------------|
|
||||
| Item Count | 4 bytes | Number of items in the tag |
|
||||
|----------------|---------|------------------------------------------------|
|
||||
| Tag Flags | 4 bytes | Global flags |
|
||||
|----------------|---------|------------------------------------------------|
|
||||
| Reserved | 8 bytes | Must be zeroed |
|
||||
\===========================================================================/
|
||||
|
||||
================================================================================
|
||||
= 3 - APE Tag Flags
|
||||
================================================================================
|
||||
|
||||
The general flag structure for either items or headers / footers is the same.
|
||||
Bits 31, 30 and 29 are specific to headers / footers, whereas 2 through 0 are
|
||||
item specific.
|
||||
|
||||
Note: APE Tags from Version 1.0 do not use any of the following. All flags in
|
||||
that version are zeroed and ignored when reading.
|
||||
|
||||
/=================================================================\
|
||||
| Contains Header | Bit 31 | 1 - has header | 0 - no header |
|
||||
|-----------------|-------------|---------------------------------|
|
||||
| Contains Footer | Bit 30 | 1 - has footer | 0 - no footer |
|
||||
|-----------------|-------------|---------------------------------|
|
||||
| Is Header | Bit 29 | 1 - is header | 0 - is footer |
|
||||
|-----------------|-------------|---------------------------------|
|
||||
| Undefined | Bits 28 - 3 | Undefined, must be zeroed |
|
||||
|-----------------|-------------|---------------------------------|
|
||||
| Encoding | Bits 2 - 1 | 00 - UTF-8 |
|
||||
| | | 01 - Binary Data * |
|
||||
| | | 10 - External Reference ** |
|
||||
| | | 11 - Reserved |
|
||||
|-----------------|-------------|---------------------------------|
|
||||
| Read Only | Bit 0 | 1 - read only | 0 - read/write |
|
||||
\=================================================================/
|
||||
|
||||
(*) Should be ignored by tools for editing text values
|
||||
(**) Allowed external reference formats:
|
||||
- http://host/directory/filename.ext
|
||||
- ftp://host/directory/filename.ext
|
||||
- filename.ext
|
||||
- /directory/filename.ext
|
||||
- DRIVE:/directory/filename.ext
|
||||
|
||||
Note: External references are also UTF-8 encoded.
|
||||
|
||||
================================================================================
|
||||
= 4 - APE Tag Item Format
|
||||
================================================================================
|
||||
|
||||
APE Tag Items are stored as key-value pairs. APE Tags Item Key are case
|
||||
sensitive, however it is illegal to use keys which only differ in case and
|
||||
it is recommended that tag reading not be case sensitive.
|
||||
|
||||
Every key can only occur (at most) once. It is not possible to repeat a key
|
||||
to signify updated contents.
|
||||
|
||||
Tags can be partially or completely repeated in the streaming format. This
|
||||
makes it possible to display an artist and / or title if it was missed at the
|
||||
beginning of the stream. It is recommended that the important information like
|
||||
artist, album and title should occur approximately every 2 minutes in the
|
||||
stream and again 5 to 10 seconds before the end. However, care should be tak
|
||||
en not to replicate this information too often or during passages with high
|
||||
bitrate demands to avoid unnecessary drop-outs.
|
||||
|
||||
/==============================================================================\
|
||||
| Content Size | 4 bytes | Length of the value in bytes |
|
||||
|----------------|---------------|---------------------------------------------|
|
||||
| Flags | 4 bytes | Item flags |
|
||||
|----------------|---------------|---------------------------------------------|
|
||||
| Key | 2 - 255 bytes | Item key |
|
||||
|----------------|---------------|---------------------------------------------|
|
||||
| Key Terminator | 1 byte | Null byte that indicates the end of the key |
|
||||
|----------------|---------------|---------------------------------------------|
|
||||
| Value | variable | Content (formatted according to the flags) |
|
||||
\==============================================================================/
|
||||
|
||||
================================================================================
|
||||
|
||||
Sections 5 - 7 haven't yet been converted from:
|
||||
|
||||
http://www.personal.uni-jena.de/~pfk/mpp/sv8/apetag.html
|
|
@ -1,270 +0,0 @@
|
|||
/***************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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 "apefile.h"
|
||||
#include "id3v1tag.h"
|
||||
|
||||
#include "apetag.h"
|
||||
#include "apefooter.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
enum { APEIndex, ID3v1Index };
|
||||
}
|
||||
|
||||
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()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::Tag *APE::File::tag() const
|
||||
{
|
||||
return &d->tag;
|
||||
}
|
||||
|
||||
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>(ID3v1Index, create);
|
||||
}
|
||||
|
||||
APE::Tag *APE::File::APETag(bool create)
|
||||
{
|
||||
return d->tag.access<APE::Tag>(APEIndex, create);
|
||||
}
|
||||
|
||||
void APE::File::strip(int tags)
|
||||
{
|
||||
if(tags & ID3v1) {
|
||||
d->tag.set(ID3v1Index, 0);
|
||||
APETag(true);
|
||||
}
|
||||
|
||||
if(tags & APE) {
|
||||
d->tag.set(APEIndex, 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(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
|
||||
d->hasID3v1 = true;
|
||||
}
|
||||
|
||||
// Look for an APE tag
|
||||
|
||||
d->APELocation = findAPE();
|
||||
|
||||
if(d->APELocation >= 0) {
|
||||
d->tag.set(APEIndex, 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;
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
/***************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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);
|
||||
|
||||
/*!
|
||||
* 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;
|
||||
|
||||
/*!
|
||||
* 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
|
|
@ -1,236 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
(C) 2002 - 2008 by Scott Wheeler (id3v2header.cpp)
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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 <iostream>
|
||||
#include <bitset>
|
||||
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
|
||||
#include "apefooter.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace APE;
|
||||
|
||||
class Footer::FooterPrivate
|
||||
{
|
||||
public:
|
||||
FooterPrivate() : version(0),
|
||||
footerPresent(true),
|
||||
headerPresent(false),
|
||||
isHeader(false),
|
||||
itemCount(0),
|
||||
tagSize(0) {}
|
||||
|
||||
~FooterPrivate() {}
|
||||
|
||||
uint version;
|
||||
|
||||
bool footerPresent;
|
||||
bool headerPresent;
|
||||
|
||||
bool isHeader;
|
||||
|
||||
uint itemCount;
|
||||
uint tagSize;
|
||||
|
||||
static const uint size = 32;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// static members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TagLib::uint Footer::size()
|
||||
{
|
||||
return FooterPrivate::size;
|
||||
}
|
||||
|
||||
ByteVector Footer::fileIdentifier()
|
||||
{
|
||||
return ByteVector::fromCString("APETAGEX");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Footer::Footer()
|
||||
{
|
||||
d = new FooterPrivate;
|
||||
}
|
||||
|
||||
Footer::Footer(const ByteVector &data)
|
||||
{
|
||||
d = new FooterPrivate;
|
||||
parse(data);
|
||||
}
|
||||
|
||||
Footer::~Footer()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::uint Footer::version() const
|
||||
{
|
||||
return d->version;
|
||||
}
|
||||
|
||||
bool Footer::headerPresent() const
|
||||
{
|
||||
return d->headerPresent;
|
||||
}
|
||||
|
||||
bool Footer::footerPresent() const
|
||||
{
|
||||
return d->footerPresent;
|
||||
}
|
||||
|
||||
bool Footer::isHeader() const
|
||||
{
|
||||
return d->isHeader;
|
||||
}
|
||||
|
||||
void Footer::setHeaderPresent(bool b) const
|
||||
{
|
||||
d->headerPresent = b;
|
||||
}
|
||||
|
||||
TagLib::uint Footer::itemCount() const
|
||||
{
|
||||
return d->itemCount;
|
||||
}
|
||||
|
||||
void Footer::setItemCount(uint s)
|
||||
{
|
||||
d->itemCount = s;
|
||||
}
|
||||
|
||||
TagLib::uint Footer::tagSize() const
|
||||
{
|
||||
return d->tagSize;
|
||||
}
|
||||
|
||||
TagLib::uint Footer::completeTagSize() const
|
||||
{
|
||||
if(d->headerPresent)
|
||||
return d->tagSize + d->size;
|
||||
else
|
||||
return d->tagSize;
|
||||
}
|
||||
|
||||
void Footer::setTagSize(uint s)
|
||||
{
|
||||
d->tagSize = s;
|
||||
}
|
||||
|
||||
void Footer::setData(const ByteVector &data)
|
||||
{
|
||||
parse(data);
|
||||
}
|
||||
|
||||
ByteVector Footer::renderFooter() const
|
||||
{
|
||||
return render(false);
|
||||
}
|
||||
|
||||
ByteVector Footer::renderHeader() const
|
||||
{
|
||||
if (!d->headerPresent) return ByteVector();
|
||||
|
||||
return render(true);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Footer::parse(const ByteVector &data)
|
||||
{
|
||||
if(data.size() < size())
|
||||
return;
|
||||
|
||||
// The first eight bytes, data[0..7], are the File Identifier, "APETAGEX".
|
||||
|
||||
// Read the version number
|
||||
|
||||
d->version = data.mid(8, 4).toUInt(false);
|
||||
|
||||
// Read the tag size
|
||||
|
||||
d->tagSize = data.mid(12, 4).toUInt(false);
|
||||
|
||||
// Read the item count
|
||||
|
||||
d->itemCount = data.mid(16, 4).toUInt(false);
|
||||
|
||||
// Read the flags
|
||||
|
||||
std::bitset<32> flags(data.mid(20, 4).toUInt(false));
|
||||
|
||||
d->headerPresent = flags[31];
|
||||
d->footerPresent = !flags[30];
|
||||
d->isHeader = flags[29];
|
||||
|
||||
}
|
||||
|
||||
ByteVector Footer::render(bool isHeader) const
|
||||
{
|
||||
ByteVector v;
|
||||
|
||||
// add the file identifier -- "APETAGEX"
|
||||
|
||||
v.append(fileIdentifier());
|
||||
|
||||
// add the version number -- we always render a 2.000 tag regardless of what
|
||||
// the tag originally was.
|
||||
|
||||
v.append(ByteVector::fromUInt(2000, false));
|
||||
|
||||
// add the tag size
|
||||
|
||||
v.append(ByteVector::fromUInt(d->tagSize, false));
|
||||
|
||||
// add the item count
|
||||
|
||||
v.append(ByteVector::fromUInt(d->itemCount, false));
|
||||
|
||||
// render and add the flags
|
||||
|
||||
std::bitset<32> flags;
|
||||
|
||||
flags[31] = d->headerPresent;
|
||||
flags[30] = false; // footer is always present
|
||||
flags[29] = isHeader;
|
||||
|
||||
v.append(ByteVector::fromUInt(flags.to_ulong(), false));
|
||||
|
||||
// add the reserved 64bit
|
||||
|
||||
v.append(ByteVector::fromLongLong(0));
|
||||
|
||||
return v;
|
||||
}
|
|
@ -1,173 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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_APEFOOTER_H
|
||||
#define TAGLIB_APEFOOTER_H
|
||||
|
||||
#include "tbytevector.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace APE {
|
||||
|
||||
//! An implementation of APE footers
|
||||
|
||||
/*!
|
||||
* This class implements APE footers (and headers). It attempts to follow, both
|
||||
* semantically and programatically, the structure specified in
|
||||
* the APE v2.0 standard. The API is based on the properties of APE footer and
|
||||
* headers specified there.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT Footer
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Constructs an empty APE footer.
|
||||
*/
|
||||
Footer();
|
||||
|
||||
/*!
|
||||
* Constructs an APE footer based on \a data. parse() is called
|
||||
* immediately.
|
||||
*/
|
||||
Footer(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Destroys the footer.
|
||||
*/
|
||||
virtual ~Footer();
|
||||
|
||||
/*!
|
||||
* Returns the version number. (Note: This is the 1000 or 2000.)
|
||||
*/
|
||||
uint version() const;
|
||||
|
||||
/*!
|
||||
* Returns true if a header is present in the tag.
|
||||
*/
|
||||
bool headerPresent() const;
|
||||
|
||||
/*!
|
||||
* Returns true if a footer is present in the tag.
|
||||
*/
|
||||
bool footerPresent() const;
|
||||
|
||||
/*!
|
||||
* Returns true this is actually the header.
|
||||
*/
|
||||
bool isHeader() const;
|
||||
|
||||
/*!
|
||||
* Sets whether the header should be rendered or not
|
||||
*/
|
||||
void setHeaderPresent(bool b) const;
|
||||
|
||||
/*!
|
||||
* Returns the number of items in the tag.
|
||||
*/
|
||||
uint itemCount() const;
|
||||
|
||||
/*!
|
||||
* Set the item count to \a s.
|
||||
* \see itemCount()
|
||||
*/
|
||||
void setItemCount(uint s);
|
||||
|
||||
/*!
|
||||
* Returns the tag size in bytes. This is the size of the frame content and footer.
|
||||
* The size of the \e entire tag will be this plus the header size, if present.
|
||||
*
|
||||
* \see completeTagSize()
|
||||
*/
|
||||
uint tagSize() const;
|
||||
|
||||
/*!
|
||||
* Returns the tag size, including if present, the header
|
||||
* size.
|
||||
*
|
||||
* \see tagSize()
|
||||
*/
|
||||
uint completeTagSize() const;
|
||||
|
||||
/*!
|
||||
* Set the tag size to \a s.
|
||||
* \see tagSize()
|
||||
*/
|
||||
void setTagSize(uint s);
|
||||
|
||||
/*!
|
||||
* Returns the size of the footer. Presently this is always 32 bytes.
|
||||
*/
|
||||
static uint size();
|
||||
|
||||
/*!
|
||||
* Returns the string used to identify an APE tag inside of a file.
|
||||
* Presently this is always "APETAGEX".
|
||||
*/
|
||||
static ByteVector fileIdentifier();
|
||||
|
||||
/*!
|
||||
* Sets the data that will be used as the footer. 32 bytes,
|
||||
* starting from \a data will be used.
|
||||
*/
|
||||
void setData(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Renders the footer back to binary format.
|
||||
*/
|
||||
ByteVector renderFooter() const;
|
||||
|
||||
/*!
|
||||
* Renders the header corresponding to the footer. If headerPresent is
|
||||
* set to false, it returns an empty ByteVector.
|
||||
*/
|
||||
ByteVector renderHeader() const;
|
||||
|
||||
protected:
|
||||
/*!
|
||||
* Called by setData() to parse the footer data. It makes this information
|
||||
* available through the public API.
|
||||
*/
|
||||
void parse(const ByteVector &data);
|
||||
|
||||
/*!
|
||||
* Called by renderFooter and renderHeader
|
||||
*/
|
||||
ByteVector render(bool isHeader) const;
|
||||
|
||||
private:
|
||||
Footer(const Footer &);
|
||||
Footer &operator=(const Footer &);
|
||||
|
||||
class FooterPrivate;
|
||||
FooterPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,229 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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 <tbytevectorlist.h>
|
||||
#include <tdebug.h>
|
||||
|
||||
#include "apeitem.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace APE;
|
||||
|
||||
class APE::Item::ItemPrivate
|
||||
{
|
||||
public:
|
||||
ItemPrivate() : type(Text), readOnly(false) {}
|
||||
|
||||
Item::ItemTypes type;
|
||||
String key;
|
||||
ByteVector value;
|
||||
StringList text;
|
||||
bool readOnly;
|
||||
};
|
||||
|
||||
APE::Item::Item()
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
}
|
||||
|
||||
APE::Item::Item(const String &key, const String &value)
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->key = key;
|
||||
d->text.append(value);
|
||||
}
|
||||
|
||||
APE::Item::Item(const String &key, const StringList &values)
|
||||
{
|
||||
d = new ItemPrivate;
|
||||
d->key = key;
|
||||
d->text = values;
|
||||
}
|
||||
|
||||
APE::Item::Item(const Item &item)
|
||||
{
|
||||
d = new ItemPrivate(*item.d);
|
||||
}
|
||||
|
||||
APE::Item::~Item()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
Item &APE::Item::operator=(const Item &item)
|
||||
{
|
||||
delete d;
|
||||
d = new ItemPrivate(*item.d);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void APE::Item::setReadOnly(bool readOnly)
|
||||
{
|
||||
d->readOnly = readOnly;
|
||||
}
|
||||
|
||||
bool APE::Item::isReadOnly() const
|
||||
{
|
||||
return d->readOnly;
|
||||
}
|
||||
|
||||
void APE::Item::setType(APE::Item::ItemTypes val)
|
||||
{
|
||||
d->type = val;
|
||||
}
|
||||
|
||||
APE::Item::ItemTypes APE::Item::type() const
|
||||
{
|
||||
return d->type;
|
||||
}
|
||||
|
||||
String APE::Item::key() const
|
||||
{
|
||||
return d->key;
|
||||
}
|
||||
|
||||
ByteVector APE::Item::value() const
|
||||
{
|
||||
// This seems incorrect as it won't be actually rendering the value to keep it
|
||||
// up to date.
|
||||
|
||||
return d->value;
|
||||
}
|
||||
|
||||
void APE::Item::setKey(const String &key)
|
||||
{
|
||||
d->key = key;
|
||||
}
|
||||
|
||||
void APE::Item::setValue(const String &value)
|
||||
{
|
||||
d->text = value;
|
||||
}
|
||||
|
||||
void APE::Item::setValues(const StringList &value)
|
||||
{
|
||||
d->text = value;
|
||||
}
|
||||
|
||||
void APE::Item::appendValue(const String &value)
|
||||
{
|
||||
d->text.append(value);
|
||||
}
|
||||
|
||||
void APE::Item::appendValues(const StringList &values)
|
||||
{
|
||||
d->text.append(values);
|
||||
}
|
||||
|
||||
int APE::Item::size() const
|
||||
{
|
||||
return 8 + d->key.size() + 1 + d->value.size();
|
||||
}
|
||||
|
||||
StringList APE::Item::toStringList() const
|
||||
{
|
||||
return d->text;
|
||||
}
|
||||
|
||||
StringList APE::Item::values() const
|
||||
{
|
||||
return d->text;
|
||||
}
|
||||
|
||||
String APE::Item::toString() const
|
||||
{
|
||||
return isEmpty() ? String::null : d->text.front();
|
||||
}
|
||||
|
||||
bool APE::Item::isEmpty() const
|
||||
{
|
||||
switch(d->type) {
|
||||
case 0:
|
||||
case 1:
|
||||
if(d->text.isEmpty())
|
||||
return true;
|
||||
if(d->text.size() == 1 && d->text.front().isEmpty())
|
||||
return true;
|
||||
return false;
|
||||
case 2:
|
||||
return d->value.isEmpty();
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void APE::Item::parse(const ByteVector &data)
|
||||
{
|
||||
// 11 bytes is the minimum size for an APE item
|
||||
|
||||
if(data.size() < 11) {
|
||||
debug("APE::Item::parse() -- no data in item");
|
||||
return;
|
||||
}
|
||||
|
||||
uint valueLength = data.mid(0, 4).toUInt(false);
|
||||
uint flags = data.mid(4, 4).toUInt(false);
|
||||
|
||||
d->key = String(data.mid(8), String::UTF8);
|
||||
|
||||
d->value = data.mid(8 + d->key.size() + 1, valueLength);
|
||||
|
||||
setReadOnly(flags & 1);
|
||||
setType(ItemTypes((flags >> 1) & 3));
|
||||
|
||||
if(int(d->type) < 2)
|
||||
d->text = StringList(ByteVectorList::split(d->value, '\0'), String::UTF8);
|
||||
}
|
||||
|
||||
ByteVector APE::Item::render() const
|
||||
{
|
||||
ByteVector data;
|
||||
TagLib::uint flags = ((d->readOnly) ? 1 : 0) | (d->type << 1);
|
||||
ByteVector value;
|
||||
|
||||
if(isEmpty())
|
||||
return data;
|
||||
|
||||
if(d->type != Item::Binary) {
|
||||
StringList::ConstIterator it = d->text.begin();
|
||||
value.append(it->data(String::UTF8));
|
||||
it++;
|
||||
for(; it != d->text.end(); ++it) {
|
||||
value.append('\0');
|
||||
value.append(it->data(String::UTF8));
|
||||
}
|
||||
d->value = value;
|
||||
}
|
||||
else
|
||||
value.append(d->value);
|
||||
|
||||
data.append(ByteVector::fromUInt(value.size(), false));
|
||||
data.append(ByteVector::fromUInt(flags, false));
|
||||
data.append(d->key.data(String::UTF8));
|
||||
data.append(ByteVector('\0'));
|
||||
data.append(value);
|
||||
|
||||
return data;
|
||||
}
|
|
@ -1,204 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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_APEITEM_H
|
||||
#define TAGLIB_APEITEM_H
|
||||
|
||||
#include "tbytevector.h"
|
||||
#include "tstring.h"
|
||||
#include "tstringlist.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace APE {
|
||||
|
||||
//! An implementation of APE-items
|
||||
|
||||
/*!
|
||||
* This class provides the features of items in the APEv2 standard.
|
||||
*/
|
||||
class TAGLIB_EXPORT Item
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Enum of types an Item can have. The value of 3 is reserved.
|
||||
*/
|
||||
enum ItemTypes {
|
||||
//! Item contains text information coded in UTF-8
|
||||
Text = 0,
|
||||
//! Item contains binary information
|
||||
Binary = 1,
|
||||
//! Item is a locator of external stored information
|
||||
Locator = 2
|
||||
};
|
||||
/*!
|
||||
* Constructs an empty item.
|
||||
*/
|
||||
Item();
|
||||
|
||||
/*!
|
||||
* Constructs an 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.
|
||||
*/
|
||||
Item(const String &key, const StringList &values);
|
||||
|
||||
/*!
|
||||
* Construct an item as a copy of \a item.
|
||||
*/
|
||||
Item(const Item &item);
|
||||
|
||||
/*!
|
||||
* Destroys the item.
|
||||
*/
|
||||
virtual ~Item();
|
||||
|
||||
/*!
|
||||
* Copies the contents of \a item into this item.
|
||||
*/
|
||||
Item &operator=(const Item &item);
|
||||
|
||||
/*!
|
||||
* Returns the key.
|
||||
*/
|
||||
String key() const;
|
||||
|
||||
/*!
|
||||
* 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.
|
||||
*/
|
||||
ByteVector value() const;
|
||||
|
||||
/*!
|
||||
* Sets the key for the item to \a key.
|
||||
*/
|
||||
void setKey(const String &key);
|
||||
|
||||
/*!
|
||||
* Sets the 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
|
||||
* any previous contents.
|
||||
*
|
||||
* \see toStringList()
|
||||
*/
|
||||
void setValues(const StringList &values);
|
||||
|
||||
/*!
|
||||
* Appends \a value to create (or extend) the current list of values.
|
||||
*
|
||||
* \see toString()
|
||||
*/
|
||||
void appendValue(const String &value);
|
||||
|
||||
/*!
|
||||
* Appends \a values to extend the current list of values.
|
||||
*
|
||||
* \see toStringList()
|
||||
*/
|
||||
void appendValues(const StringList &values);
|
||||
|
||||
/*!
|
||||
* Returns the size of the full item.
|
||||
*/
|
||||
int size() const;
|
||||
|
||||
/*!
|
||||
* Returns the value as a single string. In case of multiple strings,
|
||||
* the first is returned.
|
||||
*/
|
||||
String toString() const;
|
||||
|
||||
/*!
|
||||
* \deprecated
|
||||
* \see values
|
||||
*/
|
||||
StringList toStringList() const;
|
||||
|
||||
/*!
|
||||
* Returns the list of values.
|
||||
*/
|
||||
StringList values() const;
|
||||
|
||||
/*!
|
||||
* Render the item to a ByteVector.
|
||||
*/
|
||||
ByteVector render() const;
|
||||
|
||||
/*!
|
||||
* Parse the item from the ByteVector \a data.
|
||||
*/
|
||||
void parse(const ByteVector& data);
|
||||
|
||||
/*!
|
||||
* Set the item to read-only.
|
||||
*/
|
||||
void setReadOnly(bool readOnly);
|
||||
|
||||
/*!
|
||||
* Return true if the item is read-only.
|
||||
*/
|
||||
bool isReadOnly() const;
|
||||
|
||||
/*!
|
||||
* Sets the type of the item to \a type.
|
||||
*
|
||||
* \see ItemTypes
|
||||
*/
|
||||
void setType(ItemTypes type);
|
||||
|
||||
/*!
|
||||
* Returns the type of the item.
|
||||
*/
|
||||
ItemTypes type() const;
|
||||
|
||||
/*!
|
||||
* Returns if the item has any real content.
|
||||
*/
|
||||
bool isEmpty() const;
|
||||
|
||||
private:
|
||||
class ItemPrivate;
|
||||
ItemPrivate *d;
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -1,224 +0,0 @@
|
|||
/***************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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),
|
||||
file(file),
|
||||
streamLength(streamLength) {}
|
||||
|
||||
long streamLength;
|
||||
int length;
|
||||
int bitrate;
|
||||
int sampleRate;
|
||||
int channels;
|
||||
int version;
|
||||
int bitsPerSample;
|
||||
File *file;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// 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, 0);
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
/***************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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;
|
||||
|
||||
/*!
|
||||
* 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
|
|
@ -1,326 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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 __SUNPRO_CC
|
||||
// Sun Studio finds multiple specializations of Map because
|
||||
// it considers specializations with and without class types
|
||||
// to be different; this define forces Map to use only the
|
||||
// specialization with the class keyword.
|
||||
#define WANT_CLASS_INSTANTIATION_OF_MAP (1)
|
||||
#endif
|
||||
|
||||
#include <tfile.h>
|
||||
#include <tstring.h>
|
||||
#include <tmap.h>
|
||||
|
||||
#include "apetag.h"
|
||||
#include "apefooter.h"
|
||||
#include "apeitem.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace APE;
|
||||
|
||||
class APE::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
TagPrivate() : file(0), footerLocation(-1), tagLength(0) {}
|
||||
|
||||
File *file;
|
||||
long footerLocation;
|
||||
long tagLength;
|
||||
|
||||
Footer footer;
|
||||
|
||||
ItemListMap itemListMap;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public methods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
APE::Tag::Tag() : TagLib::Tag()
|
||||
{
|
||||
d = new TagPrivate;
|
||||
}
|
||||
|
||||
APE::Tag::Tag(File *file, long footerLocation) : TagLib::Tag()
|
||||
{
|
||||
d = new TagPrivate;
|
||||
d->file = file;
|
||||
d->footerLocation = footerLocation;
|
||||
|
||||
read();
|
||||
}
|
||||
|
||||
APE::Tag::~Tag()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
ByteVector APE::Tag::fileIdentifier()
|
||||
{
|
||||
return ByteVector::fromCString("APETAGEX");
|
||||
}
|
||||
|
||||
String APE::Tag::title() const
|
||||
{
|
||||
if(d->itemListMap["TITLE"].isEmpty())
|
||||
return String::null;
|
||||
return d->itemListMap["TITLE"].toString();
|
||||
}
|
||||
|
||||
String APE::Tag::artist() const
|
||||
{
|
||||
if(d->itemListMap["ARTIST"].isEmpty())
|
||||
return String::null;
|
||||
return d->itemListMap["ARTIST"].toString();
|
||||
}
|
||||
|
||||
String APE::Tag::album() const
|
||||
{
|
||||
if(d->itemListMap["ALBUM"].isEmpty())
|
||||
return String::null;
|
||||
return d->itemListMap["ALBUM"].toString();
|
||||
}
|
||||
|
||||
String APE::Tag::comment() const
|
||||
{
|
||||
if(d->itemListMap["COMMENT"].isEmpty())
|
||||
return String::null;
|
||||
return d->itemListMap["COMMENT"].toString();
|
||||
}
|
||||
|
||||
String APE::Tag::genre() const
|
||||
{
|
||||
if(d->itemListMap["GENRE"].isEmpty())
|
||||
return String::null;
|
||||
return d->itemListMap["GENRE"].toString();
|
||||
}
|
||||
|
||||
TagLib::uint APE::Tag::year() const
|
||||
{
|
||||
if(d->itemListMap["YEAR"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["YEAR"].toString().toInt();
|
||||
}
|
||||
|
||||
TagLib::uint APE::Tag::track() const
|
||||
{
|
||||
if(d->itemListMap["TRACK"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["TRACK"].toString().toInt();
|
||||
}
|
||||
|
||||
float APE::Tag::rgAlbumGain() const
|
||||
{
|
||||
if (d->itemListMap["REPLAYGAIN_ALBUM_GAIN"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["REPLAYGAIN_ALBUM_GAIN"].toString().toFloat();
|
||||
}
|
||||
|
||||
float APE::Tag::rgAlbumPeak() const
|
||||
{
|
||||
if (d->itemListMap["REPLAYGAIN_ALBUM_PEAK"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["REPLAYGAIN_ALBUM_PEAK"].toString().toFloat();
|
||||
}
|
||||
|
||||
float APE::Tag::rgTrackGain() const
|
||||
{
|
||||
if (d->itemListMap["REPLAYGAIN_TRACK_GAIN"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["REPLAYGAIN_TRACK_GAIN"].toString().toFloat();
|
||||
}
|
||||
|
||||
float APE::Tag::rgTrackPeak() const
|
||||
{
|
||||
if (d->itemListMap["REPLAYGAIN_TRACK_PEAK"].isEmpty())
|
||||
return 0;
|
||||
return d->itemListMap["REPLAYGAIN_TRACK_PEAK"].toString().toFloat();
|
||||
}
|
||||
|
||||
void APE::Tag::setTitle(const String &s)
|
||||
{
|
||||
addValue("TITLE", s, true);
|
||||
}
|
||||
|
||||
void APE::Tag::setArtist(const String &s)
|
||||
{
|
||||
addValue("ARTIST", s, true);
|
||||
}
|
||||
|
||||
void APE::Tag::setAlbum(const String &s)
|
||||
{
|
||||
addValue("ALBUM", s, true);
|
||||
}
|
||||
|
||||
void APE::Tag::setComment(const String &s)
|
||||
{
|
||||
addValue("COMMENT", s, true);
|
||||
}
|
||||
|
||||
void APE::Tag::setGenre(const String &s)
|
||||
{
|
||||
addValue("GENRE", s, true);
|
||||
}
|
||||
|
||||
void APE::Tag::setYear(uint i)
|
||||
{
|
||||
if(i <= 0)
|
||||
removeItem("YEAR");
|
||||
else
|
||||
addValue("YEAR", String::number(i), true);
|
||||
}
|
||||
|
||||
void APE::Tag::setTrack(uint i)
|
||||
{
|
||||
if(i <= 0)
|
||||
removeItem("TRACK");
|
||||
else
|
||||
addValue("TRACK", String::number(i), true);
|
||||
}
|
||||
|
||||
void APE::Tag::setRGAlbumGain(float f)
|
||||
{
|
||||
if (f == 0)
|
||||
removeItem("REPLAYGAIN_ALBUM_GAIN");
|
||||
else
|
||||
addValue("REPLAYGAIN_ALBUM_GAIN", String::number(f) + " dB", true);
|
||||
}
|
||||
|
||||
void APE::Tag::setRGAlbumPeak(float f)
|
||||
{
|
||||
if (f == 0)
|
||||
removeItem("REPLAYGAIN_ALBUM_PEAK");
|
||||
else
|
||||
addValue("REPLAYGAIN_ALBUM_PEAK", String::number(f), true);
|
||||
}
|
||||
|
||||
void APE::Tag::setRGTrackGain(float f)
|
||||
{
|
||||
if (f == 0)
|
||||
removeItem("REPLAYGAIN_TRACK_GAIN");
|
||||
else
|
||||
addValue("REPLAYGAIN_TRACK_GAIN", String::number(f) + " dB", true);
|
||||
}
|
||||
|
||||
void APE::Tag::setRGTrackPeak(float f)
|
||||
{
|
||||
if (f == 0)
|
||||
removeItem("REPLAYGAIN_TRACK_PEAK");
|
||||
else
|
||||
addValue("REPLAYGAIN_TRACK_PEAK", String::number(f), true);
|
||||
}
|
||||
|
||||
APE::Footer *APE::Tag::footer() const
|
||||
{
|
||||
return &d->footer;
|
||||
}
|
||||
|
||||
const APE::ItemListMap& APE::Tag::itemListMap() const
|
||||
{
|
||||
return d->itemListMap;
|
||||
}
|
||||
|
||||
void APE::Tag::removeItem(const String &key)
|
||||
{
|
||||
Map<const String, Item>::Iterator it = d->itemListMap.find(key.upper());
|
||||
if(it != d->itemListMap.end())
|
||||
d->itemListMap.erase(it);
|
||||
}
|
||||
|
||||
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);
|
||||
else
|
||||
setItem(key, Item(key, value));
|
||||
}
|
||||
}
|
||||
|
||||
void APE::Tag::setItem(const String &key, const Item &item)
|
||||
{
|
||||
d->itemListMap.insert(key.upper(), item);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected methods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void APE::Tag::read()
|
||||
{
|
||||
if(d->file && d->file->isValid()) {
|
||||
|
||||
d->file->seek(d->footerLocation);
|
||||
d->footer.setData(d->file->readBlock(Footer::size()));
|
||||
|
||||
if(d->footer.tagSize() <= Footer::size() ||
|
||||
d->footer.tagSize() > uint(d->file->length()))
|
||||
return;
|
||||
|
||||
d->file->seek(d->footerLocation + Footer::size() - d->footer.tagSize());
|
||||
parse(d->file->readBlock(d->footer.tagSize() - Footer::size()));
|
||||
}
|
||||
}
|
||||
|
||||
ByteVector APE::Tag::render() const
|
||||
{
|
||||
ByteVector data;
|
||||
uint itemCount = 0;
|
||||
|
||||
{
|
||||
for(Map<const String, Item>::ConstIterator it = d->itemListMap.begin();
|
||||
it != d->itemListMap.end(); ++it)
|
||||
{
|
||||
data.append(it->second.render());
|
||||
itemCount++;
|
||||
}
|
||||
}
|
||||
|
||||
d->footer.setItemCount(itemCount);
|
||||
d->footer.setTagSize(data.size() + Footer::size());
|
||||
d->footer.setHeaderPresent(true);
|
||||
|
||||
return d->footer.renderHeader() + data + d->footer.renderFooter();
|
||||
}
|
||||
|
||||
void APE::Tag::parse(const ByteVector &data)
|
||||
{
|
||||
uint pos = 0;
|
||||
|
||||
// 11 bytes is the minimum size for an APE item
|
||||
|
||||
for(uint i = 0; i < d->footer.itemCount() && pos <= data.size() - 11; i++) {
|
||||
APE::Item item;
|
||||
item.parse(data.mid(pos));
|
||||
|
||||
d->itemListMap.insert(item.key().upper(), item);
|
||||
|
||||
pos += item.size();
|
||||
}
|
||||
}
|
|
@ -1,170 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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_APETAG_H
|
||||
#define TAGLIB_APETAG_H
|
||||
|
||||
#include "tag.h"
|
||||
#include "tbytevector.h"
|
||||
#include "tmap.h"
|
||||
#include "tstring.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
#include "apeitem.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class File;
|
||||
|
||||
//! An implementation of the APE tagging format
|
||||
|
||||
namespace APE {
|
||||
|
||||
class Footer;
|
||||
|
||||
/*!
|
||||
* A mapping between a list of item names, or keys, and the associated item.
|
||||
*
|
||||
* \see APE::Tag::itemListMap()
|
||||
*/
|
||||
typedef Map<const String, Item> ItemListMap;
|
||||
|
||||
|
||||
//! An APE tag implementation
|
||||
|
||||
class TAGLIB_EXPORT Tag : public TagLib::Tag
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Create an APE tag with default values.
|
||||
*/
|
||||
Tag();
|
||||
|
||||
/*!
|
||||
* Create an APE tag and parse the data in \a file with APE footer at
|
||||
* \a tagOffset.
|
||||
*/
|
||||
Tag(TagLib::File *file, long footerLocation);
|
||||
|
||||
/*!
|
||||
* Destroys this Tag instance.
|
||||
*/
|
||||
virtual ~Tag();
|
||||
|
||||
/*!
|
||||
* Renders the in memory values to a ByteVector suitable for writing to
|
||||
* the file.
|
||||
*/
|
||||
ByteVector render() const;
|
||||
|
||||
/*!
|
||||
* Returns the string "APETAGEX" suitable for usage in locating the tag in a
|
||||
* file.
|
||||
*/
|
||||
static ByteVector fileIdentifier();
|
||||
|
||||
// Reimplementations.
|
||||
|
||||
virtual String title() const;
|
||||
virtual String artist() const;
|
||||
virtual String album() const;
|
||||
virtual String comment() const;
|
||||
virtual String genre() const;
|
||||
virtual uint year() const;
|
||||
virtual uint track() const;
|
||||
virtual float rgAlbumGain() const;
|
||||
virtual float rgAlbumPeak() const;
|
||||
virtual float rgTrackGain() const;
|
||||
virtual float rgTrackPeak() const;
|
||||
|
||||
virtual void setTitle(const String &s);
|
||||
virtual void setArtist(const String &s);
|
||||
virtual void setAlbum(const String &s);
|
||||
virtual void setComment(const String &s);
|
||||
virtual void setGenre(const String &s);
|
||||
virtual void setYear(uint i);
|
||||
virtual void setTrack(uint i);
|
||||
virtual void setRGAlbumGain(float f);
|
||||
virtual void setRGAlbumPeak(float f);
|
||||
virtual void setRGTrackGain(float f);
|
||||
virtual void setRGTrackPeak(float f);
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the tag's footer.
|
||||
*/
|
||||
Footer *footer() const;
|
||||
|
||||
/*!
|
||||
* Returns a reference to the item list map. This is an ItemListMap of
|
||||
* all of the items in the tag.
|
||||
*
|
||||
* This is the most powerfull structure for accessing the items of the tag.
|
||||
*
|
||||
* \warning You should not modify this data structure directly, instead
|
||||
* use setItem() and removeItem().
|
||||
*/
|
||||
const ItemListMap &itemListMap() const;
|
||||
|
||||
/*!
|
||||
* Removes the \a key item from the tag
|
||||
*/
|
||||
void removeItem(const String &key);
|
||||
|
||||
/*!
|
||||
* Adds to the 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.
|
||||
*/
|
||||
void addValue(const String &key, const String &value, bool replace = true);
|
||||
|
||||
/*!
|
||||
* 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);
|
||||
|
||||
protected:
|
||||
|
||||
/*!
|
||||
* Reads from the file specified in the constructor.
|
||||
*/
|
||||
void read();
|
||||
|
||||
/*!
|
||||
* Parses the body of the tag in \a data.
|
||||
*/
|
||||
void parse(const ByteVector &data);
|
||||
|
||||
private:
|
||||
Tag(const Tag &);
|
||||
Tag &operator=(const Tag &);
|
||||
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,338 +0,0 @@
|
|||
/**************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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()
|
||||
: stream(0),
|
||||
language(0) {}
|
||||
AttributeTypes type;
|
||||
String stringValue;
|
||||
ByteVector byteVectorValue;
|
||||
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(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
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
String
|
||||
ASF::Attribute::parse(ASF::File &f, int kind)
|
||||
{
|
||||
int size, nameLength;
|
||||
String name;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
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:
|
||||
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:
|
||||
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;
|
||||
}
|
|
@ -1,184 +0,0 @@
|
|||
/**************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
|
||||
namespace ASF
|
||||
{
|
||||
|
||||
class File;
|
||||
|
||||
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 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 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
|
|
@ -1,559 +0,0 @@
|
|||
/**************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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);
|
||||
|
||||
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;
|
||||
ByteVector guid();
|
||||
void parse(ASF::File *file, uint size);
|
||||
ByteVector render(ASF::File *file);
|
||||
};
|
||||
|
||||
void
|
||||
ASF::File::BaseObject::parse(ASF::File *file, unsigned int size)
|
||||
{
|
||||
data = file->readBlock(size - 24);
|
||||
}
|
||||
|
||||
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);
|
||||
long long size = file->readQWORD();
|
||||
BaseObject *obj;
|
||||
if(guid == metadataGuid) {
|
||||
obj = new MetadataObject();
|
||||
}
|
||||
else if(guid == metadataLibraryGuid) {
|
||||
obj = new MetadataLibraryObject();
|
||||
}
|
||||
else {
|
||||
obj = new UnknownObject(guid);
|
||||
}
|
||||
obj->parse(file, 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()
|
||||
{
|
||||
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.");
|
||||
return;
|
||||
}
|
||||
|
||||
d->tag = new ASF::Tag();
|
||||
d->properties = new ASF::Properties();
|
||||
|
||||
d->size = readQWORD();
|
||||
int numObjects = readDWORD();
|
||||
seek(2, Current);
|
||||
|
||||
for(int i = 0; i < numObjects; i++) {
|
||||
ByteVector guid = readBlock(16);
|
||||
long size = (long)readQWORD();
|
||||
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 {
|
||||
obj = new UnknownObject(guid);
|
||||
}
|
||||
obj->parse(this, size);
|
||||
d->objects.append(obj);
|
||||
}
|
||||
}
|
||||
|
||||
bool ASF::File::save()
|
||||
{
|
||||
if(readOnly()) {
|
||||
debug("ASF: File is read-only.");
|
||||
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, d->size);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int ASF::File::readBYTE()
|
||||
{
|
||||
ByteVector v = readBlock(1);
|
||||
return v[0];
|
||||
}
|
||||
|
||||
int ASF::File::readWORD()
|
||||
{
|
||||
ByteVector v = readBlock(2);
|
||||
return v.toShort(false);
|
||||
}
|
||||
|
||||
unsigned int ASF::File::readDWORD()
|
||||
{
|
||||
ByteVector v = readBlock(4);
|
||||
return v.toUInt(false);
|
||||
}
|
||||
|
||||
long long ASF::File::readQWORD()
|
||||
{
|
||||
ByteVector v = readBlock(8);
|
||||
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;
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
/**************************************************************************
|
||||
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
|
||||
|
||||
#ifdef WITH_ASF
|
||||
|
||||
#include <taglib.h>
|
||||
#include <tdebug.h>
|
||||
#include "asfattribute.h"
|
||||
#include "asffile.h"
|
||||
#include "asfpicture.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class ASF::Picture::PicturePriavte : public RefCounter
|
||||
{
|
||||
public:
|
||||
bool valid;
|
||||
Type type;
|
||||
String mimeType;
|
||||
String description;
|
||||
ByteVector picture;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Picture class members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ASF::Picture::Picture()
|
||||
{
|
||||
d = new PicturePriavte();
|
||||
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;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
***************************************************************************/
|
||||
/**************************************************************************
|
||||
copyright : (C) 2010 by Anton Sergunov
|
||||
email : setosha@gmail.com
|
||||
**************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
|
@ -15,38 +15,38 @@
|
|||
* *
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_ATTACHEDPICTUREFRAME_H
|
||||
#define TAGLIB_ATTACHEDPICTUREFRAME_H
|
||||
#ifndef ASFPICTURE_H
|
||||
#define ASFPICTURE_H
|
||||
|
||||
#include "id3v2frame.h"
|
||||
#include "id3v2header.h"
|
||||
#include "tstring.h"
|
||||
#include "tbytevector.h"
|
||||
#include "taglib_export.h"
|
||||
#include "attachedpictureframe.h"
|
||||
|
||||
namespace TagLib {
|
||||
namespace TagLib
|
||||
{
|
||||
namespace ASF
|
||||
{
|
||||
|
||||
namespace ID3v2 {
|
||||
|
||||
//! An ID3v2 attached picture frame implementation
|
||||
//! An ASF attached picture interface implementation
|
||||
|
||||
/*!
|
||||
* This is an implementation of ID3v2 attached pictures. Pictures may be
|
||||
* included in tags, one per APIC frame (but there may be multiple APIC
|
||||
* frames in a single tag). These pictures are usually in either JPEG or
|
||||
* 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 AttachedPictureFrame : public Frame
|
||||
{
|
||||
friend class FrameFactory;
|
||||
|
||||
class TAGLIB_EXPORT Picture {
|
||||
public:
|
||||
|
||||
/*!
|
||||
|
@ -98,52 +98,47 @@ namespace TagLib {
|
|||
};
|
||||
|
||||
/*!
|
||||
* Constructs an empty picture frame. The description, content and text
|
||||
* encoding should be set manually.
|
||||
* Constructs an empty picture.
|
||||
*/
|
||||
AttachedPictureFrame();
|
||||
Picture();
|
||||
|
||||
/*!
|
||||
* Constructs an AttachedPicture frame based on \a data.
|
||||
* Construct an picture as a copy of \a other.
|
||||
*/
|
||||
explicit AttachedPictureFrame(const ByteVector &data);
|
||||
Picture(const Picture& other);
|
||||
|
||||
/*!
|
||||
* Destroys the AttahcedPictureFrame instance.
|
||||
* Destroys the picture.
|
||||
*/
|
||||
virtual ~AttachedPictureFrame();
|
||||
virtual ~Picture();
|
||||
|
||||
/*!
|
||||
* Returns a string containing the description and mime-type
|
||||
* Copies the contents of \a other into this picture.
|
||||
*/
|
||||
virtual String toString() const;
|
||||
Picture& operator=(const Picture& other);
|
||||
|
||||
/*!
|
||||
* Returns the text encoding used for the description.
|
||||
*
|
||||
* \see setTextEncoding()
|
||||
* \see description()
|
||||
* Returns true if Picture stores valid picture
|
||||
*/
|
||||
String::Type textEncoding() const;
|
||||
bool isValid() const;
|
||||
|
||||
/*!
|
||||
* Set the text encoding used for the description.
|
||||
*
|
||||
* \see description()
|
||||
*/
|
||||
void setTextEncoding(String::Type t);
|
||||
|
||||
/*!
|
||||
* Returns the mime type of the image. This should in most cases be
|
||||
* 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 &m);
|
||||
void setMimeType(const String &value);
|
||||
|
||||
/*!
|
||||
* Returns the type of the image.
|
||||
|
@ -159,26 +154,20 @@ namespace TagLib {
|
|||
* \see Type
|
||||
* \see type()
|
||||
*/
|
||||
void setType(Type t);
|
||||
void setType(const ASF::Picture::Type& t);
|
||||
|
||||
/*!
|
||||
* Returns a text description of the image.
|
||||
*
|
||||
* \see setDescription()
|
||||
* \see textEncoding()
|
||||
* \see setTextEncoding()
|
||||
*/
|
||||
|
||||
String description() const;
|
||||
|
||||
/*!
|
||||
* Sets a textual description of the image to \a desc.
|
||||
*
|
||||
* \see description()
|
||||
* \see textEncoding()
|
||||
* \see setTextEncoding()
|
||||
*/
|
||||
|
||||
void setDescription(const String &desc);
|
||||
|
||||
/*!
|
||||
|
@ -202,19 +191,27 @@ namespace TagLib {
|
|||
*/
|
||||
void setPicture(const ByteVector &p);
|
||||
|
||||
protected:
|
||||
virtual void parseFields(const ByteVector &data);
|
||||
virtual ByteVector renderFields() const;
|
||||
/*!
|
||||
* Returns picture as binary raw data \a value
|
||||
*/
|
||||
ByteVector render() const;
|
||||
|
||||
private:
|
||||
AttachedPictureFrame(const ByteVector &data, Header *h);
|
||||
AttachedPictureFrame(const AttachedPictureFrame &);
|
||||
AttachedPictureFrame &operator=(const AttachedPictureFrame &);
|
||||
/*!
|
||||
* Returns picture as binary raw data \a value
|
||||
*/
|
||||
int dataSize() const;
|
||||
|
||||
class AttachedPictureFramePrivate;
|
||||
AttachedPictureFramePrivate *d;
|
||||
};
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
/* THIS IS PRIVATE, DON'T TOUCH IT! */
|
||||
void parse(const ByteVector& );
|
||||
static Picture fromInvalid();
|
||||
friend class Attribute;
|
||||
#endif
|
||||
private:
|
||||
struct PicturePriavte;
|
||||
PicturePriavte *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // ASFPICTURE_H
|
|
@ -1,259 +0,0 @@
|
|||
/**************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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;
|
||||
}
|
||||
|
||||
float
|
||||
ASF::Tag::rgAlbumGain() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
ASF::Tag::rgAlbumPeak() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
ASF::Tag::rgTrackGain() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
float
|
||||
ASF::Tag::rgTrackPeak() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
void
|
||||
ASF::Tag::setRGAlbumGain(float)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ASF::Tag::setRGAlbumPeak(float)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ASF::Tag::setRGTrackGain(float)
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ASF::Tag::setRGTrackPeak(float)
|
||||
{
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
|
@ -1,196 +0,0 @@
|
|||
/**************************************************************************
|
||||
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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;
|
||||
|
||||
virtual float rgAlbumGain() const;
|
||||
virtual float rgAlbumPeak() const;
|
||||
virtual float rgTrackGain() const;
|
||||
virtual float rgTrackPeak() 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);
|
||||
|
||||
virtual void setRGAlbumGain(float f);
|
||||
virtual void setRGAlbumPeak(float f);
|
||||
virtual void setRGTrackGain(float f);
|
||||
virtual void setRGTrackPeak(float f);
|
||||
|
||||
/*!
|
||||
* 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
|
|
@ -1,110 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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_AUDIOPROPERTIES_H
|
||||
#define TAGLIB_AUDIOPROPERTIES_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
//! A simple, abstract interface to common audio properties
|
||||
|
||||
/*!
|
||||
* The values here are common to most audio formats. For more specific, codec
|
||||
* dependant values, please see see the subclasses APIs. This is meant to
|
||||
* compliment the TagLib::File and TagLib::Tag APIs in providing a simple
|
||||
* interface that is sufficient for most applications.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT AudioProperties
|
||||
{
|
||||
public:
|
||||
|
||||
/*!
|
||||
* Reading audio properties from a file can sometimes be very time consuming
|
||||
* and for the most accurate results can often involve reading the entire
|
||||
* file. Because in many situations speed is critical or the accuracy of the
|
||||
* values is not particularly important this allows the level of desired
|
||||
* accuracy to be set.
|
||||
*/
|
||||
enum ReadStyle {
|
||||
//! Read as little of the file as possible
|
||||
Fast,
|
||||
//! Read more of the file and make better values guesses
|
||||
Average,
|
||||
//! Read as much of the file as needed to report accurate values
|
||||
Accurate
|
||||
};
|
||||
|
||||
/*!
|
||||
* Destroys this AudioProperties instance.
|
||||
*/
|
||||
virtual ~AudioProperties();
|
||||
|
||||
/*!
|
||||
* Returns the length of the file in seconds.
|
||||
*/
|
||||
virtual int length() const = 0;
|
||||
|
||||
/*!
|
||||
* Returns the most appropriate bit rate for the file in kb/s. For constant
|
||||
* bitrate formats this is simply the bitrate of the file. For variable
|
||||
* bitrate formats this is either the average or nominal bitrate.
|
||||
*/
|
||||
virtual int bitrate() const = 0;
|
||||
|
||||
/*!
|
||||
* Returns the sample rate in Hz.
|
||||
*/
|
||||
virtual int sampleRate() const = 0;
|
||||
|
||||
/*!
|
||||
* Returns the number of audio channels.
|
||||
*/
|
||||
virtual int channels() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/*!
|
||||
* Construct an audio properties instance. This is protected as this class
|
||||
* should not be instantiated directly, but should be instantiated via its
|
||||
* subclasses and can be fetched from the FileRef or File APIs.
|
||||
*
|
||||
* \see ReadStyle
|
||||
*/
|
||||
AudioProperties(ReadStyle style);
|
||||
|
||||
private:
|
||||
AudioProperties(const AudioProperties &);
|
||||
AudioProperties &operator=(const AudioProperties &);
|
||||
|
||||
class AudioPropertiesPrivate;
|
||||
AudioPropertiesPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,246 +0,0 @@
|
|||
/***************************************************************************
|
||||
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)
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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 <tfile.h>
|
||||
#include <tstring.h>
|
||||
|
||||
#include "fileref.h"
|
||||
#include "asffile.h"
|
||||
#include "mpegfile.h"
|
||||
#include "vorbisfile.h"
|
||||
#include "flacfile.h"
|
||||
#include "oggflacfile.h"
|
||||
#include "mpcfile.h"
|
||||
#include "wavpackfile.h"
|
||||
#include "speexfile.h"
|
||||
#include "opusfile.h"
|
||||
#include "trueaudiofile.h"
|
||||
#include "mp4file.h"
|
||||
#include "apefile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class FileRef::FileRefPrivate : public RefCounter
|
||||
{
|
||||
public:
|
||||
FileRefPrivate(File *f) : RefCounter(), file(f) {}
|
||||
~FileRefPrivate() {
|
||||
delete file;
|
||||
}
|
||||
|
||||
File *file;
|
||||
static List<const FileTypeResolver *> fileTypeResolvers;
|
||||
};
|
||||
|
||||
List<const FileRef::FileTypeResolver *> FileRef::FileRefPrivate::fileTypeResolvers;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FileRef::FileRef()
|
||||
{
|
||||
d = new FileRefPrivate(0);
|
||||
}
|
||||
|
||||
FileRef::FileRef(FileName fileName, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle)
|
||||
{
|
||||
d = new FileRefPrivate(create(fileName, readAudioProperties, audioPropertiesStyle));
|
||||
}
|
||||
|
||||
FileRef::FileRef(File *file)
|
||||
{
|
||||
d = new FileRefPrivate(file);
|
||||
}
|
||||
|
||||
FileRef::FileRef(const FileRef &ref) : d(ref.d)
|
||||
{
|
||||
d->ref();
|
||||
}
|
||||
|
||||
FileRef::~FileRef()
|
||||
{
|
||||
if(d->deref())
|
||||
delete d;
|
||||
}
|
||||
|
||||
Tag *FileRef::tag() const
|
||||
{
|
||||
return d->file->tag();
|
||||
}
|
||||
|
||||
AudioProperties *FileRef::audioProperties() const
|
||||
{
|
||||
return d->file->audioProperties();
|
||||
}
|
||||
|
||||
File *FileRef::file() const
|
||||
{
|
||||
return d->file;
|
||||
}
|
||||
|
||||
bool FileRef::save()
|
||||
{
|
||||
return d->file->save();
|
||||
}
|
||||
|
||||
const FileRef::FileTypeResolver *FileRef::addFileTypeResolver(const FileRef::FileTypeResolver *resolver) // static
|
||||
{
|
||||
FileRefPrivate::fileTypeResolvers.prepend(resolver);
|
||||
return resolver;
|
||||
}
|
||||
|
||||
StringList FileRef::defaultFileExtensions()
|
||||
{
|
||||
StringList l;
|
||||
|
||||
l.append("ogg");
|
||||
l.append("flac");
|
||||
l.append("oga");
|
||||
l.append("mp3");
|
||||
l.append("mpc");
|
||||
l.append("wv");
|
||||
l.append("spx");
|
||||
l.append("tta");
|
||||
l.append("m4a");
|
||||
l.append("m4b");
|
||||
l.append("m4p");
|
||||
l.append("3g2");
|
||||
l.append("mp4");
|
||||
l.append("wma");
|
||||
l.append("asf");
|
||||
l.append("ape");
|
||||
l.append("opus");
|
||||
l.append("tak");
|
||||
l.append("ac3");
|
||||
l.append("apl");
|
||||
l.append("dts");
|
||||
l.append("dtshd");
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
bool FileRef::isNull() const
|
||||
{
|
||||
return !d->file || !d->file->isValid();
|
||||
}
|
||||
|
||||
FileRef &FileRef::operator=(const FileRef &ref)
|
||||
{
|
||||
if(&ref == this)
|
||||
return *this;
|
||||
|
||||
if(d->deref())
|
||||
delete d;
|
||||
|
||||
d = ref.d;
|
||||
d->ref();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool FileRef::operator==(const FileRef &ref) const
|
||||
{
|
||||
return ref.d->file == d->file;
|
||||
}
|
||||
|
||||
bool FileRef::operator!=(const FileRef &ref) const
|
||||
{
|
||||
return ref.d->file != d->file;
|
||||
}
|
||||
|
||||
File *FileRef::create(FileName fileName, bool readAudioProperties,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle) // static
|
||||
{
|
||||
|
||||
List<const FileTypeResolver *>::ConstIterator it = FileRefPrivate::fileTypeResolvers.begin();
|
||||
|
||||
for(; it != FileRefPrivate::fileTypeResolvers.end(); ++it) {
|
||||
File *file = (*it)->createFile(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(file)
|
||||
return file;
|
||||
}
|
||||
|
||||
// Ok, this is really dumb for now, but it works for testing.
|
||||
|
||||
String s;
|
||||
|
||||
#ifdef _WIN32
|
||||
s = (wcslen((const wchar_t *) fileName) > 0) ? String((const wchar_t *) fileName) : String((const char *) fileName);
|
||||
#else
|
||||
s = fileName;
|
||||
#endif
|
||||
|
||||
// If this list is updated, the method defaultFileExtensions() should also be
|
||||
// updated. However at some point that list should be created at the same time
|
||||
// that a default file type resolver is created.
|
||||
|
||||
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(ext == "OGG")
|
||||
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "OGA") {
|
||||
File *file = new Ogg::FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if (file->isValid())
|
||||
return file;
|
||||
delete file;
|
||||
file = new Ogg::Opus::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if (file->isValid())
|
||||
return file;
|
||||
delete file;
|
||||
return new Ogg::Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
}
|
||||
if (ext == "OPUS")
|
||||
return new Ogg::Opus::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "FLAC")
|
||||
return new FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "MPC")
|
||||
return new MPC::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "WV")
|
||||
return new WavPack::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "SPX")
|
||||
return new Ogg::Speex::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "TTA")
|
||||
return new TrueAudio::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "M4A" || 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 == "APE")
|
||||
return new APE::File(fileName, readAudioProperties, audioPropertiesStyle);
|
||||
if(ext == "TAK" || ext == "AC3" || ext == "APL" || ext == "DTS" || ext == "DTSHD")
|
||||
return new APE::File(fileName, false, audioPropertiesStyle);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,264 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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_FILEREF_H
|
||||
#define TAGLIB_FILEREF_H
|
||||
|
||||
#include "tfile.h"
|
||||
#include "tstringlist.h"
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class Tag;
|
||||
|
||||
//! This class provides a simple abstraction for creating and handling files
|
||||
|
||||
/*!
|
||||
* FileRef exists to provide a minimal, generic and value-based wrapper around
|
||||
* a File. It is lightweight and implicitly shared, and as such suitable for
|
||||
* pass-by-value use. This hides some of the uglier details of TagLib::File
|
||||
* and the non-generic portions of the concrete file implementations.
|
||||
*
|
||||
* This class is useful in a "simple usage" situation where it is desirable
|
||||
* to be able to get and set some of the tag information that is similar
|
||||
* across file types.
|
||||
*
|
||||
* Also note that it is probably a good idea to plug this into your mime
|
||||
* type system rather than using the constructor that accepts a file name using
|
||||
* the FileTypeResolver.
|
||||
*
|
||||
* \see FileTypeResolver
|
||||
* \see addFileTypeResolver()
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT FileRef
|
||||
{
|
||||
public:
|
||||
|
||||
//! A class for pluggable file type resolution.
|
||||
|
||||
/*!
|
||||
* This class is used to add extend TagLib's very basic file name based file
|
||||
* type resolution.
|
||||
*
|
||||
* This can be accomplished with:
|
||||
*
|
||||
* \code
|
||||
*
|
||||
* class MyFileTypeResolver : FileTypeResolver
|
||||
* {
|
||||
* TagLib::File *createFile(TagLib::FileName *fileName, bool, AudioProperties::ReadStyle)
|
||||
* {
|
||||
* if(someCheckForAnMP3File(fileName))
|
||||
* return new TagLib::MPEG::File(fileName);
|
||||
* return 0;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* FileRef::addFileTypeResolver(new MyFileTypeResolver);
|
||||
*
|
||||
* \endcode
|
||||
*
|
||||
* Naturally a less contrived example would be slightly more complex. This
|
||||
* can be used to plug in mime-type detection systems or to add new file types
|
||||
* to TagLib.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT FileTypeResolver
|
||||
{
|
||||
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
|
||||
* return a valid File object; if not it should return 0.
|
||||
*
|
||||
* \note The created file is then owned by the FileRef and should not be
|
||||
* deleted. Deletion will happen automatically when the FileRef passes
|
||||
* out of scope.
|
||||
*/
|
||||
virtual File *createFile(FileName fileName,
|
||||
bool readAudioProperties = true,
|
||||
AudioProperties::ReadStyle
|
||||
audioPropertiesStyle = AudioProperties::Average) const = 0;
|
||||
|
||||
virtual ~FileTypeResolver() { }
|
||||
};
|
||||
|
||||
/*!
|
||||
* Creates a null FileRef.
|
||||
*/
|
||||
FileRef();
|
||||
|
||||
/*!
|
||||
* Create a FileRef from \a fileName. If \a readAudioProperties is true then
|
||||
* the audio properties will be read using \a audioPropertiesStyle. If
|
||||
* \a readAudioProperties is false then \a audioPropertiesStyle will be
|
||||
* ignored.
|
||||
*
|
||||
* Also see the note in the class documentation about why you may not want to
|
||||
* use this method in your application.
|
||||
*/
|
||||
explicit FileRef(FileName fileName,
|
||||
bool readAudioProperties = true,
|
||||
AudioProperties::ReadStyle
|
||||
audioPropertiesStyle = AudioProperties::Average);
|
||||
|
||||
/*!
|
||||
* Contruct a FileRef using \a file. The FileRef now takes ownership of the
|
||||
* pointer and will delete the File when it passes out of scope.
|
||||
*/
|
||||
explicit FileRef(File *file);
|
||||
|
||||
/*!
|
||||
* Make a copy of \a ref.
|
||||
*/
|
||||
FileRef(const FileRef &ref);
|
||||
|
||||
/*!
|
||||
* Destroys this FileRef instance.
|
||||
*/
|
||||
virtual ~FileRef();
|
||||
|
||||
/*!
|
||||
* Returns a pointer to represented file's tag.
|
||||
*
|
||||
* \warning This pointer will become invalid when this FileRef and all
|
||||
* copies pass out of scope.
|
||||
*
|
||||
* \see File::tag()
|
||||
*/
|
||||
Tag *tag() const;
|
||||
|
||||
/*!
|
||||
* Returns the audio properties for this FileRef. If no audio properties
|
||||
* were read then this will returns a null pointer.
|
||||
*/
|
||||
AudioProperties *audioProperties() const;
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the file represented by this handler class.
|
||||
*
|
||||
* As a general rule this call should be avoided since if you need to work
|
||||
* with file objects directly, you are probably better served instantiating
|
||||
* the File subclasses (i.e. MPEG::File) manually and working with their APIs.
|
||||
*
|
||||
* This <i>handle</i> exists to provide a minimal, generic and value-based
|
||||
* wrapper around a File. Accessing the file directly generally indicates
|
||||
* a moving away from this simplicity (and into things beyond the scope of
|
||||
* FileRef).
|
||||
*
|
||||
* \warning This pointer will become invalid when this FileRef and all
|
||||
* copies pass out of scope.
|
||||
*/
|
||||
File *file() const;
|
||||
|
||||
/*!
|
||||
* Saves the file. Returns true on success.
|
||||
*/
|
||||
bool save();
|
||||
|
||||
/*!
|
||||
* Adds a FileTypeResolver to the list of those used by TagLib. Each
|
||||
* additional FileTypeResolver is added to the front of a list of resolvers
|
||||
* that are tried. If the FileTypeResolver returns zero the next resolver
|
||||
* is tried.
|
||||
*
|
||||
* Returns a pointer to the added resolver (the same one that's passed in --
|
||||
* this is mostly so that static inialializers have something to use for
|
||||
* assignment).
|
||||
*
|
||||
* \see FileTypeResolver
|
||||
*/
|
||||
static const FileTypeResolver *addFileTypeResolver(const FileTypeResolver *resolver);
|
||||
|
||||
/*!
|
||||
* As is mentioned elsewhere in this class's documentation, the default file
|
||||
* type resolution code provided by TagLib only works by comparing file
|
||||
* extensions.
|
||||
*
|
||||
* This method returns the list of file extensions that are used by default.
|
||||
*
|
||||
* The extensions are all returned in lowercase, though the comparison used
|
||||
* by TagLib for resolution is case-insensitive.
|
||||
*
|
||||
* \note This does not account for any additional file type resolvers that
|
||||
* are plugged in. Also note that this is not intended to replace a propper
|
||||
* mime-type resolution system, but is just here for reference.
|
||||
*
|
||||
* \see FileTypeResolver
|
||||
*/
|
||||
static StringList defaultFileExtensions();
|
||||
|
||||
/*!
|
||||
* Returns true if the file (and as such other pointers) are null.
|
||||
*/
|
||||
bool isNull() const;
|
||||
|
||||
/*!
|
||||
* Assign the file pointed to by \a ref to this FileRef.
|
||||
*/
|
||||
FileRef &operator=(const FileRef &ref);
|
||||
|
||||
/*!
|
||||
* Returns true if this FileRef and \a ref point to the same File object.
|
||||
*/
|
||||
bool operator==(const FileRef &ref) const;
|
||||
|
||||
/*!
|
||||
* Returns true if this FileRef and \a ref do not point to the same File
|
||||
* object.
|
||||
*/
|
||||
bool operator!=(const FileRef &ref) const;
|
||||
|
||||
/*!
|
||||
* A simple implementation of file type guessing. If \a readAudioProperties
|
||||
* is true then the audio properties will be read using
|
||||
* \a audioPropertiesStyle. If \a readAudioProperties is false then
|
||||
* \a audioPropertiesStyle will be ignored.
|
||||
*
|
||||
* \note You generally shouldn't use this method, but instead the constructor
|
||||
* directly.
|
||||
*
|
||||
* \deprecated
|
||||
*/
|
||||
static File *create(FileName fileName,
|
||||
bool readAudioProperties = true,
|
||||
AudioProperties::ReadStyle audioPropertiesStyle = AudioProperties::Average);
|
||||
|
||||
|
||||
private:
|
||||
class FileRefPrivate;
|
||||
FileRefPrivate *d;
|
||||
};
|
||||
|
||||
} // namespace TagLib
|
||||
|
||||
#endif
|
|
@ -1,431 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2003-2004 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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 <tlist.h>
|
||||
#include <tdebug.h>
|
||||
#include <tagunion.h>
|
||||
|
||||
#include <id3v2header.h>
|
||||
#include <id3v2tag.h>
|
||||
#include <id3v1tag.h>
|
||||
#include <xiphcomment.h>
|
||||
|
||||
#include "flacfile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
namespace
|
||||
{
|
||||
enum { XiphIndex = 0, ID3v2Index = 1, ID3v1Index = 2 };
|
||||
enum { StreamInfo = 0, Padding, Application, SeekTable, VorbisComment, CueSheet };
|
||||
}
|
||||
|
||||
class FLAC::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
FilePrivate() :
|
||||
ID3v2FrameFactory(ID3v2::FrameFactory::instance()),
|
||||
ID3v2Location(-1),
|
||||
ID3v2OriginalSize(0),
|
||||
ID3v1Location(-1),
|
||||
properties(0),
|
||||
flacStart(0),
|
||||
streamStart(0),
|
||||
streamLength(0),
|
||||
scanned(false),
|
||||
hasXiphComment(false),
|
||||
hasID3v2(false),
|
||||
hasID3v1(false) {}
|
||||
|
||||
~FilePrivate()
|
||||
{
|
||||
delete properties;
|
||||
}
|
||||
|
||||
const ID3v2::FrameFactory *ID3v2FrameFactory;
|
||||
long ID3v2Location;
|
||||
uint ID3v2OriginalSize;
|
||||
|
||||
long ID3v1Location;
|
||||
|
||||
TagUnion tag;
|
||||
|
||||
Properties *properties;
|
||||
ByteVector streamInfoData;
|
||||
ByteVector xiphCommentData;
|
||||
|
||||
long flacStart;
|
||||
long streamStart;
|
||||
long streamLength;
|
||||
bool scanned;
|
||||
|
||||
bool hasXiphComment;
|
||||
bool hasID3v2;
|
||||
bool hasID3v1;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FLAC::File::File(FileName file, bool readProperties,
|
||||
Properties::ReadStyle propertiesStyle) :
|
||||
TagLib::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
read(readProperties, propertiesStyle);
|
||||
}
|
||||
|
||||
FLAC::File::File(FileName file, ID3v2::FrameFactory *frameFactory,
|
||||
bool readProperties, Properties::ReadStyle propertiesStyle) :
|
||||
TagLib::File(file)
|
||||
{
|
||||
d = new FilePrivate;
|
||||
d->ID3v2FrameFactory = frameFactory;
|
||||
read(readProperties, propertiesStyle);
|
||||
}
|
||||
|
||||
FLAC::File::~File()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::Tag *FLAC::File::tag() const
|
||||
{
|
||||
return &d->tag;
|
||||
}
|
||||
|
||||
FLAC::Properties *FLAC::File::audioProperties() const
|
||||
{
|
||||
return d->properties;
|
||||
}
|
||||
|
||||
|
||||
bool FLAC::File::save()
|
||||
{
|
||||
if(readOnly()) {
|
||||
debug("FLAC::File::save() - Cannot save to a read only file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create new vorbis comments
|
||||
|
||||
Tag::duplicate(&d->tag, xiphComment(true), true);
|
||||
|
||||
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
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
insert(data, firstBlockOffset + blockLength + 4, 0);
|
||||
d->hasXiphComment = true;
|
||||
}
|
||||
|
||||
// Update ID3 tags
|
||||
|
||||
if(ID3v2Tag()) {
|
||||
if(d->hasID3v2) {
|
||||
if(d->ID3v2Location < d->flacStart)
|
||||
debug("FLAC::File::save() -- This can't be right -- an ID3v2 tag after the "
|
||||
"start of the FLAC bytestream? Not writing the ID3v2 tag.");
|
||||
else
|
||||
insert(ID3v2Tag()->render(), d->ID3v2Location, d->ID3v2OriginalSize);
|
||||
}
|
||||
else
|
||||
insert(ID3v2Tag()->render(), 0, 0);
|
||||
}
|
||||
|
||||
if(ID3v1Tag()) {
|
||||
seek(-128, End);
|
||||
writeBlock(ID3v1Tag()->render());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
ID3v2::Tag *FLAC::File::ID3v2Tag(bool create)
|
||||
{
|
||||
if(!create || d->tag[ID3v2Index])
|
||||
return static_cast<ID3v2::Tag *>(d->tag[ID3v2Index]);
|
||||
|
||||
d->tag.set(ID3v2Index, new ID3v2::Tag);
|
||||
return static_cast<ID3v2::Tag *>(d->tag[ID3v2Index]);
|
||||
}
|
||||
|
||||
ID3v1::Tag *FLAC::File::ID3v1Tag(bool create)
|
||||
{
|
||||
return d->tag.access<ID3v1::Tag>(ID3v1Index, create);
|
||||
}
|
||||
|
||||
Ogg::XiphComment *FLAC::File::xiphComment(bool create)
|
||||
{
|
||||
return d->tag.access<Ogg::XiphComment>(XiphIndex, create);
|
||||
}
|
||||
|
||||
void FLAC::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
|
||||
{
|
||||
d->ID3v2FrameFactory = factory;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
|
||||
{
|
||||
// Look for an ID3v2 tag
|
||||
|
||||
d->ID3v2Location = findID3v2();
|
||||
|
||||
if(d->ID3v2Location >= 0) {
|
||||
|
||||
d->tag.set(ID3v2Index, new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory));
|
||||
|
||||
d->ID3v2OriginalSize = ID3v2Tag()->header()->completeTagSize();
|
||||
|
||||
if(ID3v2Tag()->header()->tagSize() <= 0)
|
||||
d->tag.set(ID3v2Index, 0);
|
||||
else
|
||||
d->hasID3v2 = true;
|
||||
}
|
||||
|
||||
// Look for an ID3v1 tag
|
||||
|
||||
d->ID3v1Location = findID3v1();
|
||||
|
||||
if(d->ID3v1Location >= 0) {
|
||||
d->tag.set(ID3v1Index, new ID3v1::Tag(this, d->ID3v1Location));
|
||||
d->hasID3v1 = true;
|
||||
}
|
||||
|
||||
// Look for FLAC metadata, including vorbis comments
|
||||
|
||||
scan();
|
||||
|
||||
if(!isValid())
|
||||
return;
|
||||
|
||||
if(d->hasXiphComment)
|
||||
d->tag.set(XiphIndex, new Ogg::XiphComment(xiphCommentData()));
|
||||
else
|
||||
d->tag.set(XiphIndex, new Ogg::XiphComment);
|
||||
|
||||
if(readProperties)
|
||||
d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle);
|
||||
}
|
||||
|
||||
ByteVector FLAC::File::streamInfoData()
|
||||
{
|
||||
return isValid() ? d->streamInfoData : ByteVector();
|
||||
}
|
||||
|
||||
ByteVector FLAC::File::xiphCommentData() const
|
||||
{
|
||||
return (isValid() && d->hasXiphComment) ? d->xiphCommentData : ByteVector();
|
||||
}
|
||||
|
||||
long FLAC::File::streamLength()
|
||||
{
|
||||
return d->streamLength;
|
||||
}
|
||||
|
||||
void FLAC::File::scan()
|
||||
{
|
||||
// Scan the metadata pages
|
||||
|
||||
if(d->scanned)
|
||||
return;
|
||||
|
||||
if(!isValid())
|
||||
return;
|
||||
|
||||
long nextBlockOffset;
|
||||
|
||||
if(d->hasID3v2)
|
||||
nextBlockOffset = find("fLaC", d->ID3v2Location + d->ID3v2OriginalSize);
|
||||
else
|
||||
nextBlockOffset = find("fLaC");
|
||||
|
||||
if(nextBlockOffset < 0) {
|
||||
debug("FLAC::File::scan() -- FLAC stream not found");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
nextBlockOffset += 4;
|
||||
d->flacStart = nextBlockOffset;
|
||||
|
||||
seek(nextBlockOffset);
|
||||
|
||||
ByteVector header = readBlock(4);
|
||||
|
||||
// Header format (from spec):
|
||||
// <1> Last-metadata-block flag
|
||||
// <7> BLOCK_TYPE
|
||||
// 0 : STREAMINFO
|
||||
// 1 : PADDING
|
||||
// ..
|
||||
// 4 : VORBIS_COMMENT
|
||||
// ..
|
||||
// <24> Length of metadata to follow
|
||||
|
||||
char blockType = header[0] & 0x7f;
|
||||
bool isLastBlock = (header[0] & 0x80) != 0;
|
||||
uint length = header.mid(1, 3).toUInt();
|
||||
|
||||
// First block should be the stream_info metadata
|
||||
|
||||
if(blockType != StreamInfo) {
|
||||
debug("FLAC::File::scan() -- invalid FLAC stream");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
|
||||
d->streamInfoData = readBlock(length);
|
||||
nextBlockOffset += length + 4;
|
||||
|
||||
// Search through the remaining metadata
|
||||
|
||||
while(!isLastBlock) {
|
||||
|
||||
header = readBlock(4);
|
||||
blockType = header[0] & 0x7f;
|
||||
isLastBlock = (header[0] & 0x80) != 0;
|
||||
length = header.mid(1, 3).toUInt();
|
||||
|
||||
if(blockType == Padding) {
|
||||
// debug("FLAC::File::scan() -- Padding found");
|
||||
}
|
||||
// Found the vorbis-comment
|
||||
else if(blockType == VorbisComment) {
|
||||
d->xiphCommentData = readBlock(length);
|
||||
d->hasXiphComment = true;
|
||||
}
|
||||
|
||||
nextBlockOffset += length + 4;
|
||||
|
||||
if(nextBlockOffset >= File::length()) {
|
||||
debug("FLAC::File::scan() -- FLAC stream corrupted");
|
||||
setValid(false);
|
||||
return;
|
||||
}
|
||||
seek(nextBlockOffset);
|
||||
}
|
||||
|
||||
// End of metadata, now comes the datastream
|
||||
|
||||
d->streamStart = nextBlockOffset;
|
||||
d->streamLength = File::length() - d->streamStart;
|
||||
|
||||
if(d->hasID3v1)
|
||||
d->streamLength -= 128;
|
||||
|
||||
d->scanned = true;
|
||||
}
|
||||
|
||||
long FLAC::File::findID3v1()
|
||||
{
|
||||
if(!isValid())
|
||||
return -1;
|
||||
|
||||
seek(-128, End);
|
||||
long p = tell();
|
||||
|
||||
if(readBlock(3) == ID3v1::Tag::fileIdentifier())
|
||||
return p;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
long FLAC::File::findID3v2()
|
||||
{
|
||||
if(!isValid())
|
||||
return -1;
|
||||
|
||||
seek(0);
|
||||
|
||||
if(readBlock(3) == ID3v2::Header::fileIdentifier())
|
||||
return 0;
|
||||
|
||||
return -1;
|
||||
}
|
|
@ -1,201 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2003 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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_FLACFILE_H
|
||||
#define TAGLIB_FLACFILE_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "tfile.h"
|
||||
|
||||
#include "flacproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class Tag;
|
||||
|
||||
namespace ID3v2 { class FrameFactory; class Tag; }
|
||||
namespace ID3v1 { class Tag; }
|
||||
namespace Ogg { class XiphComment; }
|
||||
|
||||
//! An implementation of FLAC metadata
|
||||
|
||||
/*!
|
||||
* This is implementation of FLAC metadata for non-Ogg FLAC files. At some
|
||||
* point when Ogg / FLAC is more common there will be a similar implementation
|
||||
* under the Ogg hiearchy.
|
||||
*
|
||||
* This supports ID3v1, ID3v2 and Xiph style comments as well as reading stream
|
||||
* properties from the file.
|
||||
*/
|
||||
|
||||
namespace FLAC {
|
||||
|
||||
//! An implementation of TagLib::File with FLAC specific methods
|
||||
|
||||
/*!
|
||||
* This implements and provides an interface for FLAC 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 FLAC files.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT File : public TagLib::File
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* 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.
|
||||
*
|
||||
* \deprecated This constructor will be dropped in favor of the one below
|
||||
* in a future version.
|
||||
*/
|
||||
File(FileName file, 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.
|
||||
*/
|
||||
// BIC: merge with the above constructor
|
||||
File(FileName file, ID3v2::FrameFactory *frameFactory,
|
||||
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 a union of XiphComment,
|
||||
* ID3v1 and ID3v2 tags.
|
||||
*
|
||||
* \see ID3v2Tag()
|
||||
* \see ID3v1Tag()
|
||||
* \see XiphComment()
|
||||
*/
|
||||
virtual TagLib::Tag *tag() const;
|
||||
|
||||
/*!
|
||||
* Returns the FLAC::Properties for this file. If no audio properties
|
||||
* were read then this will return a null pointer.
|
||||
*/
|
||||
virtual Properties *audioProperties() const;
|
||||
|
||||
/*!
|
||||
* Save the file. This will primarily save the XiphComment, but
|
||||
* will also keep any old ID3-tags up to date. If the file
|
||||
* has no XiphComment, one will be constructed from the ID3-tags.
|
||||
*
|
||||
* This returns true if the save was successful.
|
||||
*/
|
||||
virtual bool save();
|
||||
|
||||
/*!
|
||||
* Returns a pointer to the ID3v2 tag of the file.
|
||||
*
|
||||
* If \a create is false (the default) this will return a null pointer
|
||||
* if there is no valid ID3v2 tag. If \a create is true it will create
|
||||
* an ID3v2 tag if one does not exist.
|
||||
*
|
||||
* \note The Tag <b>is still</b> owned by the FLAC::File and should not be
|
||||
* deleted by the user. It will be deleted when the file (object) is
|
||||
* destroyed.
|
||||
*/
|
||||
ID3v2::Tag *ID3v2Tag(bool create = false);
|
||||
|
||||
/*!
|
||||
* 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.
|
||||
*
|
||||
* \note The Tag <b>is still</b> owned by the FLAC::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 XiphComment for the file.
|
||||
*
|
||||
* If \a create is false (the default) this will return a null pointer
|
||||
* if there is no valid XiphComment. If \a create is true it will create
|
||||
* a XiphComment if one does not exist.
|
||||
*
|
||||
* \note The Tag <b>is still</b> owned by the FLAC::File and should not be
|
||||
* deleted by the user. It will be deleted when the file (object) is
|
||||
* destroyed.
|
||||
*/
|
||||
Ogg::XiphComment *xiphComment(bool create = false);
|
||||
|
||||
/*!
|
||||
* Set the ID3v2::FrameFactory to something other than the default. This
|
||||
* can be used to specify the way that ID3v2 frames will be interpreted
|
||||
* when
|
||||
*
|
||||
* \see ID3v2FrameFactory
|
||||
*/
|
||||
void setID3v2FrameFactory(const ID3v2::FrameFactory *factory);
|
||||
|
||||
/*!
|
||||
* Returns the block of data used by FLAC::Properties for parsing the
|
||||
* stream properties.
|
||||
*
|
||||
* \deprecated This method will not be public in a future release.
|
||||
*/
|
||||
ByteVector streamInfoData(); // BIC: remove
|
||||
|
||||
/*!
|
||||
* Returns the length of the audio-stream, used by FLAC::Properties for
|
||||
* calculating the bitrate.
|
||||
*
|
||||
* \deprecated This method will not be public in a future release.
|
||||
*/
|
||||
long streamLength(); // BIC: remove
|
||||
|
||||
private:
|
||||
File(const File &);
|
||||
File &operator=(const File &);
|
||||
|
||||
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
|
||||
void scan();
|
||||
long findID3v2();
|
||||
long findID3v1();
|
||||
ByteVector xiphCommentData() const;
|
||||
|
||||
class FilePrivate;
|
||||
FilePrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
***************************************************************************/
|
||||
/**************************************************************************
|
||||
copyright : (C) 2010 by Lukáš Lalinský
|
||||
email : lalinsky@gmail.com
|
||||
**************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
|
@ -15,25 +15,37 @@
|
|||
* *
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_EXPORT_H
|
||||
#define TAGLIB_EXPORT_H
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#ifdef MAKE_TAGLIB_LIB
|
||||
#define TAGLIB_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#define TAGLIB_EXPORT __declspec(dllimport)
|
||||
#endif
|
||||
#else
|
||||
#define TAGLIB_EXPORT
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#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()
|
||||
{
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
***************************************************************************/
|
||||
/**************************************************************************
|
||||
copyright : (C) 2010 by Lukáš Lalinský
|
||||
email : lalinsky@gmail.com
|
||||
**************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
|
@ -15,57 +15,61 @@
|
|||
* *
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_DEBUG_H
|
||||
#define TAGLIB_DEBUG_H
|
||||
#ifndef TAGLIB_FLACMETADATABLOCK_H
|
||||
#define TAGLIB_FLACMETADATABLOCK_H
|
||||
|
||||
#include "tlist.h"
|
||||
#include "tbytevector.h"
|
||||
#include "taglib_export.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
class String;
|
||||
class ByteVector;
|
||||
namespace FLAC {
|
||||
|
||||
#ifndef DO_NOT_DOCUMENT
|
||||
#ifndef NDEBUG
|
||||
class TAGLIB_EXPORT MetadataBlock
|
||||
{
|
||||
public:
|
||||
MetadataBlock();
|
||||
virtual ~MetadataBlock();
|
||||
|
||||
/*!
|
||||
* A simple function that prints debugging output to cerr if debugging is
|
||||
* not disabled.
|
||||
*
|
||||
* \warning Do not use this outside of TagLib, it could lead to undefined
|
||||
* symbols in your build if TagLib is built with NDEBUG defined and your
|
||||
* application is not.
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
void debug(const String &s);
|
||||
enum BlockType {
|
||||
StreamInfo = 0,
|
||||
Padding,
|
||||
Application,
|
||||
SeekTable,
|
||||
VorbisComment,
|
||||
CueSheet,
|
||||
Picture
|
||||
};
|
||||
|
||||
/*!
|
||||
* For debugging binary data.
|
||||
*
|
||||
* \warning Do not use this outside of TagLib, it could lead to undefined
|
||||
* symbols in your build if TagLib is built with NDEBUG defined and your
|
||||
* application is not.
|
||||
*
|
||||
* \internal
|
||||
*/
|
||||
void debugData(const ByteVector &v);
|
||||
/*!
|
||||
* Returns the FLAC metadata block type.
|
||||
*/
|
||||
virtual int code() const = 0;
|
||||
|
||||
#else
|
||||
/*!
|
||||
* Render the content of the block.
|
||||
*/
|
||||
virtual ByteVector render() const = 0;
|
||||
|
||||
// Define these to an empty statement if debugging is disabled.
|
||||
private:
|
||||
MetadataBlock(const MetadataBlock &item);
|
||||
MetadataBlock &operator=(const MetadataBlock &item);
|
||||
|
||||
#define debug(x)
|
||||
#define debugData(x)
|
||||
class MetadataBlockPrivate;
|
||||
MetadataBlockPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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
|
|
@ -1,150 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2003 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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 "flacproperties.h"
|
||||
#include "flacfile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class FLAC::Properties::PropertiesPrivate
|
||||
{
|
||||
public:
|
||||
PropertiesPrivate(ByteVector d, long st, ReadStyle s) :
|
||||
data(d),
|
||||
streamLength(st),
|
||||
style(s),
|
||||
length(0),
|
||||
bitrate(0),
|
||||
sampleRate(0),
|
||||
sampleWidth(0),
|
||||
channels(0) {}
|
||||
|
||||
ByteVector data;
|
||||
long streamLength;
|
||||
ReadStyle style;
|
||||
int length;
|
||||
int bitrate;
|
||||
int sampleRate;
|
||||
int sampleWidth;
|
||||
int channels;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FLAC::Properties::Properties(ByteVector data, long streamLength, ReadStyle style) : AudioProperties(style)
|
||||
{
|
||||
d = new PropertiesPrivate(data, streamLength, style);
|
||||
read();
|
||||
}
|
||||
|
||||
FLAC::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
|
||||
{
|
||||
d = new PropertiesPrivate(file->streamInfoData(), file->streamLength(), style);
|
||||
read();
|
||||
}
|
||||
|
||||
FLAC::Properties::~Properties()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
int FLAC::Properties::length() const
|
||||
{
|
||||
return d->length;
|
||||
}
|
||||
|
||||
int FLAC::Properties::bitrate() const
|
||||
{
|
||||
return d->bitrate;
|
||||
}
|
||||
|
||||
int FLAC::Properties::sampleRate() const
|
||||
{
|
||||
return d->sampleRate;
|
||||
}
|
||||
|
||||
int FLAC::Properties::sampleWidth() const
|
||||
{
|
||||
return d->sampleWidth;
|
||||
}
|
||||
|
||||
int FLAC::Properties::channels() const
|
||||
{
|
||||
return d->channels;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// private members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void FLAC::Properties::read()
|
||||
{
|
||||
if(d->data.size() < 18) {
|
||||
debug("FLAC::Properties::read() - FLAC properties must contain at least 18 bytes.");
|
||||
return;
|
||||
}
|
||||
|
||||
int pos = 0;
|
||||
|
||||
// Minimum block size (in samples)
|
||||
pos += 2;
|
||||
|
||||
// Maximum block size (in samples)
|
||||
pos += 2;
|
||||
|
||||
// Minimum frame size (in bytes)
|
||||
pos += 3;
|
||||
|
||||
// Maximum frame size (in bytes)
|
||||
pos += 3;
|
||||
|
||||
uint flags = d->data.mid(pos, 4).toUInt(true);
|
||||
d->sampleRate = flags >> 12;
|
||||
d->channels = ((flags >> 9) & 7) + 1;
|
||||
d->sampleWidth = ((flags >> 4) & 31) + 1;
|
||||
|
||||
// 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;
|
||||
pos += 4;
|
||||
|
||||
d->length = d->sampleRate > 0 ?
|
||||
(d->data.mid(pos, 4).toUInt(true)) / d->sampleRate + highLength : 0;
|
||||
pos += 4;
|
||||
|
||||
// Uncompressed bitrate:
|
||||
|
||||
//d->bitrate = ((d->sampleRate * d->channels) / 1000) * d->sampleWidth;
|
||||
|
||||
// Real bitrate:
|
||||
|
||||
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2003 by Allan Sandfeld Jensen
|
||||
email : kde@carewolf.org
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
* 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_FLACPROPERTIES_H
|
||||
#define TAGLIB_FLACPROPERTIES_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace FLAC {
|
||||
|
||||
class File;
|
||||
|
||||
//! An implementation of audio property reading for FLAC
|
||||
|
||||
/*!
|
||||
* This reads the data from an FLAC stream found in the AudioProperties
|
||||
* API.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT Properties : public AudioProperties
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Create an instance of FLAC::Properties with the data read from the
|
||||
* ByteVector \a data.
|
||||
*/
|
||||
// BIC: switch to const reference
|
||||
Properties(ByteVector data, long streamLength, ReadStyle style = Average);
|
||||
|
||||
/*!
|
||||
* Create an instance of FLAC::Properties with the data read from the
|
||||
* FLAC::File \a file.
|
||||
*/
|
||||
// BIC: remove
|
||||
Properties(File *file, ReadStyle style = Average);
|
||||
|
||||
/*!
|
||||
* Destroys this FLAC::Properties instance.
|
||||
*/
|
||||
virtual ~Properties();
|
||||
|
||||
// Reimplementations.
|
||||
|
||||
virtual int length() const;
|
||||
virtual int bitrate() const;
|
||||
virtual int sampleRate() const;
|
||||
virtual int channels() const;
|
||||
|
||||
/*!
|
||||
* Returns the sample width as read from the FLAC identification
|
||||
* header.
|
||||
*/
|
||||
int sampleWidth() const;
|
||||
|
||||
private:
|
||||
Properties(const Properties &);
|
||||
Properties &operator=(const Properties &);
|
||||
|
||||
void read();
|
||||
|
||||
class PropertiesPrivate;
|
||||
PropertiesPrivate *d;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
***************************************************************************/
|
||||
/**************************************************************************
|
||||
copyright : (C) 2010 by Lukáš Lalinský
|
||||
email : lalinsky@gmail.com
|
||||
**************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
|
@ -15,57 +15,69 @@
|
|||
* *
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#include "id3v2extendedheader.h"
|
||||
#include "id3v2synchdata.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <taglib.h>
|
||||
#include <tdebug.h>
|
||||
#include <tstring.h>
|
||||
#include "flacunknownmetadatablock.h"
|
||||
|
||||
using namespace TagLib;
|
||||
using namespace ID3v2;
|
||||
|
||||
class ExtendedHeader::ExtendedHeaderPrivate
|
||||
class FLAC::UnknownMetadataBlock::UnknownMetadataBlockPrivate
|
||||
{
|
||||
public:
|
||||
ExtendedHeaderPrivate() : size(0) {}
|
||||
UnknownMetadataBlockPrivate() : code(0) {}
|
||||
|
||||
uint size;
|
||||
int code;
|
||||
ByteVector data;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// public methods
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ExtendedHeader::ExtendedHeader()
|
||||
FLAC::UnknownMetadataBlock::UnknownMetadataBlock(int code, const ByteVector &data)
|
||||
{
|
||||
d = new ExtendedHeaderPrivate();
|
||||
d = new UnknownMetadataBlockPrivate;
|
||||
d->code = code;
|
||||
//debug(String(data.toHex()));
|
||||
d->data = data;
|
||||
}
|
||||
|
||||
ExtendedHeader::~ExtendedHeader()
|
||||
FLAC::UnknownMetadataBlock::~UnknownMetadataBlock()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::uint ExtendedHeader::size() const
|
||||
int FLAC::UnknownMetadataBlock::code() const
|
||||
{
|
||||
return d->size;
|
||||
return d->code;
|
||||
}
|
||||
|
||||
void ExtendedHeader::setData(const ByteVector &data)
|
||||
void FLAC::UnknownMetadataBlock::setCode(int code)
|
||||
{
|
||||
parse(data);
|
||||
d->code = code;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// protected members
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ExtendedHeader::parse(const ByteVector &data)
|
||||
ByteVector FLAC::UnknownMetadataBlock::data() const
|
||||
{
|
||||
d->size = SynchData::toUInt(data.mid(0, 4)); // (structure 3.2 "Extended header size")
|
||||
return d->data;
|
||||
}
|
||||
|
||||
void FLAC::UnknownMetadataBlock::setData(const ByteVector &data)
|
||||
{
|
||||
d->data = data;
|
||||
}
|
||||
|
||||
ByteVector FLAC::UnknownMetadataBlock::render() const
|
||||
{
|
||||
return d->data;
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/***************************************************************************
|
||||
copyright : (C) 2002 - 2008 by Scott Wheeler
|
||||
email : wheeler@kde.org
|
||||
***************************************************************************/
|
||||
/**************************************************************************
|
||||
copyright : (C) 2010 by Lukáš Lalinský
|
||||
email : lalinsky@gmail.com
|
||||
**************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* This library is free software; you can redistribute it and/or modify *
|
||||
|
@ -15,68 +15,67 @@
|
|||
* *
|
||||
* 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/ *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef TAGLIB_ID3V2FOOTER_H
|
||||
#define TAGLIB_ID3V2FOOTER_H
|
||||
#ifndef TAGLIB_FLACUNKNOWNMETADATABLOCK_H
|
||||
#define TAGLIB_FLACUNKNOWNMETADATABLOCK_H
|
||||
|
||||
#include "taglib_export.h"
|
||||
#include "tlist.h"
|
||||
#include "tbytevector.h"
|
||||
#include "taglib_export.h"
|
||||
#include "flacmetadatablock.h"
|
||||
|
||||
namespace TagLib {
|
||||
|
||||
namespace ID3v2 {
|
||||
namespace FLAC {
|
||||
|
||||
class Header;
|
||||
|
||||
//! ID3v2 footer implementation
|
||||
|
||||
/*!
|
||||
* Per the ID3v2 specification, the tag's footer is just a copy of the
|
||||
* information in the header. As such there is no API for reading the
|
||||
* data from the header, it can just as easily be done from the header.
|
||||
*
|
||||
* In fact, at this point, TagLib does not even parse the footer since
|
||||
* it is not useful internally. However, if the flag to include a footer
|
||||
* has been set in the ID3v2::Tag, TagLib will render a footer.
|
||||
*/
|
||||
|
||||
class TAGLIB_EXPORT Footer
|
||||
class TAGLIB_EXPORT UnknownMetadataBlock : public MetadataBlock
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Constructs an empty ID3v2 footer.
|
||||
*/
|
||||
Footer();
|
||||
/*!
|
||||
* Destroys the footer.
|
||||
*/
|
||||
virtual ~Footer();
|
||||
UnknownMetadataBlock(int blockType, const ByteVector &data);
|
||||
~UnknownMetadataBlock();
|
||||
|
||||
/*!
|
||||
* Returns the size of the footer. Presently this is always 10 bytes.
|
||||
* Returns the FLAC metadata block type.
|
||||
*/
|
||||
static const unsigned int size();
|
||||
int code() const;
|
||||
|
||||
/*!
|
||||
* Renders the footer based on the data in \a header.
|
||||
* Sets the FLAC metadata block type.
|
||||
*/
|
||||
ByteVector render(const Header *header) const;
|
||||
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:
|
||||
Footer(const Footer &);
|
||||
Footer &operator=(const Footer &);
|
||||
UnknownMetadataBlock(const MetadataBlock &item);
|
||||
UnknownMetadataBlock &operator=(const MetadataBlock &item);
|
||||
|
||||
class FooterPrivate;
|
||||
FooterPrivate *d;
|
||||
class UnknownMetadataBlockPrivate;
|
||||
UnknownMetadataBlockPrivate *d;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,129 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "tstring.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4skipbox.h"
|
||||
#include "mp4moovbox.h"
|
||||
#include "mp4mvhdbox.h"
|
||||
#include "mp4trakbox.h"
|
||||
#include "mp4mdiabox.h"
|
||||
#include "mp4minfbox.h"
|
||||
#include "mp4stblbox.h"
|
||||
#include "mp4stsdbox.h"
|
||||
#include "mp4hdlrbox.h"
|
||||
#include "mp4udtabox.h"
|
||||
#include "mp4metabox.h"
|
||||
#include "mp4ilstbox.h"
|
||||
#include "itunesnambox.h"
|
||||
#include "itunesartbox.h"
|
||||
#include "itunesalbbox.h"
|
||||
#include "itunesgenbox.h"
|
||||
#include "itunesdaybox.h"
|
||||
#include "itunestrknbox.h"
|
||||
#include "itunescmtbox.h"
|
||||
#include "itunesgrpbox.h"
|
||||
#include "ituneswrtbox.h"
|
||||
#include "itunesdiskbox.h"
|
||||
#include "itunestmpobox.h"
|
||||
#include "itunescvrbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
MP4::BoxFactory::BoxFactory()
|
||||
{
|
||||
}
|
||||
|
||||
MP4::BoxFactory::~BoxFactory()
|
||||
{
|
||||
}
|
||||
|
||||
//! factory function
|
||||
MP4::Mp4IsoBox* MP4::BoxFactory::createInstance( TagLib::File* anyfile, MP4::Fourcc fourcc, uint size, long offset ) const
|
||||
{
|
||||
MP4::File * file = static_cast<MP4::File *>(anyfile);
|
||||
if(!file)
|
||||
return 0;
|
||||
|
||||
//std::cout << "creating box for: " << fourcc.toString() << std::endl;
|
||||
|
||||
switch( fourcc )
|
||||
{
|
||||
case 0x6d6f6f76: // 'moov'
|
||||
return new MP4::Mp4MoovBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x6d766864: // 'mvhd'
|
||||
return new MP4::Mp4MvhdBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x7472616b: // 'trak'
|
||||
return new MP4::Mp4TrakBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x6d646961: // 'mdia'
|
||||
return new MP4::Mp4MdiaBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x6d696e66: // 'minf'
|
||||
return new MP4::Mp4MinfBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x7374626c: // 'stbl'
|
||||
return new MP4::Mp4StblBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x73747364: // 'stsd'
|
||||
return new MP4::Mp4StsdBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x68646c72: // 'hdlr'
|
||||
return new MP4::Mp4HdlrBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x75647461: // 'udta'
|
||||
return new MP4::Mp4UdtaBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x6d657461: // 'meta'
|
||||
return new MP4::Mp4MetaBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x696c7374: // 'ilst'
|
||||
return new MP4::Mp4IlstBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa96e616d: // '_nam'
|
||||
return new MP4::ITunesNamBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa9415254: // '_ART'
|
||||
return new MP4::ITunesArtBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa9616c62: // '_alb'
|
||||
return new MP4::ITunesAlbBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa967656e: // '_gen'
|
||||
return new MP4::ITunesGenBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x676e7265: // 'gnre'
|
||||
return new MP4::ITunesGenBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa9646179: // '_day'
|
||||
return new MP4::ITunesDayBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x74726b6e: // 'trkn'
|
||||
return new MP4::ITunesTrknBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa9636d74: // '_cmt'
|
||||
return new MP4::ITunesCmtBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa9677270: // '_grp'
|
||||
return new MP4::ITunesGrpBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0xa9777274: // '_wrt'
|
||||
return new MP4::ITunesWrtBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x6469736b: // 'disk'
|
||||
return new MP4::ITunesDiskBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x746d706f: // 'tmpo'
|
||||
return new MP4::ITunesTmpoBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x636f7672: // 'covr'
|
||||
return new MP4::ITunesCvrBox( file, fourcc, size, offset );
|
||||
break;
|
||||
case 0x64616461: // 'data'
|
||||
return new MP4::ITunesDataBox( file, fourcc, size, offset );
|
||||
break;
|
||||
default:
|
||||
return new MP4::Mp4SkipBox( file, fourcc, size, offset );
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#ifndef BOXFACTORY_H
|
||||
#define BOXFACTORY_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "mp4isobox.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class BoxFactory
|
||||
{
|
||||
public:
|
||||
BoxFactory();
|
||||
~BoxFactory();
|
||||
|
||||
//! factory function
|
||||
Mp4IsoBox* createInstance( TagLib::File* anyfile, MP4::Fourcc fourcc, uint size, long offset ) const;
|
||||
}; // class BoxFactory
|
||||
|
||||
} // namepace MP4
|
||||
} // namepace TagLib
|
||||
|
||||
#endif // BOXFACTORY_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesalbbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesAlbBox::ITunesAlbBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesAlbBox::ITunesAlbBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesAlbBox::ITunesAlbBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesAlbBox::~ITunesAlbBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesAlbBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesAlbBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::album, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of album box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESALBBOX_H
|
||||
#define ITUNESALBBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesAlbBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesAlbBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesAlbBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesAlbBoxPrivate;
|
||||
ITunesAlbBoxPrivate* d;
|
||||
}; // class ITunesAlbBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESALBBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesartbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesArtBox::ITunesArtBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesArtBox::ITunesArtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesArtBox::ITunesArtBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesArtBox::~ITunesArtBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesArtBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesArtBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::artist, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of artist box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESARTBOX_H
|
||||
#define ITUNESARTBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesArtBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesArtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesArtBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesArtBoxPrivate;
|
||||
ITunesArtBoxPrivate* d;
|
||||
}; // class ITunesArtBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESARTBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunescmtbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesCmtBox::ITunesCmtBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesCmtBox::ITunesCmtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesCmtBox::ITunesCmtBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesCmtBox::~ITunesCmtBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesCmtBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesCmtBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::comment, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of title box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESCMTBOX_H
|
||||
#define ITUNESCMTBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesCmtBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesCmtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesCmtBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesCmtBoxPrivate;
|
||||
ITunesCmtBoxPrivate* d;
|
||||
}; // class ITunesCmtBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESCMTBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunescvrbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesCvrBox::ITunesCvrBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesCvrBox::ITunesCvrBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesCvrBox::ITunesCvrBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesCvrBox::~ITunesCvrBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesCvrBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesCvrBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::cover, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of album box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESCVRBOX_H
|
||||
#define ITUNESCVRBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesCvrBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesCvrBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesCvrBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesCvrBoxPrivate;
|
||||
ITunesCvrBoxPrivate* d;
|
||||
}; // class ITunesCvrBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESCVRBOX_H
|
|
@ -1,42 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesdatabox.h"
|
||||
#include "tbytevector.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "tfile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesDataBox::ITunesDataBoxPrivate
|
||||
{
|
||||
public:
|
||||
ByteVector data;
|
||||
};
|
||||
|
||||
MP4::ITunesDataBox::ITunesDataBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoFullBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesDataBox::ITunesDataBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::ITunesDataBox::~ITunesDataBox()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
ByteVector MP4::ITunesDataBox::data() const
|
||||
{
|
||||
return d->data;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesDataBox::parse()
|
||||
{
|
||||
// skip first 4 byte - don't know what they are supposed to be for - simply 4 zeros
|
||||
file()->seek( 4, TagLib::File::Current );
|
||||
// read contents - remaining size is box_size-12-4 (12:fullbox header, 4:starting zeros of data box)
|
||||
#if 0
|
||||
std::cout << " reading data box with data length: " << size()-16 << std::endl;
|
||||
#endif
|
||||
d->data = file()->readBlock( size()-12-4 );
|
||||
}
|
||||
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef ITUNESDATABOX_H
|
||||
#define ITUNESDATABOX_H
|
||||
|
||||
#include "mp4isofullbox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesDataBox: public Mp4IsoFullBox
|
||||
{
|
||||
public:
|
||||
ITunesDataBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesDataBox();
|
||||
|
||||
//! get the internal data, which can be txt or binary data as well
|
||||
ByteVector data() const;
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesDataBoxPrivate;
|
||||
ITunesDataBoxPrivate* d;
|
||||
}; // class ITunesDataBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESDATABOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesdaybox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesDayBox::ITunesDayBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesDayBox::ITunesDayBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesDayBox::ITunesDayBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesDayBox::~ITunesDayBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesDayBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesDayBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::year, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of day box: " << dataString.substr(0,4) << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESDAYBOX_H
|
||||
#define ITUNESDAYBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesDayBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesDayBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesDayBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesDayBoxPrivate;
|
||||
ITunesDayBoxPrivate* d;
|
||||
}; // class ITunesDayBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESDAYBOX_H
|
|
@ -1,72 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesdiskbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesDiskBox::ITunesDiskBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesDiskBox::ITunesDiskBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesDiskBox::ITunesDiskBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesDiskBox::~ITunesDiskBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesDiskBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesDiskBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::disk, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::ByteVector trknData = d->dataBox->data();
|
||||
TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
|
||||
static_cast<unsigned char>(trknData[1]) << 16 |
|
||||
static_cast<unsigned char>(trknData[2]) << 8 |
|
||||
static_cast<unsigned char>(trknData[3]) ) );
|
||||
std::cout << "Content of tracknumber box: " << trknumber << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESDISKBOX_H
|
||||
#define ITUNESDISKBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesDiskBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesDiskBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesDiskBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesDiskBoxPrivate;
|
||||
ITunesDiskBoxPrivate* d;
|
||||
}; // class ITunesDiskBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESDISKBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesgenbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesGenBox::ITunesGenBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesGenBox::ITunesGenBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesGenBox::ITunesGenBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesGenBox::~ITunesGenBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesGenBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesGenBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::genre, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of genre box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESGENBOX_H
|
||||
#define ITUNESGENBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesGenBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesGenBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesGenBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesGenBoxPrivate;
|
||||
ITunesGenBoxPrivate* d;
|
||||
}; // class ITunesGenBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESGENBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesgrpbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesGrpBox::ITunesGrpBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesGrpBox::ITunesGrpBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesGrpBox::ITunesGrpBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesGrpBox::~ITunesGrpBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesGrpBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesGrpBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::grouping, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of title box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESGRPBOX_H
|
||||
#define ITUNESGRPBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesGrpBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesGrpBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesGrpBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesGrpBoxPrivate;
|
||||
ITunesGrpBoxPrivate* d;
|
||||
}; // class ITunesGrpBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESGRPBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunesnambox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesNamBox::ITunesNamBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesNamBox::ITunesNamBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesNamBox::ITunesNamBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesNamBox::~ITunesNamBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesNamBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesNamBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::title, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of title box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESNAMBOX_H
|
||||
#define ITUNESNAMBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesNamBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesNamBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesNamBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesNamBoxPrivate;
|
||||
ITunesNamBoxPrivate* d;
|
||||
}; // class ITunesNamBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESNAMBOX_H
|
|
@ -1,72 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunestmpobox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesTmpoBox::ITunesTmpoBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesTmpoBox::ITunesTmpoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesTmpoBox::ITunesTmpoBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesTmpoBox::~ITunesTmpoBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesTmpoBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesTmpoBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::bpm, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::ByteVector trknData = d->dataBox->data();
|
||||
TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
|
||||
static_cast<unsigned char>(trknData[1]) << 16 |
|
||||
static_cast<unsigned char>(trknData[2]) << 8 |
|
||||
static_cast<unsigned char>(trknData[3]) ) );
|
||||
std::cout << "Content of tracknumber box: " << trknumber << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESTMPOBOX_H
|
||||
#define ITUNESTMPOBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesTmpoBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesTmpoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesTmpoBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesTmpoBoxPrivate;
|
||||
ITunesTmpoBoxPrivate* d;
|
||||
}; // class ITunesTmpoBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESTMPOBOX_H
|
|
@ -1,72 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "itunestrknbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesTrknBox::ITunesTrknBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesTrknBox::ITunesTrknBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesTrknBox::ITunesTrknBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesTrknBox::~ITunesTrknBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesTrknBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesTrknBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::trackno, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::ByteVector trknData = d->dataBox->data();
|
||||
TagLib::String trknumber = TagLib::String::number( static_cast<int>( static_cast<unsigned char>(trknData[0]) << 24 |
|
||||
static_cast<unsigned char>(trknData[1]) << 16 |
|
||||
static_cast<unsigned char>(trknData[2]) << 8 |
|
||||
static_cast<unsigned char>(trknData[3]) ) );
|
||||
std::cout << "Content of tracknumber box: " << trknumber << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESTRKNBOX_H
|
||||
#define ITUNESTRKNBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesTrknBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesTrknBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesTrknBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesTrknBoxPrivate;
|
||||
ITunesTrknBoxPrivate* d;
|
||||
}; // class ITunesTrknBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESTRKNBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "ituneswrtbox.h"
|
||||
#include "itunesdatabox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "tfile.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::ITunesWrtBox::ITunesWrtBoxPrivate
|
||||
{
|
||||
public:
|
||||
ITunesDataBox* dataBox;
|
||||
};
|
||||
|
||||
MP4::ITunesWrtBox::ITunesWrtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::ITunesWrtBox::ITunesWrtBoxPrivate();
|
||||
d->dataBox = 0;
|
||||
}
|
||||
|
||||
MP4::ITunesWrtBox::~ITunesWrtBox()
|
||||
{
|
||||
if( d->dataBox != 0 )
|
||||
delete d->dataBox;
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::ITunesWrtBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
// parse data box
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
if(mp4file->readSizeAndType( size, fourcc ) == true)
|
||||
{
|
||||
// check for type - must be 'data'
|
||||
if( fourcc != MP4::Fourcc("data") )
|
||||
{
|
||||
std::cerr << "bad atom in itunes tag - skipping it." << std::endl;
|
||||
// jump over data tag
|
||||
mp4file->seek( size-8, TagLib::File::Current );
|
||||
return;
|
||||
}
|
||||
d->dataBox = new ITunesDataBox( mp4file, fourcc, size, mp4file->tell() );
|
||||
d->dataBox->parsebox();
|
||||
}
|
||||
else
|
||||
{
|
||||
// reading unsuccessful - serious error!
|
||||
std::cerr << "Error in parsing ITunesWrtBox - serious Error in taglib!" << std::endl;
|
||||
return;
|
||||
}
|
||||
// register data box
|
||||
mp4file->tagProxy()->registerBox( Mp4TagsProxy::composer, d->dataBox );
|
||||
|
||||
#if 0
|
||||
// get data pointer - just for debuging...
|
||||
TagLib::String dataString( d->dataBox->data() );
|
||||
std::cout << "Content of title box: " << dataString << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#ifndef ITUNESWRTBOX_H
|
||||
#define ITUNESWRTBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class ITunesWrtBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
ITunesWrtBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~ITunesWrtBox();
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
protected:
|
||||
class ITunesWrtBoxPrivate;
|
||||
ITunesWrtBoxPrivate* d;
|
||||
}; // class ITunesWrtBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // ITUNESWRTBOX_H
|
|
@ -1,54 +0,0 @@
|
|||
#include "mp4audioproperties.h"
|
||||
#include "mp4propsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::AudioProperties::AudioPropertiesPrivate
|
||||
{
|
||||
public:
|
||||
MP4::Mp4PropsProxy* propsproxy;
|
||||
}; // AudioPropertiesPrivate
|
||||
|
||||
MP4::AudioProperties::AudioProperties():TagLib::AudioProperties(TagLib::AudioProperties::Average)
|
||||
{
|
||||
d = new MP4::AudioProperties::AudioPropertiesPrivate();
|
||||
}
|
||||
|
||||
MP4::AudioProperties::~AudioProperties()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::AudioProperties::setProxy( Mp4PropsProxy* proxy )
|
||||
{
|
||||
d->propsproxy = proxy;
|
||||
}
|
||||
|
||||
int MP4::AudioProperties::length() const
|
||||
{
|
||||
if( d->propsproxy == 0 )
|
||||
return 0;
|
||||
return d->propsproxy->seconds();
|
||||
}
|
||||
|
||||
int MP4::AudioProperties::bitrate() const
|
||||
{
|
||||
if( d->propsproxy == 0 )
|
||||
return 0;
|
||||
return d->propsproxy->bitRate()/1000;
|
||||
}
|
||||
|
||||
int MP4::AudioProperties::sampleRate() const
|
||||
{
|
||||
if( d->propsproxy == 0 )
|
||||
return 0;
|
||||
return d->propsproxy->sampleRate();
|
||||
}
|
||||
|
||||
int MP4::AudioProperties::channels() const
|
||||
{
|
||||
if( d->propsproxy == 0 )
|
||||
return 0;
|
||||
return d->propsproxy->channels();
|
||||
}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
#ifndef MP4AUDIOPROPERTIES_H
|
||||
#define MP4AUDIOPROPERTIES_H MP4AUDIOPROPERTIES_H
|
||||
|
||||
#include "audioproperties.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4PropsProxy;
|
||||
|
||||
class AudioProperties : public TagLib::AudioProperties
|
||||
{
|
||||
public:
|
||||
//! constructor
|
||||
AudioProperties();
|
||||
//! destructor
|
||||
~AudioProperties();
|
||||
|
||||
//! function to set the proxy
|
||||
void setProxy( Mp4PropsProxy* proxy );
|
||||
|
||||
/*!
|
||||
* Returns the lenght of the file in seconds.
|
||||
*/
|
||||
int length() const;
|
||||
|
||||
/*!
|
||||
* Returns the most appropriate bit rate for the file in kb/s. For constant
|
||||
* bitrate formats this is simply the bitrate of the file. For variable
|
||||
* bitrate formats this is either the average or nominal bitrate.
|
||||
*/
|
||||
int bitrate() const;
|
||||
|
||||
/*!
|
||||
* Returns the sample rate in Hz.
|
||||
*/
|
||||
int sampleRate() const;
|
||||
|
||||
/*!
|
||||
* Returns the number of audio channels.
|
||||
*/
|
||||
int channels() const;
|
||||
|
||||
private:
|
||||
class AudioPropertiesPrivate;
|
||||
AudioPropertiesPrivate* d;
|
||||
};
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4AUDIOPROPERTIES_H
|
|
@ -1,124 +0,0 @@
|
|||
#include <iostream>
|
||||
#include "mp4audiosampleentry.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
#include "mp4propsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntryPrivate
|
||||
{
|
||||
public:
|
||||
TagLib::uint channelcount;
|
||||
TagLib::uint samplerate;
|
||||
TagLib::uint bitrate;
|
||||
};
|
||||
|
||||
MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4SampleEntry(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::Mp4AudioSampleEntry::Mp4AudioSampleEntryPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4AudioSampleEntry::~Mp4AudioSampleEntry()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4AudioSampleEntry::channels() const
|
||||
{
|
||||
return d->channelcount;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4AudioSampleEntry::samplerate() const
|
||||
{
|
||||
return d->samplerate;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4AudioSampleEntry::bitrate() const
|
||||
{
|
||||
return d->bitrate;
|
||||
}
|
||||
|
||||
void MP4::Mp4AudioSampleEntry::parseEntry()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<TagLib::MP4::File*>(file());
|
||||
if(!mp4file)
|
||||
return;
|
||||
|
||||
// read 8 reserved bytes
|
||||
mp4file->seek( 8, TagLib::File::Current );
|
||||
// read channelcount
|
||||
if(!mp4file->readShort( d->channelcount ))
|
||||
return;
|
||||
// seek over samplesize, pre_defined and reserved
|
||||
mp4file->seek( 6, TagLib::File::Current );
|
||||
// read samplerate
|
||||
if(!mp4file->readInt( d->samplerate ))
|
||||
return;
|
||||
|
||||
// register box at proxy
|
||||
mp4file->propProxy()->registerAudioSampleEntry( this );
|
||||
|
||||
|
||||
//std::cout << "fourcc of audio sample entry: " << fourcc().toString() << std::endl;
|
||||
// check for both mp4a (plain files) and drms (encrypted files)
|
||||
if( (fourcc() == MP4::Fourcc("mp4a")) ||
|
||||
(fourcc() == MP4::Fourcc("drms")) )
|
||||
{
|
||||
TagLib::MP4::Fourcc fourcc;
|
||||
TagLib::uint esds_size;
|
||||
|
||||
mp4file->readSizeAndType( esds_size, fourcc );
|
||||
|
||||
// read esds' main parts
|
||||
if( size()-48 > 0 )
|
||||
ByteVector flags_version = mp4file->readBlock(4);
|
||||
else
|
||||
return;
|
||||
|
||||
ByteVector EsDescrTag = mp4file->readBlock(1);
|
||||
// first 4 bytes contain full box specifics (version & flags)
|
||||
// upcoming byte must be ESDescrTag (0x03)
|
||||
if( EsDescrTag[0] == 0x03 )
|
||||
{
|
||||
TagLib::uint descr_len = mp4file->readSystemsLen();
|
||||
TagLib::uint EsId;
|
||||
if( !mp4file->readShort( EsId ) )
|
||||
return;
|
||||
ByteVector priority = mp4file->readBlock(1);
|
||||
if( descr_len < 20 )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
TagLib::uint EsId;
|
||||
if( !mp4file->readShort( EsId ) )
|
||||
return;
|
||||
}
|
||||
// read decoder configuration tag (0x04)
|
||||
ByteVector DecCfgTag = mp4file->readBlock(1);
|
||||
if( DecCfgTag[0] != 0x04 )
|
||||
return;
|
||||
// read decoder configuration length
|
||||
/*TagLib::uint deccfg_len =*/ mp4file->readSystemsLen();
|
||||
// read object type Id
|
||||
ByteVector objId = mp4file->readBlock(1);
|
||||
// read stream type id
|
||||
ByteVector strId = mp4file->readBlock(1);
|
||||
// read buffer Size DB
|
||||
ByteVector bufferSizeDB = mp4file->readBlock(3);
|
||||
// read max bitrate
|
||||
TagLib::uint max_bitrate;
|
||||
if( !mp4file->readInt( max_bitrate ) )
|
||||
return;
|
||||
// read average bitrate
|
||||
if( !mp4file->readInt( d->bitrate ) )
|
||||
return;
|
||||
// skip the rest
|
||||
mp4file->seek( offset()+size()-8, File::Beginning );
|
||||
}
|
||||
else
|
||||
mp4file->seek( size()-36, File::Current );
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef MP4AUDIOSAMPLEENTRY_H
|
||||
#define MP4AUDIOSAMPLEENTRY_H
|
||||
|
||||
#include "mp4sampleentry.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4AudioSampleEntry: public Mp4SampleEntry
|
||||
{
|
||||
public:
|
||||
Mp4AudioSampleEntry( File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~Mp4AudioSampleEntry();
|
||||
|
||||
//! function to get the number of channels
|
||||
TagLib::uint channels() const;
|
||||
//! function to get the sample rate
|
||||
TagLib::uint samplerate() const;
|
||||
//! function to get the average bitrate of the audio stream
|
||||
TagLib::uint bitrate() const;
|
||||
|
||||
private:
|
||||
//! parse the content of the box
|
||||
void parseEntry();
|
||||
|
||||
protected:
|
||||
class Mp4AudioSampleEntryPrivate;
|
||||
Mp4AudioSampleEntryPrivate* d;
|
||||
}; // class Mp4AudioSampleEntry
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4AUDIOSAMPLEENTRY_H
|
|
@ -1,383 +0,0 @@
|
|||
#include <tbytevector.h>
|
||||
#include <tstring.h>
|
||||
#include <tdebug.h>
|
||||
#include "tlist.h"
|
||||
|
||||
#include "id3v1genres.h"
|
||||
|
||||
#include "mp4itunestag.h"
|
||||
#include "mp4file.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4tagsproxy.h"
|
||||
#include "mp4propsproxy.h"
|
||||
#include "mp4audioproperties.h"
|
||||
#include "itunesdatabox.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::File::FilePrivate
|
||||
{
|
||||
public:
|
||||
//! list for all boxes of the mp4 file
|
||||
TagLib::List<MP4::Mp4IsoBox*> boxes;
|
||||
//! the box factory - will create all boxes by tag and size
|
||||
MP4::BoxFactory boxfactory;
|
||||
//! proxy for the tags is filled after parsing
|
||||
MP4::Mp4TagsProxy tagsProxy;
|
||||
//! proxy for audio properties
|
||||
MP4::Mp4PropsProxy propsProxy;
|
||||
//! the tag returned by tag() function
|
||||
MP4::Tag mp4tag;
|
||||
//! container for the audio properties returned by properties() function
|
||||
MP4::AudioProperties mp4audioproperties;
|
||||
//! is set to valid after successfull parsing
|
||||
bool isValid;
|
||||
};
|
||||
|
||||
//! function to fill the tags with converted proxy data, which has been parsed out of the file previously
|
||||
static void fillTagFromProxy( MP4::Mp4TagsProxy& proxy, MP4::Tag& mp4tag );
|
||||
|
||||
MP4::File::File(FileName file, bool , AudioProperties::ReadStyle )
|
||||
:TagLib::File( file )
|
||||
{
|
||||
// create member container
|
||||
d = new MP4::File::FilePrivate();
|
||||
|
||||
read();
|
||||
}
|
||||
|
||||
MP4::File::~File()
|
||||
{
|
||||
TagLib::List<Mp4IsoBox*>::Iterator delIter;
|
||||
for( delIter = d->boxes.begin();
|
||||
delIter != d->boxes.end();
|
||||
delIter++ )
|
||||
{
|
||||
delete *delIter;
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
Tag *MP4::File::tag() const
|
||||
{
|
||||
return &d->mp4tag;
|
||||
}
|
||||
|
||||
AudioProperties * MP4::File::audioProperties() const
|
||||
{
|
||||
d->mp4audioproperties.setProxy( &d->propsProxy );
|
||||
return &d->mp4audioproperties;
|
||||
}
|
||||
|
||||
void MP4::File::read( bool, TagLib::AudioProperties::ReadStyle )
|
||||
{
|
||||
d->isValid = false;
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
while( readSizeAndType( size, fourcc ) == true )
|
||||
{
|
||||
// create the appropriate subclass and parse it
|
||||
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( this, fourcc, size, tell() );
|
||||
curbox->parsebox();
|
||||
d->boxes.append( curbox );
|
||||
}
|
||||
|
||||
for( TagLib::List<MP4::Mp4IsoBox*>::Iterator iter = d->boxes.begin();
|
||||
iter != d->boxes.end();
|
||||
iter++ )
|
||||
{
|
||||
if( (*iter)->fourcc() == MP4::Fourcc("moov") )
|
||||
{
|
||||
d->isValid = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( d->isValid )
|
||||
debug( "file is valid" );
|
||||
else
|
||||
debug( "file is NOT valid" );
|
||||
|
||||
// fill tags from proxy data
|
||||
fillTagFromProxy( d->tagsProxy, d->mp4tag );
|
||||
}
|
||||
|
||||
bool MP4::File::save()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void MP4::File::remove()
|
||||
{
|
||||
}
|
||||
|
||||
TagLib::uint MP4::File::readSystemsLen()
|
||||
{
|
||||
TagLib::uint length = 0;
|
||||
TagLib::uint nbytes = 0;
|
||||
ByteVector input;
|
||||
TagLib::uchar tmp_input;
|
||||
|
||||
do
|
||||
{
|
||||
input = readBlock(1);
|
||||
tmp_input = static_cast<TagLib::uchar>(input[0]);
|
||||
nbytes++;
|
||||
length = (length<<7) | (tmp_input&0x7F);
|
||||
} while( (tmp_input&0x80) && (nbytes<4) );
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
bool MP4::File::readSizeAndType( TagLib::uint& size, MP4::Fourcc& fourcc )
|
||||
{
|
||||
// read the two blocks from file
|
||||
ByteVector readsize = readBlock(4);
|
||||
ByteVector readtype = readBlock(4);
|
||||
|
||||
if( (readsize.size() != 4) || (readtype.size() != 4) )
|
||||
return false;
|
||||
|
||||
// set size
|
||||
size = static_cast<unsigned char>(readsize[0]) << 24 |
|
||||
static_cast<unsigned char>(readsize[1]) << 16 |
|
||||
static_cast<unsigned char>(readsize[2]) << 8 |
|
||||
static_cast<unsigned char>(readsize[3]);
|
||||
if (size == 0)
|
||||
return false;
|
||||
|
||||
// set fourcc
|
||||
fourcc = readtype.data();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MP4::File::readInt( TagLib::uint& toRead )
|
||||
{
|
||||
ByteVector readbuffer = readBlock(4);
|
||||
if( readbuffer.size() != 4 )
|
||||
return false;
|
||||
|
||||
toRead = static_cast<unsigned char>(readbuffer[0]) << 24 |
|
||||
static_cast<unsigned char>(readbuffer[1]) << 16 |
|
||||
static_cast<unsigned char>(readbuffer[2]) << 8 |
|
||||
static_cast<unsigned char>(readbuffer[3]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MP4::File::readShort( TagLib::uint& toRead )
|
||||
{
|
||||
ByteVector readbuffer = readBlock(2);
|
||||
if( readbuffer.size() != 2 )
|
||||
return false;
|
||||
|
||||
toRead = static_cast<unsigned char>(readbuffer[0]) << 8 |
|
||||
static_cast<unsigned char>(readbuffer[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MP4::File::readLongLong( TagLib::ulonglong& toRead )
|
||||
{
|
||||
ByteVector readbuffer = readBlock(8);
|
||||
if( readbuffer.size() != 8 )
|
||||
return false;
|
||||
|
||||
toRead = static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[0])) << 56 |
|
||||
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[1])) << 48 |
|
||||
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[2])) << 40 |
|
||||
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[3])) << 32 |
|
||||
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[4])) << 24 |
|
||||
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[5])) << 16 |
|
||||
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[6])) << 8 |
|
||||
static_cast<ulonglong>(static_cast<unsigned char>(readbuffer[7]));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MP4::File::readFourcc( TagLib::MP4::Fourcc& fourcc )
|
||||
{
|
||||
ByteVector readtype = readBlock(4);
|
||||
|
||||
if( readtype.size() != 4)
|
||||
return false;
|
||||
|
||||
// set fourcc
|
||||
fourcc = readtype.data();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
MP4::Mp4TagsProxy* MP4::File::tagProxy() const
|
||||
{
|
||||
return &d->tagsProxy;
|
||||
}
|
||||
|
||||
MP4::Mp4PropsProxy* MP4::File::propProxy() const
|
||||
{
|
||||
return &d->propsProxy;
|
||||
}
|
||||
|
||||
/* This function has been updated based on information at */
|
||||
/* "http://atomicparsley.sourceforge.net/mpeg-4files.html". */
|
||||
void fillTagFromProxy( MP4::Mp4TagsProxy& proxy, MP4::Tag& mp4tag )
|
||||
{
|
||||
// tmp buffer for each tag
|
||||
MP4::ITunesDataBox* databox;
|
||||
|
||||
databox = proxy.titleData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setTitle( datastring );
|
||||
}
|
||||
|
||||
databox = proxy.artistData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setArtist( datastring );
|
||||
}
|
||||
|
||||
databox = proxy.albumData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setAlbum( datastring );
|
||||
}
|
||||
|
||||
databox = proxy.genreData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
if (databox->flags() == 0)
|
||||
{
|
||||
// convert data to uint
|
||||
TagLib::ByteVector datavec = databox->data();
|
||||
int genreVal = static_cast<int>( datavec[1] );
|
||||
if (genreVal > 0)
|
||||
{
|
||||
TagLib::String datastring = ID3v1::genre( genreVal - 1 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setGenre( datastring );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setGenre( datastring );
|
||||
}
|
||||
}
|
||||
|
||||
databox = proxy.yearData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setYear( datastring.toInt() );
|
||||
}
|
||||
|
||||
databox = proxy.trknData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to uint
|
||||
TagLib::ByteVector datavec = databox->data();
|
||||
if( datavec.size() >= 6 )
|
||||
{
|
||||
TagLib::uint notracks = static_cast<TagLib::uint>( datavec[5] );
|
||||
mp4tag.setNumTracks( notracks );
|
||||
}
|
||||
if( datavec.size() >= 4 )
|
||||
{
|
||||
TagLib::uint trackno = static_cast<TagLib::uint>( datavec[3] );
|
||||
mp4tag.setTrack( trackno );
|
||||
}
|
||||
else
|
||||
mp4tag.setTrack( 0 );
|
||||
}
|
||||
|
||||
databox = proxy.commentData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setComment( datastring );
|
||||
}
|
||||
|
||||
databox = proxy.groupingData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setGrouping( datastring );
|
||||
}
|
||||
|
||||
databox = proxy.composerData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to string
|
||||
TagLib::String datastring( databox->data(), String::UTF8 );
|
||||
// check if string was set
|
||||
if( !(datastring == "") )
|
||||
mp4tag.setComposer( datastring );
|
||||
}
|
||||
|
||||
databox = proxy.diskData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to uint
|
||||
TagLib::ByteVector datavec = databox->data();
|
||||
if( datavec.size() >= 6 )
|
||||
{
|
||||
TagLib::uint nodiscs = static_cast<TagLib::uint>( datavec[5] );
|
||||
mp4tag.setNumDisks( nodiscs );
|
||||
}
|
||||
if( datavec.size() >= 4 )
|
||||
{
|
||||
TagLib::uint discno = static_cast<TagLib::uint>( datavec[3] );
|
||||
mp4tag.setDisk( discno );
|
||||
}
|
||||
else
|
||||
mp4tag.setDisk( 0 );
|
||||
}
|
||||
|
||||
databox = proxy.bpmData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// convert data to uint
|
||||
TagLib::ByteVector datavec = databox->data();
|
||||
|
||||
if( datavec.size() >= 2 )
|
||||
{
|
||||
TagLib::uint bpm = static_cast<TagLib::uint>( static_cast<unsigned char>(datavec[0]) << 8 |
|
||||
static_cast<unsigned char>(datavec[1]) );
|
||||
mp4tag.setBpm( bpm );
|
||||
}
|
||||
else
|
||||
mp4tag.setBpm( 0 );
|
||||
}
|
||||
|
||||
databox = proxy.coverData();
|
||||
if( databox != 0 )
|
||||
{
|
||||
// get byte vector
|
||||
mp4tag.setCover( databox->data() );
|
||||
}
|
||||
}
|
|
@ -22,8 +22,8 @@
|
|||
#ifndef TAGLIB_MP4FILE_H
|
||||
#define TAGLIB_MP4FILE_H
|
||||
|
||||
#include <tfile.h>
|
||||
#include <audioproperties.h>
|
||||
#include "tfile.h"
|
||||
#include "audioproperties.h"
|
||||
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
|
|
|
@ -1,63 +0,0 @@
|
|||
#include "mp4fourcc.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
MP4::Fourcc::Fourcc()
|
||||
{
|
||||
m_fourcc = 0U;
|
||||
}
|
||||
|
||||
MP4::Fourcc::Fourcc( TagLib::String fourcc )
|
||||
{
|
||||
m_fourcc = 0U;
|
||||
|
||||
if( fourcc.size() >= 4 )
|
||||
m_fourcc = static_cast<unsigned char>(fourcc[0]) << 24 |
|
||||
static_cast<unsigned char>(fourcc[1]) << 16 |
|
||||
static_cast<unsigned char>(fourcc[2]) << 8 |
|
||||
static_cast<unsigned char>(fourcc[3]);
|
||||
}
|
||||
|
||||
MP4::Fourcc::~Fourcc()
|
||||
{}
|
||||
|
||||
TagLib::String MP4::Fourcc::toString() const
|
||||
{
|
||||
TagLib::String fourcc;
|
||||
fourcc.append(static_cast<char>(m_fourcc >> 24 & 0xFF));
|
||||
fourcc.append(static_cast<char>(m_fourcc >> 16 & 0xFF));
|
||||
fourcc.append(static_cast<char>(m_fourcc >> 8 & 0xFF));
|
||||
fourcc.append(static_cast<char>(m_fourcc & 0xFF));
|
||||
|
||||
return fourcc;
|
||||
}
|
||||
|
||||
MP4::Fourcc::operator unsigned int() const
|
||||
{
|
||||
return m_fourcc;
|
||||
}
|
||||
|
||||
bool MP4::Fourcc::operator == (unsigned int fourccB ) const
|
||||
{
|
||||
return (m_fourcc==fourccB);
|
||||
}
|
||||
|
||||
bool MP4::Fourcc::operator != (unsigned int fourccB ) const
|
||||
{
|
||||
return (m_fourcc!=fourccB);
|
||||
}
|
||||
|
||||
MP4::Fourcc& MP4::Fourcc::operator = (unsigned int fourcc )
|
||||
{
|
||||
m_fourcc = fourcc;
|
||||
return *this;
|
||||
}
|
||||
|
||||
MP4::Fourcc& MP4::Fourcc::operator = (char fourcc[4])
|
||||
{
|
||||
m_fourcc = static_cast<unsigned char>(fourcc[0]) << 24 |
|
||||
static_cast<unsigned char>(fourcc[1]) << 16 |
|
||||
static_cast<unsigned char>(fourcc[2]) << 8 |
|
||||
static_cast<unsigned char>(fourcc[3]);
|
||||
return *this;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
#ifndef MP4FOURCC_H
|
||||
#define MP4FOURCC_H
|
||||
|
||||
#include "tstring.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
/*! union for easy fourcc / type handling */
|
||||
class Fourcc
|
||||
{
|
||||
public:
|
||||
//! std constructor
|
||||
Fourcc();
|
||||
//! string constructor
|
||||
Fourcc(TagLib::String fourcc);
|
||||
|
||||
//! destructor
|
||||
~Fourcc();
|
||||
|
||||
//! function to get a string version of the fourcc
|
||||
TagLib::String toString() const;
|
||||
//! cast operator to unsigned int
|
||||
operator unsigned int() const;
|
||||
//! comparison operator
|
||||
bool operator == (unsigned int fourccB ) const;
|
||||
//! comparison operator
|
||||
bool operator != (unsigned int fourccB ) const;
|
||||
//! assigment operator for unsigned int
|
||||
Fourcc& operator = (unsigned int fourcc );
|
||||
//! assigment operator for character string
|
||||
Fourcc& operator = (char fourcc[4]);
|
||||
|
||||
private:
|
||||
uint m_fourcc; /*!< integer code of the fourcc */
|
||||
};
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4FOURCC_H
|
|
@ -1,54 +0,0 @@
|
|||
#include <deque>
|
||||
#include <iostream>
|
||||
#include "mp4hdlrbox.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4HdlrBox::Mp4HdlrBoxPrivate
|
||||
{
|
||||
public:
|
||||
TagLib::uint pre_defined;
|
||||
MP4::Fourcc handler_type;
|
||||
TagLib::String hdlr_string;
|
||||
}; // class Mp4HdlrBoxPrivate
|
||||
|
||||
MP4::Mp4HdlrBox::Mp4HdlrBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
: Mp4IsoFullBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4HdlrBox::Mp4HdlrBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4HdlrBox::~Mp4HdlrBox()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
MP4::Fourcc MP4::Mp4HdlrBox::hdlr_type() const
|
||||
{
|
||||
return d->handler_type;
|
||||
}
|
||||
|
||||
TagLib::String MP4::Mp4HdlrBox::hdlr_string() const
|
||||
{
|
||||
return d->hdlr_string;
|
||||
}
|
||||
|
||||
void MP4::Mp4HdlrBox::parse()
|
||||
{
|
||||
TagLib::uint totalread = 12+20;
|
||||
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
if( mp4file->readInt( d->pre_defined ) == false )
|
||||
return;
|
||||
if( mp4file->readFourcc( d->handler_type ) == false )
|
||||
return;
|
||||
|
||||
// read reserved into trash
|
||||
mp4file->seek( 3*4, TagLib::File::Current );
|
||||
|
||||
// check if there are bytes remaining - used for hdlr string
|
||||
if( size() - totalread != 0 )
|
||||
d->hdlr_string = mp4file->readBlock( size()-totalread );
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef MP4HDLRBOX_H
|
||||
#define MP4HDLRBOX_H
|
||||
|
||||
#include "mp4isofullbox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4HdlrBox: public Mp4IsoFullBox
|
||||
{
|
||||
public:
|
||||
Mp4HdlrBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
|
||||
~Mp4HdlrBox();
|
||||
|
||||
//! parse hdlr contents
|
||||
void parse();
|
||||
//! get the handler type
|
||||
MP4::Fourcc hdlr_type() const;
|
||||
//! get the hdlr string
|
||||
TagLib::String hdlr_string() const;
|
||||
|
||||
private:
|
||||
class Mp4HdlrBoxPrivate;
|
||||
Mp4HdlrBoxPrivate* d;
|
||||
}; // Mp4HdlrBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4HDLRBOX_H
|
|
@ -1,76 +0,0 @@
|
|||
#include "tlist.h"
|
||||
#include <iostream>
|
||||
#include "mp4ilstbox.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4IlstBox::Mp4IlstBoxPrivate
|
||||
{
|
||||
public:
|
||||
//! container for all boxes in ilst box
|
||||
TagLib::List<Mp4IsoBox*> ilstBoxes;
|
||||
//! a box factory for creating the appropriate boxes
|
||||
MP4::BoxFactory boxfactory;
|
||||
}; // class Mp4IlstBoxPrivate
|
||||
|
||||
MP4::Mp4IlstBox::Mp4IlstBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
: Mp4IsoBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4IlstBox::Mp4IlstBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4IlstBox::~Mp4IlstBox()
|
||||
{
|
||||
TagLib::List<Mp4IsoBox*>::Iterator delIter;
|
||||
for( delIter = d->ilstBoxes.begin();
|
||||
delIter != d->ilstBoxes.end();
|
||||
delIter++ )
|
||||
{
|
||||
delete *delIter;
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::Mp4IlstBox::parse()
|
||||
{
|
||||
#if 0
|
||||
std::cout << " parsing ilst box" << std::endl;
|
||||
#endif
|
||||
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
TagLib::uint totalsize = 8;
|
||||
// parse all contained boxes
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
#if 0
|
||||
std::cout << " ";
|
||||
#endif
|
||||
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
|
||||
{
|
||||
totalsize += size;
|
||||
|
||||
// check for errors
|
||||
if( totalsize > MP4::Mp4IsoBox::size() )
|
||||
{
|
||||
std::cerr << "Error in mp4 file " << mp4file->name() << " ilst box contains bad box with name: " << fourcc.toString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// create the appropriate subclass and parse it
|
||||
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
|
||||
curbox->parsebox();
|
||||
d->ilstBoxes.append( curbox );
|
||||
|
||||
// check for end of ilst box
|
||||
if( totalsize == MP4::Mp4IsoBox::size() )
|
||||
break;
|
||||
|
||||
#if 0
|
||||
std::cout << " ";
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef MP4ILSTBOX_H
|
||||
#define MP4ILSTBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4IlstBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
Mp4IlstBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
|
||||
~Mp4IlstBox();
|
||||
|
||||
//! parse ilst contents
|
||||
void parse();
|
||||
|
||||
private:
|
||||
class Mp4IlstBoxPrivate;
|
||||
Mp4IlstBoxPrivate* d;
|
||||
}; // Mp4IlstBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4ILSTBOX_H
|
|
@ -1,55 +0,0 @@
|
|||
#include "mp4isobox.h"
|
||||
#include "tfile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4IsoBox::Mp4IsoBoxPrivate
|
||||
{
|
||||
public:
|
||||
MP4::Fourcc fourcc;
|
||||
TagLib::uint size;
|
||||
long offset;
|
||||
TagLib::File* file;
|
||||
};
|
||||
|
||||
MP4::Mp4IsoBox::Mp4IsoBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
{
|
||||
d = new MP4::Mp4IsoBox::Mp4IsoBoxPrivate();
|
||||
d->file = file;
|
||||
d->fourcc = fourcc;
|
||||
d->size = size;
|
||||
d->offset = offset;
|
||||
}
|
||||
|
||||
MP4::Mp4IsoBox::~Mp4IsoBox()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::Mp4IsoBox::parsebox()
|
||||
{
|
||||
// seek to offset
|
||||
file()->seek( offset(), File::Beginning );
|
||||
// simply call parse method of sub class
|
||||
parse();
|
||||
}
|
||||
|
||||
MP4::Fourcc MP4::Mp4IsoBox::fourcc() const
|
||||
{
|
||||
return d->fourcc;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4IsoBox::size() const
|
||||
{
|
||||
return d->size;
|
||||
}
|
||||
|
||||
long MP4::Mp4IsoBox::offset() const
|
||||
{
|
||||
return d->offset;
|
||||
}
|
||||
|
||||
TagLib::File* MP4::Mp4IsoBox::file() const
|
||||
{
|
||||
return d->file;
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
#ifndef MP4ISOBOX_H
|
||||
#define MP4ISOBOX_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
class File;
|
||||
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
//! constructor for base class
|
||||
Mp4IsoBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
//! destructor - simply freeing private ptr
|
||||
virtual ~Mp4IsoBox();
|
||||
|
||||
//! function to get the fourcc code
|
||||
MP4::Fourcc fourcc() const;
|
||||
//! function to get the size of tha atom/box
|
||||
uint size() const;
|
||||
//! function to get the offset of the atom in the mp4 file
|
||||
long offset() const;
|
||||
|
||||
//! parse wrapper to get common interface for both box and fullbox
|
||||
virtual void parsebox();
|
||||
//! pure virtual function for all subclasses to implement
|
||||
virtual void parse() = 0;
|
||||
|
||||
protected:
|
||||
//! function to get the file pointer
|
||||
TagLib::File* file() const;
|
||||
|
||||
protected:
|
||||
class Mp4IsoBoxPrivate;
|
||||
Mp4IsoBoxPrivate* d;
|
||||
};
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4ISOBOX_H
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
#include "mp4isofullbox.h"
|
||||
#include "tfile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4IsoFullBox::Mp4IsoFullBoxPrivate
|
||||
{
|
||||
public:
|
||||
uchar version;
|
||||
uint flags;
|
||||
}; // Mp4IsoFullBoxPrivate
|
||||
|
||||
|
||||
MP4::Mp4IsoFullBox::Mp4IsoFullBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
: Mp4IsoBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4IsoFullBox::Mp4IsoFullBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4IsoFullBox::~Mp4IsoFullBox()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::Mp4IsoFullBox::parsebox()
|
||||
{
|
||||
// seek to offset
|
||||
Mp4IsoBox::file()->seek(Mp4IsoBox::offset(), File::Beginning );
|
||||
// parse version and flags
|
||||
ByteVector version_flags = Mp4IsoBox::file()->readBlock(4);
|
||||
d->version = version_flags[0];
|
||||
d->flags = version_flags[1] << 16 || version_flags[2] << 8 || version_flags[3];
|
||||
// call parse method of subclass
|
||||
parse();
|
||||
}
|
||||
|
||||
TagLib::uchar MP4::Mp4IsoFullBox::version()
|
||||
{
|
||||
return d->version;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4IsoFullBox::flags()
|
||||
{
|
||||
return d->flags;
|
||||
}
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef MP4ISOFULLBOX_H
|
||||
#define MP4ISOFULLBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4IsoFullBox : public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
//! constructor for full box
|
||||
Mp4IsoFullBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
//! destructor for mp4 iso full box
|
||||
virtual ~Mp4IsoFullBox();
|
||||
|
||||
//! function to get the version of box
|
||||
uchar version();
|
||||
//! function to get the flag map
|
||||
uint flags();
|
||||
|
||||
//! parse wrapper to get common interface for both box and fullbox
|
||||
virtual void parsebox();
|
||||
|
||||
protected:
|
||||
class Mp4IsoFullBoxPrivate;
|
||||
Mp4IsoFullBoxPrivate* d;
|
||||
};
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4ISOFULLBOX_H
|
||||
|
|
@ -1,250 +0,0 @@
|
|||
#include "mp4itunestag.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Tag::TagPrivate
|
||||
{
|
||||
public:
|
||||
MP4::File* mp4file;
|
||||
TagLib::String title;
|
||||
TagLib::String artist;
|
||||
TagLib::String album;
|
||||
TagLib::String genre;
|
||||
TagLib::uint year;
|
||||
TagLib::uint track;
|
||||
TagLib::uint numTracks;
|
||||
TagLib::String comment;
|
||||
TagLib::String grouping;
|
||||
TagLib::String composer;
|
||||
TagLib::uint disk;
|
||||
TagLib::uint numDisks;
|
||||
TagLib::uint bpm;
|
||||
float rgAlbumGain;
|
||||
float rgAlbumPeak;
|
||||
float rgTrackGain;
|
||||
float rgTrackPeak;
|
||||
bool isEmpty;
|
||||
TagLib::ByteVector cover;
|
||||
};
|
||||
|
||||
|
||||
MP4::Tag::Tag( )
|
||||
{
|
||||
d = new TagPrivate();
|
||||
d->year = 0;
|
||||
d->track = 0;
|
||||
d->numTracks = 0;
|
||||
d->disk = 0;
|
||||
d->numTracks = 0;
|
||||
d->bpm = 0;
|
||||
d->isEmpty = true;
|
||||
}
|
||||
|
||||
MP4::Tag::~Tag()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
String MP4::Tag::title() const
|
||||
{
|
||||
return d->title;
|
||||
}
|
||||
|
||||
String MP4::Tag::artist() const
|
||||
{
|
||||
return d->artist;
|
||||
}
|
||||
|
||||
String MP4::Tag::album() const
|
||||
{
|
||||
return d->album;
|
||||
}
|
||||
|
||||
String MP4::Tag::comment() const
|
||||
{
|
||||
return d->comment;
|
||||
}
|
||||
|
||||
String MP4::Tag::genre() const
|
||||
{
|
||||
return d->genre;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Tag::year() const
|
||||
{
|
||||
return d->year;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Tag::track() const
|
||||
{
|
||||
return d->track;
|
||||
}
|
||||
|
||||
float MP4::Tag::rgAlbumGain() const
|
||||
{
|
||||
return d->rgAlbumGain;
|
||||
}
|
||||
|
||||
float MP4::Tag::rgAlbumPeak() const
|
||||
{
|
||||
return d->rgAlbumPeak;
|
||||
}
|
||||
|
||||
float MP4::Tag::rgTrackGain() const
|
||||
{
|
||||
return d->rgTrackGain;
|
||||
}
|
||||
|
||||
float MP4::Tag::rgTrackPeak() const
|
||||
{
|
||||
return d->rgTrackPeak;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Tag::numTracks() const
|
||||
{
|
||||
return d->numTracks;
|
||||
}
|
||||
|
||||
String MP4::Tag::grouping() const
|
||||
{
|
||||
return d->grouping;
|
||||
}
|
||||
|
||||
String MP4::Tag::composer() const
|
||||
{
|
||||
return d->composer;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Tag::disk() const
|
||||
{
|
||||
return d->disk;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Tag::numDisks() const
|
||||
{
|
||||
return d->numDisks;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Tag::bpm() const
|
||||
{
|
||||
return d->bpm;
|
||||
}
|
||||
|
||||
TagLib::ByteVector MP4::Tag::cover() const
|
||||
{
|
||||
return d->cover;
|
||||
}
|
||||
|
||||
void MP4::Tag::setTitle(const String &s)
|
||||
{
|
||||
d->title = s;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setArtist(const String &s)
|
||||
{
|
||||
d->artist = s;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setAlbum(const String &s)
|
||||
{
|
||||
d->album = s;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setComment(const String &s)
|
||||
{
|
||||
d->comment = s;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setGenre(const String &s)
|
||||
{
|
||||
d->genre = s;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setYear(TagLib::uint i)
|
||||
{
|
||||
d->year = i;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setTrack(TagLib::uint i)
|
||||
{
|
||||
d->track = i;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setRGAlbumGain(float f)
|
||||
{
|
||||
d->rgAlbumGain = f;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setRGAlbumPeak(float f)
|
||||
{
|
||||
d->rgAlbumPeak = f;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setRGTrackGain(float f)
|
||||
{
|
||||
d->rgTrackGain = f;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setRGTrackPeak(float f)
|
||||
{
|
||||
d->rgTrackPeak = f;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setNumTracks(TagLib::uint i)
|
||||
{
|
||||
d->numTracks = i;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setGrouping(const String &s)
|
||||
{
|
||||
d->grouping = s;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setComposer(const String &s)
|
||||
{
|
||||
d->composer = s;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setDisk(const TagLib::uint i)
|
||||
{
|
||||
d->disk = i;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setNumDisks(const TagLib::uint i)
|
||||
{
|
||||
d->numDisks = i;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setBpm(const TagLib::uint i)
|
||||
{
|
||||
d->bpm = i;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
void MP4::Tag::setCover(const TagLib::ByteVector& c)
|
||||
{
|
||||
d->cover = c;
|
||||
d->isEmpty = false;
|
||||
}
|
||||
|
||||
bool MP4::Tag::isEmpty() const
|
||||
{
|
||||
return d->isEmpty;
|
||||
}
|
||||
|
|
@ -1,84 +0,0 @@
|
|||
#ifndef MP4ITUNESTAG_H
|
||||
#define MP4ITUNESTAG_H
|
||||
|
||||
#include "taglib.h"
|
||||
#include "tstring.h"
|
||||
#include "tag.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class File;
|
||||
|
||||
class Tag : public TagLib::Tag
|
||||
{
|
||||
public:
|
||||
/*!
|
||||
* Constructs an empty MP4 iTunes tag.
|
||||
*/
|
||||
Tag( );
|
||||
|
||||
/*!
|
||||
* Destroys this Tag instance.
|
||||
*/
|
||||
virtual ~Tag();
|
||||
|
||||
// Reimplementations.
|
||||
|
||||
virtual String title() const;
|
||||
virtual String artist() const;
|
||||
virtual String album() const;
|
||||
virtual String comment() const;
|
||||
virtual String genre() const;
|
||||
virtual uint year() const;
|
||||
virtual uint track() const;
|
||||
virtual float rgAlbumGain() const;
|
||||
virtual float rgAlbumPeak() const;
|
||||
virtual float rgTrackGain() const;
|
||||
virtual float rgTrackPeak() const;
|
||||
|
||||
virtual void setTitle(const String &s);
|
||||
virtual void setArtist(const String &s);
|
||||
virtual void setAlbum(const String &s);
|
||||
virtual void setComment(const String &s);
|
||||
virtual void setGenre(const String &s);
|
||||
virtual void setYear(uint i);
|
||||
virtual void setTrack(uint i);
|
||||
virtual void setRGAlbumGain(float f);
|
||||
virtual void setRGAlbumPeak(float f);
|
||||
virtual void setRGTrackGain(float f);
|
||||
virtual void setRGTrackPeak(float f);
|
||||
|
||||
// MP4 specific fields
|
||||
|
||||
String grouping() const;
|
||||
String composer() const;
|
||||
uint numTracks() const;
|
||||
uint disk() const;
|
||||
uint numDisks() const;
|
||||
uint bpm() const;
|
||||
ByteVector cover() const;
|
||||
|
||||
void setGrouping(const String &s);
|
||||
void setComposer(const String &s);
|
||||
void setNumTracks(const uint i);
|
||||
void setDisk(const uint i);
|
||||
void setNumDisks(const uint i);
|
||||
void setBpm(const uint i);
|
||||
void setCover( const ByteVector& cover );
|
||||
|
||||
virtual bool isEmpty() const;
|
||||
|
||||
private:
|
||||
Tag(const Tag &);
|
||||
Tag &operator=(const Tag &);
|
||||
|
||||
class TagPrivate;
|
||||
TagPrivate *d;
|
||||
};
|
||||
} // namespace MP4
|
||||
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4ITUNESTAG_H
|
|
@ -1,90 +0,0 @@
|
|||
#include "tlist.h"
|
||||
#include <iostream>
|
||||
#include "mp4mdiabox.h"
|
||||
#include "mp4hdlrbox.h"
|
||||
#include "mp4minfbox.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4MdiaBox::Mp4MdiaBoxPrivate
|
||||
{
|
||||
public:
|
||||
//! container for all boxes in mdia box
|
||||
TagLib::List<Mp4IsoBox*> mdiaBoxes;
|
||||
//! a box factory for creating the appropriate boxes
|
||||
MP4::BoxFactory boxfactory;
|
||||
}; // class Mp4MdiaBoxPrivate
|
||||
|
||||
MP4::Mp4MdiaBox::Mp4MdiaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
: Mp4IsoBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4MdiaBox::Mp4MdiaBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4MdiaBox::~Mp4MdiaBox()
|
||||
{
|
||||
TagLib::List<Mp4IsoBox*>::Iterator delIter;
|
||||
for( delIter = d->mdiaBoxes.begin();
|
||||
delIter != d->mdiaBoxes.end();
|
||||
delIter++ )
|
||||
{
|
||||
delete *delIter;
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::Mp4MdiaBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
TagLib::uint totalsize = 8;
|
||||
// parse all contained boxes
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
// stores the current handler type
|
||||
TagLib::MP4::Fourcc hdlrtype;
|
||||
|
||||
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
|
||||
{
|
||||
totalsize += size;
|
||||
|
||||
// check for errors
|
||||
if( totalsize > MP4::Mp4IsoBox::size() )
|
||||
{
|
||||
std::cerr << "Error in mp4 file " << mp4file->name() << " mdia box contains bad box with name: " << fourcc.toString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// create the appropriate subclass and parse it
|
||||
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
|
||||
if( static_cast<TagLib::uint>( fourcc ) == 0x6d696e66 /*"minf"*/ )
|
||||
{
|
||||
// cast to minf
|
||||
Mp4MinfBox* minfbox = static_cast<Mp4MinfBox*>( curbox );
|
||||
if(!minfbox)
|
||||
return;
|
||||
// set handler type
|
||||
minfbox->setHandlerType( hdlrtype );
|
||||
}
|
||||
|
||||
curbox->parsebox();
|
||||
d->mdiaBoxes.append( curbox );
|
||||
|
||||
if(static_cast<TagLib::uint>( fourcc ) == 0x68646c72 /*"hdlr"*/ )
|
||||
{
|
||||
// cast to hdlr box
|
||||
Mp4HdlrBox* hdlrbox = static_cast<Mp4HdlrBox*>( curbox );
|
||||
if(!hdlrbox)
|
||||
return;
|
||||
// get handler type
|
||||
hdlrtype = hdlrbox->hdlr_type();
|
||||
}
|
||||
// check for end of mdia box
|
||||
if( totalsize == MP4::Mp4IsoBox::size() )
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef MP4MDIABOX_H
|
||||
#define MP4MDIABOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4MdiaBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
Mp4MdiaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
|
||||
~Mp4MdiaBox();
|
||||
|
||||
//! parse mdia contents
|
||||
void parse();
|
||||
|
||||
private:
|
||||
class Mp4MdiaBoxPrivate;
|
||||
Mp4MdiaBoxPrivate* d;
|
||||
}; // Mp4MdiaBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4MDIABOX_H
|
|
@ -1,65 +0,0 @@
|
|||
#include <tlist.h>
|
||||
#include <iostream>
|
||||
#include "mp4metabox.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4MetaBox::Mp4MetaBoxPrivate
|
||||
{
|
||||
public:
|
||||
//! container for all boxes in meta box
|
||||
TagLib::List<Mp4IsoBox*> metaBoxes;
|
||||
//! a box factory for creating the appropriate boxes
|
||||
MP4::BoxFactory boxfactory;
|
||||
}; // class Mp4MetaBoxPrivate
|
||||
|
||||
MP4::Mp4MetaBox::Mp4MetaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
: Mp4IsoFullBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4MetaBox::Mp4MetaBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4MetaBox::~Mp4MetaBox()
|
||||
{
|
||||
TagLib::List<Mp4IsoBox*>::Iterator delIter;
|
||||
for( delIter = d->metaBoxes.begin();
|
||||
delIter != d->metaBoxes.end();
|
||||
delIter++ )
|
||||
{
|
||||
delete *delIter;
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::Mp4MetaBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
TagLib::uint totalsize = 12; // initial size of box
|
||||
// parse all contained boxes
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
|
||||
{
|
||||
totalsize += size;
|
||||
|
||||
// check for errors
|
||||
if( totalsize > MP4::Mp4IsoBox::size() )
|
||||
{
|
||||
std::cerr << "Error in mp4 file " << mp4file->name() << " meta box contains bad box with name: " << fourcc.toString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// create the appropriate subclass and parse it
|
||||
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
|
||||
curbox->parsebox();
|
||||
d->metaBoxes.append( curbox );
|
||||
|
||||
// check for end of meta box
|
||||
if( totalsize == MP4::Mp4IsoBox::size() )
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef MP4METABOX_H
|
||||
#define MP4METABOX_H
|
||||
|
||||
#include "mp4isofullbox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4MetaBox: public Mp4IsoFullBox
|
||||
{
|
||||
public:
|
||||
Mp4MetaBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
|
||||
~Mp4MetaBox();
|
||||
|
||||
//! parse meta contents
|
||||
void parse();
|
||||
|
||||
private:
|
||||
class Mp4MetaBoxPrivate;
|
||||
Mp4MetaBoxPrivate* d;
|
||||
}; // Mp4MetaBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4METABOX_H
|
|
@ -1,83 +0,0 @@
|
|||
#include "tlist.h"
|
||||
#include <iostream>
|
||||
#include "mp4minfbox.h"
|
||||
#include "mp4stblbox.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4MinfBox::Mp4MinfBoxPrivate
|
||||
{
|
||||
public:
|
||||
//! container for all boxes in minf box
|
||||
TagLib::List<Mp4IsoBox*> minfBoxes;
|
||||
//! a box factory for creating the appropriate boxes
|
||||
MP4::BoxFactory boxfactory;
|
||||
//! stores the handler type of the current trak
|
||||
MP4::Fourcc handler_type;
|
||||
}; // class Mp4MinfBoxPrivate
|
||||
|
||||
MP4::Mp4MinfBox::Mp4MinfBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
: Mp4IsoBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4MinfBox::Mp4MinfBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4MinfBox::~Mp4MinfBox()
|
||||
{
|
||||
TagLib::List<Mp4IsoBox*>::Iterator delIter;
|
||||
for( delIter = d->minfBoxes.begin();
|
||||
delIter != d->minfBoxes.end();
|
||||
delIter++ )
|
||||
{
|
||||
delete *delIter;
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::Mp4MinfBox::setHandlerType( MP4::Fourcc fourcc )
|
||||
{
|
||||
d->handler_type = fourcc;
|
||||
}
|
||||
|
||||
void MP4::Mp4MinfBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
TagLib::uint totalsize = 8;
|
||||
// parse all contained boxes
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
|
||||
{
|
||||
totalsize += size;
|
||||
|
||||
// check for errors
|
||||
if( totalsize > MP4::Mp4IsoBox::size() )
|
||||
{
|
||||
std::cerr << "Error in mp4 file " << mp4file->name() << " minf box contains bad box with name: " << fourcc.toString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// create the appropriate subclass and parse it
|
||||
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
|
||||
if(static_cast<TagLib::uint>( fourcc ) == 0x7374626c /*stbl*/ )
|
||||
{
|
||||
// cast to hdlr box
|
||||
Mp4StblBox* stblbox = static_cast<Mp4StblBox*>( curbox );
|
||||
if(!stblbox)
|
||||
return;
|
||||
// set handler type
|
||||
stblbox->setHandlerType( d->handler_type );
|
||||
}
|
||||
|
||||
curbox->parsebox();
|
||||
d->minfBoxes.append( curbox );
|
||||
|
||||
// check for end of minf box
|
||||
if( totalsize == MP4::Mp4IsoBox::size() )
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef MP4MINFBOX_H
|
||||
#define MP4MINFBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4MinfBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
Mp4MinfBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
|
||||
~Mp4MinfBox();
|
||||
|
||||
//! parse minf contents
|
||||
void parse();
|
||||
//! set the handler type - needed for stsd
|
||||
void setHandlerType( MP4::Fourcc fourcc );
|
||||
|
||||
private:
|
||||
class Mp4MinfBoxPrivate;
|
||||
Mp4MinfBoxPrivate* d;
|
||||
}; // Mp4MinfBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4MINFBOX_H
|
|
@ -1,65 +0,0 @@
|
|||
#include "tlist.h"
|
||||
#include <iostream>
|
||||
#include "mp4moovbox.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4MoovBox::Mp4MoovBoxPrivate
|
||||
{
|
||||
public:
|
||||
//! container for all boxes in moov box
|
||||
TagLib::List<Mp4IsoBox*> moovBoxes;
|
||||
//! a box factory for creating the appropriate boxes
|
||||
MP4::BoxFactory boxfactory;
|
||||
}; // class Mp4MoovBoxPrivate
|
||||
|
||||
MP4::Mp4MoovBox::Mp4MoovBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
: Mp4IsoBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4MoovBox::Mp4MoovBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4MoovBox::~Mp4MoovBox()
|
||||
{
|
||||
TagLib::List<Mp4IsoBox*>::Iterator delIter;
|
||||
for( delIter = d->moovBoxes.begin();
|
||||
delIter != d->moovBoxes.end();
|
||||
delIter++ )
|
||||
{
|
||||
delete *delIter;
|
||||
}
|
||||
delete d;
|
||||
}
|
||||
|
||||
void MP4::Mp4MoovBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
TagLib::uint totalsize = 8;
|
||||
// parse all contained boxes
|
||||
TagLib::uint size;
|
||||
MP4::Fourcc fourcc;
|
||||
|
||||
while( (mp4file->readSizeAndType( size, fourcc ) == true) )
|
||||
{
|
||||
totalsize += size;
|
||||
|
||||
// check for errors
|
||||
if( totalsize > MP4::Mp4IsoBox::size() )
|
||||
{
|
||||
std::cerr << "Error in mp4 file " << mp4file->name() << " moov box contains bad box with name: " << fourcc.toString() << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// create the appropriate subclass and parse it
|
||||
MP4::Mp4IsoBox* curbox = d->boxfactory.createInstance( mp4file, fourcc, size, mp4file->tell() );
|
||||
curbox->parsebox();
|
||||
d->moovBoxes.append( curbox );
|
||||
|
||||
// check for end of moov box
|
||||
if( totalsize == MP4::Mp4IsoBox::size() )
|
||||
break;
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
#ifndef MP4MOOVBOX_H
|
||||
#define MP4MOOVBOX_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4MoovBox: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
Mp4MoovBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
|
||||
~Mp4MoovBox();
|
||||
|
||||
//! parse moov contents
|
||||
void parse();
|
||||
|
||||
private:
|
||||
class Mp4MoovBoxPrivate;
|
||||
Mp4MoovBoxPrivate* d;
|
||||
}; // Mp4MoovBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4MOOVBOX_H
|
|
@ -1,119 +0,0 @@
|
|||
#include <deque>
|
||||
#include <iostream>
|
||||
#include "mp4mvhdbox.h"
|
||||
#include "boxfactory.h"
|
||||
#include "mp4file.h"
|
||||
#include "mp4propsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4MvhdBox::Mp4MvhdBoxPrivate
|
||||
{
|
||||
public:
|
||||
//! creation time of the file
|
||||
TagLib::ulonglong creationTime;
|
||||
//! modification time of the file - since midnight, Jan. 1, 1904, UTC-time
|
||||
TagLib::ulonglong modificationTime;
|
||||
//! timescale for the file - referred by all time specifications in this box
|
||||
TagLib::uint timescale;
|
||||
//! duration of presentation
|
||||
TagLib::ulonglong duration;
|
||||
//! playout speed
|
||||
TagLib::uint rate;
|
||||
//! volume for entire presentation
|
||||
TagLib::uint volume;
|
||||
//! track ID for an additional track (next new track)
|
||||
TagLib::uint nextTrackID;
|
||||
}; // class Mp4MvhdBoxPrivate
|
||||
|
||||
MP4::Mp4MvhdBox::Mp4MvhdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset )
|
||||
: Mp4IsoFullBox( file, fourcc, size, offset )
|
||||
{
|
||||
d = new MP4::Mp4MvhdBox::Mp4MvhdBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4MvhdBox::~Mp4MvhdBox()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::ulonglong MP4::Mp4MvhdBox::creationTime() const
|
||||
{
|
||||
return d->creationTime;
|
||||
}
|
||||
|
||||
TagLib::ulonglong MP4::Mp4MvhdBox::modificationTime() const
|
||||
{
|
||||
return d->modificationTime;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4MvhdBox::timescale() const
|
||||
{
|
||||
return d->timescale;
|
||||
}
|
||||
|
||||
TagLib::ulonglong MP4::Mp4MvhdBox::duration() const
|
||||
{
|
||||
return d->duration;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4MvhdBox::rate() const
|
||||
{
|
||||
return d->rate;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4MvhdBox::volume() const
|
||||
{
|
||||
return d->volume;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4MvhdBox::nextTrackID() const
|
||||
{
|
||||
return d->nextTrackID;
|
||||
}
|
||||
|
||||
|
||||
void MP4::Mp4MvhdBox::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<MP4::File*>( file() );
|
||||
|
||||
if( version() == 1 )
|
||||
{
|
||||
if( !mp4file->readLongLong( d->creationTime ) )
|
||||
return;
|
||||
if( !mp4file->readLongLong( d->modificationTime ) )
|
||||
return;
|
||||
if( !mp4file->readInt( d->timescale ) )
|
||||
return;
|
||||
if( !mp4file->readLongLong( d->duration ) )
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
TagLib::uint creationTime_tmp, modificationTime_tmp, duration_tmp;
|
||||
|
||||
if( !mp4file->readInt( creationTime_tmp ) )
|
||||
return;
|
||||
if( !mp4file->readInt( modificationTime_tmp ) )
|
||||
return;
|
||||
if( !mp4file->readInt( d->timescale ) )
|
||||
return;
|
||||
if( !mp4file->readInt( duration_tmp ) )
|
||||
return;
|
||||
|
||||
d->creationTime = creationTime_tmp;
|
||||
d->modificationTime = modificationTime_tmp;
|
||||
d->duration = duration_tmp;
|
||||
}
|
||||
if( !mp4file->readInt( d->rate ) )
|
||||
return;
|
||||
if( !mp4file->readInt( d->volume ) )
|
||||
return;
|
||||
// jump over unused fields
|
||||
mp4file->seek( 68, File::Current );
|
||||
|
||||
if( !mp4file->readInt( d->nextTrackID ) )
|
||||
return;
|
||||
// register at proxy
|
||||
mp4file->propProxy()->registerMvhd( this );
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
#ifndef MP4MVHDBOX_H
|
||||
#define MP4MVHDBOX_H
|
||||
|
||||
#include "mp4isofullbox.h"
|
||||
#include "mp4fourcc.h"
|
||||
#include "mp4file.h" // ulonglong
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4MvhdBox: public Mp4IsoFullBox
|
||||
{
|
||||
public:
|
||||
Mp4MvhdBox( TagLib::File* file, MP4::Fourcc fourcc, TagLib::uint size, long offset );
|
||||
~Mp4MvhdBox();
|
||||
|
||||
//! function to get the creation time of the mp4 file
|
||||
ulonglong creationTime() const;
|
||||
//! function to get the modification time of the mp4 file
|
||||
ulonglong modificationTime() const;
|
||||
//! function to get the timescale referenced by the above timestamps
|
||||
uint timescale() const;
|
||||
//! function to get the presentation duration in the mp4 file
|
||||
ulonglong duration() const;
|
||||
//! function to get the rate (playout speed) - typically 1.0;
|
||||
uint rate() const;
|
||||
//! function to get volume level for presentation - typically 1.0;
|
||||
uint volume() const;
|
||||
//! function to get the track ID for adding new tracks - useless for this lib
|
||||
uint nextTrackID() const;
|
||||
|
||||
//! parse mvhd contents
|
||||
void parse();
|
||||
|
||||
private:
|
||||
class Mp4MvhdBoxPrivate;
|
||||
Mp4MvhdBoxPrivate* d;
|
||||
}; // Mp4MvhdBox
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4MVHDBOX_H
|
|
@ -1,68 +0,0 @@
|
|||
#include "mp4propsproxy.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4PropsProxy::Mp4PropsProxyPrivate
|
||||
{
|
||||
public:
|
||||
//! the movie header box
|
||||
MP4::Mp4MvhdBox* mvhdbox;
|
||||
//! the sample table box
|
||||
MP4::Mp4AudioSampleEntry* audiosampleentry;
|
||||
};
|
||||
|
||||
|
||||
MP4::Mp4PropsProxy::Mp4PropsProxy()
|
||||
{
|
||||
d = new MP4::Mp4PropsProxy::Mp4PropsProxyPrivate();
|
||||
d->mvhdbox = 0;
|
||||
d->audiosampleentry = 0;
|
||||
}
|
||||
|
||||
MP4::Mp4PropsProxy::~Mp4PropsProxy()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4PropsProxy::seconds() const
|
||||
{
|
||||
if( d->mvhdbox )
|
||||
return static_cast<TagLib::uint>( d->mvhdbox->duration() / d->mvhdbox->timescale() );
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4PropsProxy::channels() const
|
||||
{
|
||||
if( d->audiosampleentry )
|
||||
return d->audiosampleentry->channels();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4PropsProxy::sampleRate() const
|
||||
{
|
||||
if( d->audiosampleentry )
|
||||
return (d->audiosampleentry->samplerate()>>16);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
TagLib::uint MP4::Mp4PropsProxy::bitRate() const
|
||||
{
|
||||
if( d->audiosampleentry )
|
||||
return (d->audiosampleentry->bitrate());
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void MP4::Mp4PropsProxy::registerMvhd( MP4::Mp4MvhdBox* mvhdbox )
|
||||
{
|
||||
d->mvhdbox = mvhdbox;
|
||||
}
|
||||
|
||||
void MP4::Mp4PropsProxy::registerAudioSampleEntry( MP4::Mp4AudioSampleEntry* audioSampleEntry )
|
||||
{
|
||||
d->audiosampleentry = audioSampleEntry;
|
||||
}
|
||||
|
|
@ -1,44 +0,0 @@
|
|||
#ifndef MP4PROPSPROXY_H
|
||||
#define MP4PROPSPROXY_H MP4PROPSPROXY_H
|
||||
#include "mp4mvhdbox.h"
|
||||
#include "mp4audiosampleentry.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
//! Mp4PropsProxy is used to access the stsd box and mvhd box directly
|
||||
/*! this class works as a shortcut to avoid stepping through all parent boxes
|
||||
* to access the boxes in question
|
||||
*/
|
||||
class Mp4PropsProxy
|
||||
{
|
||||
public:
|
||||
//! constructor for properties proxy
|
||||
Mp4PropsProxy();
|
||||
//! destructor
|
||||
~Mp4PropsProxy();
|
||||
|
||||
//! function to get length of media in seconds
|
||||
TagLib::uint seconds() const;
|
||||
//! function to get the nunmber of channels
|
||||
TagLib::uint channels() const;
|
||||
//! function to get the sample rate
|
||||
TagLib::uint sampleRate() const;
|
||||
//! function to get the bitrate rate
|
||||
TagLib::uint bitRate() const;
|
||||
|
||||
//! function to register the movie header box - mvhd
|
||||
void registerMvhd( MP4::Mp4MvhdBox* mvhdbox );
|
||||
//! function to register the sample description box
|
||||
void registerAudioSampleEntry( MP4::Mp4AudioSampleEntry* audiosampleentry );
|
||||
|
||||
private:
|
||||
class Mp4PropsProxyPrivate;
|
||||
Mp4PropsProxyPrivate* d;
|
||||
|
||||
}; // Mp4PropsProxy
|
||||
} // MP4
|
||||
} // TagLib
|
||||
|
||||
#endif // MP4PROPSPROXY_H
|
|
@ -1,38 +0,0 @@
|
|||
#include "mp4sampleentry.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4file.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4SampleEntry::Mp4SampleEntryPrivate
|
||||
{
|
||||
public:
|
||||
TagLib::uint data_reference_index;
|
||||
};
|
||||
|
||||
MP4::Mp4SampleEntry::Mp4SampleEntry( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::Mp4SampleEntry::Mp4SampleEntryPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4SampleEntry::~Mp4SampleEntry()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::Mp4SampleEntry::parse()
|
||||
{
|
||||
TagLib::MP4::File* mp4file = static_cast<TagLib::MP4::File*>(file());
|
||||
if(!mp4file)
|
||||
return;
|
||||
|
||||
// skip the first 6 bytes
|
||||
mp4file->seek( 6, TagLib::File::Current );
|
||||
// read data reference index
|
||||
if(!mp4file->readShort( d->data_reference_index))
|
||||
return;
|
||||
parseEntry();
|
||||
}
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef MP4SAMPLEENTRY_H
|
||||
#define MP4SAMPLEENTRY_H
|
||||
|
||||
#include "mp4isobox.h"
|
||||
#include "mp4fourcc.h"
|
||||
|
||||
namespace TagLib
|
||||
{
|
||||
namespace MP4
|
||||
{
|
||||
class Mp4SampleEntry: public Mp4IsoBox
|
||||
{
|
||||
public:
|
||||
Mp4SampleEntry( File* file, MP4::Fourcc fourcc, uint size, long offset );
|
||||
~Mp4SampleEntry();
|
||||
|
||||
public:
|
||||
//! parse the content of the box
|
||||
virtual void parse();
|
||||
|
||||
private:
|
||||
//! function to be implemented in subclass
|
||||
virtual void parseEntry() = 0;
|
||||
|
||||
protected:
|
||||
class Mp4SampleEntryPrivate;
|
||||
Mp4SampleEntryPrivate* d;
|
||||
}; // class Mp4SampleEntry
|
||||
|
||||
} // namespace MP4
|
||||
} // namespace TagLib
|
||||
|
||||
#endif // MP4SAMPLEENTRY_H
|
|
@ -1,29 +0,0 @@
|
|||
#include "mp4skipbox.h"
|
||||
#include "mp4isobox.h"
|
||||
#include "tfile.h"
|
||||
|
||||
using namespace TagLib;
|
||||
|
||||
class MP4::Mp4SkipBox::Mp4SkipBoxPrivate
|
||||
{
|
||||
public:
|
||||
};
|
||||
|
||||
MP4::Mp4SkipBox::Mp4SkipBox( TagLib::File* file, MP4::Fourcc fourcc, uint size, long offset )
|
||||
:Mp4IsoBox(file, fourcc, size, offset)
|
||||
{
|
||||
d = new MP4::Mp4SkipBox::Mp4SkipBoxPrivate();
|
||||
}
|
||||
|
||||
MP4::Mp4SkipBox::~Mp4SkipBox()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
//! parse the content of the box
|
||||
void MP4::Mp4SkipBox::parse()
|
||||
{
|
||||
// skip contents
|
||||
file()->seek( size() - 8, TagLib::File::Current );
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue