Universal Binary

This commit is contained in:
vspader 2006-04-17 13:12:04 +00:00
parent 29afdd5941
commit f6ab4532b3
171 changed files with 48141 additions and 0 deletions

Binary file not shown.

View file

@ -0,0 +1,8 @@
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

View file

@ -0,0 +1,481 @@
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!

View file

View file

@ -0,0 +1,167 @@
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.

View file

@ -0,0 +1,29 @@
SUBDIRS = taglib bindings tests
EXTRA_DIST = admin AUTHORS COPYING ChangeLog INSTALL README TODO taglib.lsm
AUTOMAKE_OPTIONS = foreign
$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ;
$(top_srcdir)/subdirs:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
@cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4
MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files
package-messages:
$(MAKE) -f admin/Makefile.common package-messages
dist-hook:
cd $(top_distdir) && perl admin/am_edit -padmin
cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs
examples: examples-all
examples-all:
cd examples ; \
$(MAKE) all

View file

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

View file

@ -0,0 +1,643 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
SUBDIRS = taglib bindings tests
EXTRA_DIST = admin AUTHORS COPYING ChangeLog INSTALL README TODO taglib.lsm
AUTOMAKE_OPTIONS = foreign
MAINTAINERCLEANFILES = subdirs configure.in acinclude.m4 configure.files
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
DIST_SOURCES =
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
Makefile.in TODO acinclude.m4 aclocal.m4 admin/ChangeLog \
admin/compile admin/config.guess admin/config.sub admin/depcomp \
admin/install-sh admin/ltmain.sh admin/missing \
admin/mkinstalldirs admin/ylwrap config.h.in configure \
configure.in
DIST_SUBDIRS = $(SUBDIRS)
#>- all: config.h
#>+ 1
all: docs-am config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --foreign Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
cd $(top_srcdir) && perl admin/am_edit Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)
$(top_builddir)/config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): configure.in acinclude.m4
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status config.h
$(srcdir)/config.h.in: $(top_srcdir)/configure.in $(ACLOCAL_M4)
cd $(top_srcdir) && $(AUTOHEADER)
touch $(srcdir)/config.h.in
distclean-hdr:
-rm -f config.h stamp-h1
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
#>+ 4
KDE_DIST=configure.files configure.in.in Makefile.cvs subdirs
DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
top_distdir = .
distdir = $(PACKAGE)-$(VERSION)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkinstalldirs) $(distdir)/admin $(distdir)/taglib
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" distdir="$(distdir)" \
dist-hook
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist dist-all: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
$(am__remove_distdir)
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf -
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && $(mkinstalldirs) "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist-gzip \
&& rm -f $(distdir).tar.gz \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@echo "$(distdir).tar.gz is ready for distribution" | \
sed 'h;s/./=/g;p;x;p;x'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile config.h
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(MAINTAINERCLEANFILES)" || rm -f $(MAINTAINERCLEANFILES)
#>- clean: clean-recursive
#>+ 1
clean: kde-rpo-clean clean-recursive
clean-am: clean-generic clean-libtool mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
distclean-am: clean-am distclean-generic distclean-hdr distclean-libtool \
distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-libtool clean-recursive ctags \
ctags-recursive dist dist-all dist-gzip distcheck distclean \
distclean-generic distclean-hdr distclean-libtool \
distclean-recursive distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am dvi-recursive info info-am \
info-recursive install install-am install-data install-data-am \
install-data-recursive install-exec install-exec-am \
install-exec-recursive install-info install-info-am \
install-info-recursive install-man install-recursive \
install-strip installcheck installcheck-am installdirs \
installdirs-am installdirs-recursive maintainer-clean \
maintainer-clean-generic maintainer-clean-recursive mostlyclean \
mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \
tags-recursive uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive
$(top_srcdir)/configure.in: configure.in.in $(top_srcdir)/subdirs
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common configure.in ;
$(top_srcdir)/subdirs:
cd $(top_srcdir) && $(MAKE) -f admin/Makefile.common subdirs
$(top_srcdir)/acinclude.m4: $(top_srcdir)/admin/acinclude.m4.in $(top_srcdir)/admin/libtool.m4.in
@cd $(top_srcdir) && cat admin/acinclude.m4.in admin/libtool.m4.in > acinclude.m4
package-messages:
$(MAKE) -f admin/Makefile.common package-messages
dist-hook:
cd $(top_distdir) && perl admin/am_edit -padmin
cd $(top_distdir) && $(MAKE) -f admin/Makefile.common subdirs
examples: examples-all
examples-all:
cd examples ; \
$(MAKE) all
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --foreign Makefile
cd $(top_srcdir) && perl admin/am_edit Makefile.in
#>+ 2
final:
$(MAKE) all-am
#>+ 2
final-install:
$(MAKE) install-am
#>+ 2
no-final:
$(MAKE) all-am
#>+ 2
no-final-install:
$(MAKE) install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1 @@

View file

View file

@ -0,0 +1,237 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include "tag_c.h"
#include <fileref.h>
#include <tfile.h>
#include <vorbisfile.h>
#include <mpegfile.h>
#include <flacfile.h>
#include <mpcfile.h>
#include <tag.h>
namespace TagLib
{
static List<char *> strings;
static bool unicodeStrings = true;
static bool stringManagementEnabled = true;
}
using namespace TagLib;
void taglib_set_strings_unicode(BOOL unicode)
{
unicodeStrings = bool(unicode);
}
void taglib_set_string_management_enabled(BOOL management)
{
stringManagementEnabled = bool(management);
}
////////////////////////////////////////////////////////////////////////////////
// TagLib::File wrapper
////////////////////////////////////////////////////////////////////////////////
TagLib_File *taglib_file_new(const char *filename)
{
return reinterpret_cast<TagLib_File *>(FileRef::create(filename));
}
TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type)
{
switch(type) {
case TagLib_File_MPEG:
return reinterpret_cast<TagLib_File *>(new MPEG::File(filename));
case TagLib_File_OggVorbis:
return reinterpret_cast<TagLib_File *>(new Vorbis::File(filename));
case TagLib_File_FLAC:
return reinterpret_cast<TagLib_File *>(new FLAC::File(filename));
case TagLib_File_MPC:
return reinterpret_cast<TagLib_File *>(new MPC::File(filename));
}
return 0;
}
void taglib_file_free(TagLib_File *file)
{
delete reinterpret_cast<File *>(file);
}
TagLib_Tag *taglib_file_tag(const TagLib_File *file)
{
const File *f = reinterpret_cast<const File *>(file);
return reinterpret_cast<TagLib_Tag *>(f->tag());
}
const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file)
{
const File *f = reinterpret_cast<const File *>(file);
return reinterpret_cast<const TagLib_AudioProperties *>(f->audioProperties());
}
BOOL taglib_file_save(TagLib_File *file)
{
return reinterpret_cast<File *>(file)->save();
}
////////////////////////////////////////////////////////////////////////////////
// TagLib::Tag wrapper
////////////////////////////////////////////////////////////////////////////////
char *taglib_tag_title(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
char *s = ::strdup(t->title().toCString(unicodeStrings));
if(stringManagementEnabled)
strings.append(s);
return s;
}
char *taglib_tag_artist(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
char *s = ::strdup(t->artist().toCString(unicodeStrings));
if(stringManagementEnabled)
strings.append(s);
return s;
}
char *taglib_tag_album(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
char *s = ::strdup(t->album().toCString(unicodeStrings));
if(stringManagementEnabled)
strings.append(s);
return s;
}
char *taglib_tag_comment(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
char *s = ::strdup(t->comment().toCString(unicodeStrings));
if(stringManagementEnabled)
strings.append(s);
return s;
}
char *taglib_tag_genre(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
char *s = ::strdup(t->genre().toCString(unicodeStrings));
if(stringManagementEnabled)
strings.append(s);
return s;
}
unsigned int taglib_tag_year(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
return t->year();
}
unsigned int taglib_tag_track(const TagLib_Tag *tag)
{
const Tag *t = reinterpret_cast<const Tag *>(tag);
return t->track();
}
void taglib_tag_set_title(TagLib_Tag *tag, const char *title)
{
Tag *t = reinterpret_cast<Tag *>(tag);
t->setTitle(String(title, unicodeStrings ? String::UTF8 : String::Latin1));
}
void taglib_tag_set_artist(TagLib_Tag *tag, const char *artist)
{
Tag *t = reinterpret_cast<Tag *>(tag);
t->setArtist(String(artist, unicodeStrings ? String::UTF8 : String::Latin1));
}
void taglib_tag_set_album(TagLib_Tag *tag, const char *album)
{
Tag *t = reinterpret_cast<Tag *>(tag);
t->setAlbum(String(album, unicodeStrings ? String::UTF8 : String::Latin1));
}
void taglib_tag_set_comment(TagLib_Tag *tag, const char *comment)
{
Tag *t = reinterpret_cast<Tag *>(tag);
t->setComment(String(comment, unicodeStrings ? String::UTF8 : String::Latin1));
}
void taglib_tag_set_genre(TagLib_Tag *tag, const char *genre)
{
Tag *t = reinterpret_cast<Tag *>(tag);
t->setGenre(String(genre, unicodeStrings ? String::UTF8 : String::Latin1));
}
void taglib_tag_set_year(TagLib_Tag *tag, unsigned int year)
{
Tag *t = reinterpret_cast<Tag *>(tag);
t->setYear(year);
}
void taglib_tag_set_track(TagLib_Tag *tag, unsigned int track)
{
Tag *t = reinterpret_cast<Tag *>(tag);
t->setTrack(track);
}
void taglib_tag_free_strings()
{
if(!stringManagementEnabled)
return;
for(List<char *>::Iterator it = strings.begin(); it != strings.end(); ++it)
delete [] *it;
strings.clear();
}
////////////////////////////////////////////////////////////////////////////////
// TagLib::AudioProperties wrapper
////////////////////////////////////////////////////////////////////////////////
int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties)
{
const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
return p->length();
}
int taglib_audioproperties_bitrate(const TagLib_AudioProperties *audioProperties)
{
const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
return p->bitrate();
}
int taglib_audioproperties_samplerate(const TagLib_AudioProperties *audioProperties)
{
const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
return p->sampleRate();
}
int taglib_audioproperties_channels(const TagLib_AudioProperties *audioProperties)
{
const AudioProperties *p = reinterpret_cast<const AudioProperties *>(audioProperties);
return p->channels();
}

View file

@ -0,0 +1,250 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#ifndef TAGLIB_TAG_C
#define TAGLIB_TAG_C
/* Do not include this in the main TagLib documentation. */
#ifndef DO_NOT_DOCUMENT
#ifdef __cplusplus
extern "C" {
#endif
#ifndef BOOL
#define BOOL int
#endif
/*******************************************************************************
* [ TagLib C Binding ]
*
* This is an interface to TagLib's "simple" API, meaning that you can read and
* modify media files in a generic, but not specialized way. This is a rough
* representation of TagLib::File and TagLib::Tag, for which the documentation
* is somewhat more complete and worth consulting.
*******************************************************************************/
/*
* These are used for type provide some type safety to the C API (as opposed to
* using void *, but pointers to them are simply cast to the coresponding C++
* types in the implementation.
*/
typedef struct { int dummy; } TagLib_File;
typedef struct { int dummy; } TagLib_Tag;
typedef struct { int dummy; } TagLib_AudioProperties;
/*!
* By default all strings coming into or out of TagLib's C API are in UTF8.
* However, it may be desirable for TagLib to operate on Latin1 (ISO-8859-1)
* strings in which case this should be set to FALSE.
*/
void taglib_set_strings_unicode(BOOL unicode);
/*!
* TagLib can keep track of strings that are created when outputting tag values
* and clear them using taglib_tag_clear_strings(). This is enabled by default.
* However if you wish to do more fine grained management of strings, you can do
* so by setting \a management to FALSE.
*/
void taglib_set_string_management_enabled(BOOL management);
/*******************************************************************************
* File API
******************************************************************************/
typedef enum {
TagLib_File_MPEG,
TagLib_File_OggVorbis,
TagLib_File_FLAC,
TagLib_File_MPC
} TagLib_File_Type;
/*!
* Creates a TagLib file based on \a filename. TagLib will try to guess the file
* type.
*
* \returns NULL if the file type cannot be determined or the file cannot
* be opened.
*/
TagLib_File *taglib_file_new(const char *filename);
/*!
* Creates a TagLib file based on \a filename. Rather than attempting to guess
* the type, it will use the one specified by \a type.
*/
TagLib_File *taglib_file_new_type(const char *filename, TagLib_File_Type type);
/*!
* Frees and closes the file.
*/
void taglib_file_free(TagLib_File *file);
/*!
* Returns a pointer to the tag associated with this file. This will be freed
* automatically when the file is freed.
*/
TagLib_Tag *taglib_file_tag(const TagLib_File *file);
/*!
* Returns a pointer to the the audio properties associated with this file. This
* will be freed automatically when the file is freed.
*/
const TagLib_AudioProperties *taglib_file_audioproperties(const TagLib_File *file);
/*!
* Saves the \a file to disk.
*/
BOOL taglib_file_save(TagLib_File *file);
/******************************************************************************
* Tag API
******************************************************************************/
/*!
* Returns a string with this tag's title.
*
* \note By default this string should be UTF8 encoded and its memory should be
* freed using taglib_tag_free_strings().
*/
char *taglib_tag_title(const TagLib_Tag *tag);
/*!
* Returns a string with this tag's artist.
*
* \note By default this string should be UTF8 encoded and its memory should be
* freed using taglib_tag_free_strings().
*/
char *taglib_tag_artist(const TagLib_Tag *tag);
/*!
* Returns a string with this tag's album name.
*
* \note By default this string should be UTF8 encoded and its memory should be
* freed using taglib_tag_free_strings().
*/
char *taglib_tag_album(const TagLib_Tag *tag);
/*!
* Returns a string with this tag's comment.
*
* \note By default this string should be UTF8 encoded and its memory should be
* freed using taglib_tag_free_strings().
*/
char *taglib_tag_comment(const TagLib_Tag *tag);
/*!
* Returns a string with this tag's genre.
*
* \note By default this string should be UTF8 encoded and its memory should be
* freed using taglib_tag_free_strings().
*/
char *taglib_tag_genre(const TagLib_Tag *tag);
/*!
* Returns the tag's year or 0 if year is not set.
*/
unsigned int taglib_tag_year(const TagLib_Tag *tag);
/*!
* Returns the tag's track number or 0 if track number is not set.
*/
unsigned int taglib_tag_track(const TagLib_Tag *tag);
/*!
* Sets the tag's title.
*
* \note By default this string should be UTF8 encoded.
*/
void taglib_tag_set_title(TagLib_Tag *tag, const char *title);
/*!
* Sets the tag's artist.
*
* \note By default this string should be UTF8 encoded.
*/
void taglib_tag_set_artist(TagLib_Tag *tag, const char *artist);
/*!
* Sets the tag's album.
*
* \note By default this string should be UTF8 encoded.
*/
void taglib_tag_set_album(TagLib_Tag *tag, const char *album);
/*!
* Sets the tag's comment.
*
* \note By default this string should be UTF8 encoded.
*/
void taglib_tag_set_comment(TagLib_Tag *tag, const char *comment);
/*!
* Sets the tag's genre.
*
* \note By default this string should be UTF8 encoded.
*/
void taglib_tag_set_genre(TagLib_Tag *tag, const char *genre);
/*!
* Sets the tag's year. 0 indicates that this field should be cleared.
*/
void taglib_tag_set_year(TagLib_Tag *tag, unsigned int year);
/*!
* Sets the tag's track number. 0 indicates that this field should be cleared.
*/
void taglib_tag_set_track(TagLib_Tag *tag, unsigned int track);
/*!
* Frees all of the strings that have been created by the tag.
*/
void taglib_tag_free_strings();
/******************************************************************************
* Audio Properties API
******************************************************************************/
/*!
* Returns the lenght of the file in seconds.
*/
int taglib_audioproperties_length(const TagLib_AudioProperties *audioProperties);
/*!
* Returns the bitrate of the file in kb/s.
*/
int taglib_audioproperties_bitrate(const TagLib_AudioProperties *audioProperties);
/*!
* Returns the sample rate of the file in Hz.
*/
int taglib_audioproperties_samplerate(const TagLib_AudioProperties *audioProperties);
/*!
* Returns the number of channels in the audio stream.
*/
int taglib_audioproperties_channels(const TagLib_AudioProperties *audioProperties);
#ifdef __cplusplus
}
#endif
#endif /* DO_NOT_DOCUMENT */
#endif

View file

@ -0,0 +1,65 @@
/* config.h. Generated by configure. */
/* config.h.in. Generated from configure.in by autoheader. */
/* 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
/* C++ compiler supports template repository */
#define HAVE_TEMPLATE_REPOSITORY 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* have zlib */
#define HAVE_ZLIB 0
/* 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 "0.1"

View file

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

View file

@ -0,0 +1,553 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
$(all_includes)
noinst_LTLIBRARIES = libape.la
libape_la_SOURCES = apetag.cpp apefooter.cpp apeitem.cpp
taglib_include_HEADERS = apetag.h apefooter.h apeitem.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libape_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/ape
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libape_la_LDFLAGS =
libape_la_LIBADD =
am_libape_la_OBJECTS = apetag.lo apefooter.lo apeitem.lo
#>- libape_la_OBJECTS = $(am_libape_la_OBJECTS)
#>+ 4
libape_la_final_OBJECTS = libape_la.all_cpp.lo
libape_la_nofinal_OBJECTS = apetag.lo apefooter.lo apeitem.lo
@KDE_USE_FINAL_FALSE@libape_la_OBJECTS = $(libape_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libape_la_OBJECTS = $(libape_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/apefooter.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/apeitem.Plo ./$(DEPDIR)/apetag.Plo
#>+ 5
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libape_la.all_cpp.P ./$(DEPDIR)/apefooter.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/apeitem.Plo ./$(DEPDIR)/apetag.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/apefooter.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/apeitem.Plo ./$(DEPDIR)/apetag.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libape_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
SOURCES = $(libape_la_SOURCES)
#>- all: all-am
#>+ 1
all: docs-am all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/ape/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/ape/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/ape/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libape.la: $(libape_la_OBJECTS) $(libape_la_DEPENDENCIES)
$(CXXLINK) $(libape_la_LDFLAGS) $(libape_la_OBJECTS) $(libape_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apefooter.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apeitem.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/apetag.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
#>+ 4
KDE_DIST=ape-tag-format.txt
DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/ape/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/ape/Makefile.in
#>+ 11
libape_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/apetag.cpp $(srcdir)/apefooter.cpp $(srcdir)/apeitem.cpp
@echo 'creating libape_la.all_cpp.cpp ...'; \
rm -f libape_la.all_cpp.files libape_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libape_la.all_cpp.final; \
for file in apetag.cpp apefooter.cpp apeitem.cpp ; do \
echo "#include \"$$file\"" >> libape_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libape_la.all_cpp.final; \
done; \
cat libape_la.all_cpp.final libape_la.all_cpp.files > libape_la.all_cpp.cpp; \
rm -f libape_la.all_cpp.final libape_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libape_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libape_la_OBJECTS="$(libape_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libape_la_OBJECTS="$(libape_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libape_la_OBJECTS="$(libape_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libape_la_OBJECTS="$(libape_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,170 @@
================================================================================
= 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

View file

@ -0,0 +1,232 @@
/***************************************************************************
copyright : (C) 2004 by Allan Sandfeld Jensen
(C) 2002, 2003 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 *
***************************************************************************/
#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;
}

View file

@ -0,0 +1,168 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef TAGLIB_APEFOOTER_H
#define TAGLIB_APEFOOTER_H
#include <tbytevector.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 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

View file

@ -0,0 +1,186 @@
/***************************************************************************
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 *
***************************************************************************/
#include <tbytevectorlist.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);
}
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
{
return d->value;
}
int APE::Item::size() const
{
return 8 + d->key.size() + 1 + d->value.size();
}
StringList APE::Item::toStringList() const
{
return d->text;
}
String APE::Item::toString() const
{
return 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() == "")
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;
}

View file

@ -0,0 +1,150 @@
/***************************************************************************
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 *
***************************************************************************/
#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 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.
*/
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);
/*!
* Copies the contents of \a item into this item.
*/
Item &operator=(const Item &item);
/*!
* Returns the key.
*/
String key() const;
/*!
* Returns the binary value.
*/
ByteVector value() const;
/*!
* 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;
/*!
* Returns the value as a string list.
*/
StringList toStringList() 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

View file

@ -0,0 +1,255 @@
/***************************************************************************
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 *
***************************************************************************/
#include <tdebug.h>
#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), tagOffset(-1), tagLength(0) {}
File *file;
long tagOffset;
long tagLength;
Footer footer;
ItemListMap itemListMap;
};
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
APE::Tag::Tag() : TagLib::Tag()
{
d = new TagPrivate;
}
APE::Tag::Tag(File *file, long tagOffset) : TagLib::Tag()
{
d = new TagPrivate;
d->file = file;
d->tagOffset = tagOffset;
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();
}
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);
}
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()].toStringList().append(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->tagOffset);
d->footer.setData(d->file->readBlock(Footer::size()));
if(d->footer.tagSize() == 0 ||
d->footer.tagSize() > uint(d->file->length()))
return;
d->file->seek(d->tagOffset + 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();
}
}

View file

@ -0,0 +1,157 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef TAGLIB_APETAG_H
#define TAGLIB_APETAG_H
#include <tag.h>
#include <tbytevector.h>
#include <tmap.h>
#include <tstring.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 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(File *file, long tagOffset);
/*!
* 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 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);
/*!
* 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

View file

@ -0,0 +1,47 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include "audioproperties.h"
using namespace TagLib;
class AudioProperties::AudioPropertiesPrivate
{
};
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
AudioProperties::~AudioProperties()
{
}
////////////////////////////////////////////////////////////////////////////////
// protected methods
////////////////////////////////////////////////////////////////////////////////
AudioProperties::AudioProperties(ReadStyle)
{
}

View file

@ -0,0 +1,104 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#ifndef TAGLIB_AUDIOPROPERTIES_H
#define TAGLIB_AUDIOPROPERTIES_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 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 lenght 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

View file

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

View file

@ -0,0 +1,18 @@
#AM_INIT_AUTOMAKE(taglib,1.0)
dnl don't remove the below
dnl AC_OUTPUT(taglib/taglib-config)
AC_DEFUN([AC_HAVE_ZLIB],
[
AC_DEFINE(HAVE_ZLIB, 1, [have zlib])
have_zlib=true
])
AC_DEFUN([AC_NO_ZLIB],
[
AC_DEFINE(HAVE_ZLIB, 0, [have zlib])
have_zlib=false
])
AC_CHECK_HEADER(zlib.h, AC_HAVE_ZLIB, AC_NO_ZLIB)
AM_CONDITIONAL(link_zlib, test x$have_zlib = xtrue)

View file

@ -0,0 +1,143 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include <tfile.h>
#include <tstring.h>
#include "fileref.h"
#include "mpegfile.h"
#include "vorbisfile.h"
#include "flacfile.h"
#include "mpcfile.h"
using namespace TagLib;
class FileRef::FileRefPrivate : public RefCounter
{
public:
FileRefPrivate(File *f) : RefCounter(), file(f) {}
~FileRefPrivate() {
delete file;
}
File *file;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
FileRef::FileRef()
{
d = new FileRefPrivate(0);
}
FileRef::FileRef(const char *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();
}
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(const char *fileName, bool readAudioProperties,
AudioProperties::ReadStyle audioPropertiesStyle) // static
{
// Ok, this is really dumb for now, but it works for testing.
String s = fileName;
if(s.size() > 4) {
if(s.substr(s.size() - 4, 4).upper() == ".OGG")
return new Vorbis::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".MP3")
return new MPEG::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 5, 5).upper() == ".FLAC")
return new FLAC::File(fileName, readAudioProperties, audioPropertiesStyle);
if(s.substr(s.size() - 4, 4).upper() == ".MPC")
return new MPC::File(fileName, readAudioProperties, audioPropertiesStyle);
}
return 0;
}

View file

@ -0,0 +1,183 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#ifndef TAGLIB_FILEREF_H
#define TAGLIB_FILEREF_H
#include "audioproperties.h"
namespace TagLib {
class String;
class File;
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.
*
* For example in KDE this could be done with:
*
* \code
*
* TagLib::FileRef createFileRef( const QString &fileName )
* {
* KMimeType::Ptr result = KMimeType::findByPath( fileName, 0, true );
*
* if( result->name() == "audio/x-mp3" )
* return FileRef( new MPEG::File( QFile::encodeName( fileName ).data() ) );
*
* if( result->name() == "application/ogg" )
* return FileRef( new Vorbis::File( QFile::encodeName( fileName ).data() ) );
*
* return FileRef( 0 );
* }
*
* \endcode
*/
class FileRef
{
public:
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(const char *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();
/*!
* 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.
*/
static File *create(const char *fileName,
bool readAudioProperties = true,
AudioProperties::ReadStyle audioPropertiesStyle = AudioProperties::Average);
private:
class FileRefPrivate;
FileRefPrivate *d;
};
} // namespace TagLib
#endif

View file

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

View file

@ -0,0 +1,555 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
$(all_includes)
noinst_LTLIBRARIES = libflac.la
libflac_la_SOURCES = flacfile.cpp flacproperties.cpp
taglib_include_HEADERS = flacfile.h flacproperties.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libflac_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/flac
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libflac_la_LDFLAGS =
libflac_la_LIBADD =
am_libflac_la_OBJECTS = flacfile.lo flacproperties.lo
#>- libflac_la_OBJECTS = $(am_libflac_la_OBJECTS)
#>+ 4
libflac_la_final_OBJECTS = libflac_la.all_cpp.lo
libflac_la_nofinal_OBJECTS = flacfile.lo flacproperties.lo
@KDE_USE_FINAL_FALSE@libflac_la_OBJECTS = $(libflac_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libflac_la_OBJECTS = $(libflac_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/flacfile.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/flacproperties.Plo
#>+ 5
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libflac_la.all_cpp.P ./$(DEPDIR)/flacfile.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/flacproperties.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/flacfile.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/flacproperties.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libflac_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
SOURCES = $(libflac_la_SOURCES)
#>- all: all-am
#>+ 1
all: docs-am all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/flac/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/flac/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/flac/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libflac.la: $(libflac_la_OBJECTS) $(libflac_la_DEPENDENCIES)
$(CXXLINK) $(libflac_la_LDFLAGS) $(libflac_la_OBJECTS) $(libflac_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flacfile.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/flacproperties.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
#>+ 4
KDE_DIST=flactag.h
DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/flac/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/flac/Makefile.in
#>+ 11
libflac_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/flacfile.cpp $(srcdir)/flacproperties.cpp
@echo 'creating libflac_la.all_cpp.cpp ...'; \
rm -f libflac_la.all_cpp.files libflac_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libflac_la.all_cpp.final; \
for file in flacfile.cpp flacproperties.cpp ; do \
echo "#include \"$$file\"" >> libflac_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libflac_la.all_cpp.final; \
done; \
cat libflac_la.all_cpp.final libflac_la.all_cpp.files > libflac_la.all_cpp.cpp; \
rm -f libflac_la.all_cpp.final libflac_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libflac_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libflac_la_OBJECTS="$(libflac_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libflac_la_OBJECTS="$(libflac_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libflac_la_OBJECTS="$(libflac_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libflac_la_OBJECTS="$(libflac_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,468 @@
/***************************************************************************
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 *
***************************************************************************/
#include <tbytevector.h>
#include <tstring.h>
#include <tlist.h>
#include <tdebug.h>
#include <id3v2header.h>
#include <id3v2tag.h>
#include <id3v1tag.h>
#include "flacfile.h"
#include "flactag.h"
using namespace TagLib;
namespace TagLib {
namespace FLAC {
enum BLOCK_TYPE { STREAMINFO = 0, PADDING, APPLICATION, SEEKTABLE, VORBISCOMMENT, CUESHEET };
}}
class FLAC::File::FilePrivate
{
public:
FilePrivate() :
ID3v2FrameFactory(ID3v2::FrameFactory::instance()),
ID3v2Tag(0),
ID3v2Location(-1),
ID3v2OriginalSize(0),
ID3v1Tag(0),
ID3v1Location(-1),
comment(0),
properties(0),
flacStart(0),
streamStart(0),
streamLength(0),
scanned(false),
hasXiphComment(false),
hasID3v2(false),
hasID3v1(false) {}
~FilePrivate()
{
delete ID3v2Tag;
delete ID3v1Tag;
delete comment;
delete properties;
}
const ID3v2::FrameFactory *ID3v2FrameFactory;
ID3v2::Tag *ID3v2Tag;
long ID3v2Location;
uint ID3v2OriginalSize;
ID3v1::Tag *ID3v1Tag;
long ID3v1Location;
Ogg::XiphComment *comment;
FLAC::Tag *tag;
Properties *properties;
// Map<BLOCK_TYPE, ByteVector> metaData;
ByteVector streamInfoData;
ByteVector xiphCommentData;
long flacStart;
long streamStart;
long streamLength;
bool scanned;
bool hasXiphComment;
bool hasID3v2;
bool hasID3v1;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
FLAC::File::File(const char *file, bool readProperties,
Properties::ReadStyle propertiesStyle) :
TagLib::File(file)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
FLAC::File::File(const char *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
if(!d->comment) {
d->comment = new Ogg::XiphComment;
if(d->tag)
Tag::duplicate(d->tag, d->comment, true);
}
d->xiphCommentData = d->comment->render(false);
ByteVector v = ByteVector::fromUInt(d->xiphCommentData.size());
// Set the type of the comment to be a Xiph / Vorbis comment
// (See scan() for comments on header-format)
v[0] = 4;
v.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 nextPageOffset = d->flacStart;
seek(nextPageOffset);
ByteVector header = readBlock(4);
uint length = header.mid(1, 3).toUInt();
nextPageOffset += length + 4;
// Search through the remaining metadata
char blockType = header[0] & 0x7f;
bool lastBlock = header[0] & 0x80;
while(!lastBlock) {
seek(nextPageOffset);
header = readBlock(4);
blockType = header[0] & 0x7f;
lastBlock = header[0] & 0x80;
length = header.mid(1, 3).toUInt();
// Type is vorbiscomment
if(blockType == 4) {
v[0] = header[0];
insert(v, nextPageOffset, length + 4);
break;
}
nextPageOffset += length + 4;
}
}
else {
long nextPageOffset = d->flacStart;
seek(nextPageOffset);
ByteVector header = readBlock(4);
// char blockType = header[0] & 0x7f;
bool lastBlock = header[0] & 0x80;
uint length = header.mid(1, 3).toUInt();
// If last block was last, make this one last
if(lastBlock) {
// Copy the bottom seven bits into the new value
ByteVector h(static_cast<char>(header[0] & 0x7F));
insert(h, nextPageOffset, 1);
// Set the last bit
v[0] |= 0x80;
}
insert(v, nextPageOffset + length + 4, 0);
d->hasXiphComment = true;
}
// Update ID3 tags
if(d->ID3v2Tag) {
if(d->hasID3v2)
insert(d->ID3v2Tag->render(), d->ID3v2Location, d->ID3v2OriginalSize);
else
insert(d->ID3v2Tag->render(), 0, 0);
}
if(d->ID3v1Tag) {
if(d->hasID3v1)
seek(-128, End);
else
seek(0, End);
writeBlock(d->ID3v1Tag->render());
}
return true;
}
ID3v2::Tag *FLAC::File::ID3v2Tag(bool create)
{
if(!create || d->ID3v2Tag)
return d->ID3v2Tag;
// no ID3v2 tag exists and we've been asked to create one
d->ID3v2Tag = new ID3v2::Tag;
return d->ID3v2Tag;
}
ID3v1::Tag *FLAC::File::ID3v1Tag(bool create)
{
if(!create || d->ID3v1Tag)
return d->ID3v1Tag;
// no ID3v1 tag exists and we've been asked to create one
d->ID3v1Tag = new ID3v1::Tag;
return d->ID3v1Tag;
}
Ogg::XiphComment *FLAC::File::xiphComment(bool create)
{
if(!create || d->comment)
return d->comment;
// no XiphComment exists and we've been asked to create one
d->comment = new Ogg::XiphComment;
return d->comment;
}
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->ID3v2Tag = new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory);
d->ID3v2OriginalSize = d->ID3v2Tag->header()->completeTagSize();
if(d->ID3v2Tag->header()->tagSize() <= 0) {
delete d->ID3v2Tag;
d->ID3v2Tag = 0;
}
else
d->hasID3v2 = true;
}
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for FLAC metadata, including vorbis comments
scan();
if (!isValid()) return;
if(d->hasXiphComment)
d->comment = new Ogg::XiphComment(xiphCommentData());
if(d->hasXiphComment || d->hasID3v2 || d->hasID3v1)
d->tag = new FLAC::Tag(d->comment, d->ID3v2Tag, d->ID3v1Tag);
else
d->tag = new FLAC::Tag(new Ogg::XiphComment);
if(readProperties)
d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle);
}
ByteVector FLAC::File::streamInfoData()
{
if (isValid())
return d->streamInfoData;
// return d->metaData[STREAMINFO];
else
return ByteVector();
}
ByteVector FLAC::File::xiphCommentData()
{
if (isValid() && d->hasXiphComment)
return d->xiphCommentData;
// return d->metaData[VORBISCOMMENT];
else
return ByteVector();
}
long FLAC::File::streamLength()
{
return d->streamLength;
}
void FLAC::File::scan()
{
// Scan the metadata pages
if(d->scanned)
return;
if(!isValid())
return;
long nextPageOffset;
long fileSize = length();
if (d->hasID3v2)
nextPageOffset = find("fLaC", d->ID3v2Location+d->ID3v2OriginalSize);
else
nextPageOffset = find("fLaC");
if(nextPageOffset < 0) {
debug("FLAC::File::scan() -- FLAC stream not found");
setValid(false);
return;
}
nextPageOffset += 4;
d->flacStart = nextPageOffset;
seek(nextPageOffset);
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 lastBlock = header[0] & 0x80;
uint length = header.mid(1, 3).toUInt();
// First block should be the stream_info metadata
if(blockType != 0) {
debug("FLAC::File::scan() -- invalid FLAC stream");
setValid(false);
return;
}
d->streamInfoData = readBlock(length);
// d->metadata.insert(STREAMINFO, readBlock(length));
nextPageOffset += length + 4;
// Search through the remaining metadata
while(!lastBlock) {
header = readBlock(4);
blockType = header[0] & 0x7f;
lastBlock = header[0] & 0x80;
length = header.mid(1, 3).toUInt();
if(blockType == 1) {
// debug("FLAC::File::scan() -- Padding found");
}
// Found the vorbis-comment
else if(blockType == 4) {
d->xiphCommentData = readBlock(length);
// d->metadata.insert(VORBISCOMMENT, readBlock(length));
d->hasXiphComment = true;
}
nextPageOffset += length + 4;
if (nextPageOffset >= fileSize) {
debug("FLAC::File::scan() -- FLAC stream corrupted");
setValid(false);
return;
}
seek(nextPageOffset);
}
// End of metadata, now comes the datastream
d->streamStart = nextPageOffset;
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;
}

View file

@ -0,0 +1,196 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef TAGLIB_FLACFILE_H
#define TAGLIB_FLACFILE_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 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(const char *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(const char *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();
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,146 @@
/***************************************************************************
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 *
***************************************************************************/
#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;
}

View file

@ -0,0 +1,84 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef TAGLIB_FLACPROPERTIES_H
#define TAGLIB_FLACPROPERTIES_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 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:
void read();
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,212 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef DO_NOT_DOCUMENT // Tell Doxygen not to document this header
#ifndef TAGLIB_FLACTAG_H
#define TAGLIB_FLACTAG_H
////////////////////////////////////////////////////////////////////////////////
// Note that this header is not installed.
////////////////////////////////////////////////////////////////////////////////
#include <xiphcomment.h>
#include <id3v2tag.h>
#include <id3v1tag.h>
namespace TagLib {
namespace FLAC {
/*!
* A union of Xiph, ID3v2 and ID3v1 tags.
*/
class Tag : public TagLib::Tag
{
public:
Tag(Ogg::XiphComment *xiph, ID3v2::Tag *id3v2 = 0, ID3v1::Tag *id3v1 = 0) :
TagLib::Tag(),
xiph(xiph), id3v2(id3v2), id3v1(id3v1) {}
virtual String title() const {
if(xiph && !xiph->title().isEmpty())
return xiph->title();
if(id3v2 && !id3v2->title().isEmpty())
return id3v2->title();
if(id3v1)
return id3v1->title();
return String::null;
}
virtual String artist() const {
if(xiph && !xiph->artist().isEmpty())
return xiph->artist();
if(id3v2 && !id3v2->artist().isEmpty())
return id3v2->artist();
if(id3v1)
return id3v1->artist();
return String::null;
}
virtual String album() const {
if(xiph && !xiph->album().isEmpty())
return xiph->album();
if(id3v2 && !id3v2->album().isEmpty())
return id3v2->album();
if(id3v1)
return id3v1->album();
return String::null;
}
virtual String comment() const {
if(xiph && !xiph->comment().isEmpty())
return xiph->comment();
if(id3v2 && !id3v2->comment().isEmpty())
return id3v2->comment();
if(id3v1)
return id3v1->comment();
return String::null;
}
virtual String genre() const {
if(xiph && !xiph->genre().isEmpty())
return xiph->genre();
if(id3v2 && !id3v2->genre().isEmpty())
return id3v2->genre();
if(id3v1)
return id3v1->genre();
return String::null;
}
virtual uint year() const {
if(xiph && xiph->year() > 0)
return xiph->year();
if(id3v2 && id3v2->year() > 0)
return id3v2->year();
if(id3v1)
return id3v1->year();
return 0;
}
virtual uint track() const {
if(xiph && xiph->track() > 0)
return xiph->track();
if(id3v2 && id3v2->track() > 0)
return id3v2->track();
if(id3v1)
return id3v1->track();
return 0;
}
virtual void setTitle(const String &s) {
if(xiph)
xiph->setTitle(s);
if(id3v2)
id3v2->setTitle(s);
if(id3v1)
id3v1->setTitle(s);
}
virtual void setArtist(const String &s) {
if(xiph)
xiph->setArtist(s);
if(id3v2)
id3v2->setArtist(s);
if(id3v1)
id3v1->setArtist(s);
}
virtual void setAlbum(const String &s) {
if(xiph)
xiph->setAlbum(s);
if(id3v2)
id3v2->setAlbum(s);
if(id3v1)
id3v1->setAlbum(s);
}
virtual void setComment(const String &s) {
if(xiph)
xiph->setComment(s);
if(id3v2)
id3v2->setComment(s);
if(id3v1)
id3v1->setComment(s);
}
virtual void setGenre(const String &s) {
if(xiph)
xiph->setGenre(s);
if(id3v2)
id3v2->setGenre(s);
if(id3v1)
id3v1->setGenre(s);
}
virtual void setYear(uint i) {
if(xiph)
xiph->setYear(i);
if(id3v2)
id3v2->setYear(i);
if(id3v1)
id3v1->setYear(i);
}
virtual void setTrack(uint i) {
if(xiph)
xiph->setTrack(i);
if(id3v2)
id3v2->setTrack(i);
if(id3v1)
id3v1->setTrack(i);
}
private:
Ogg::XiphComment *xiph;
ID3v2::Tag *id3v2;
ID3v1::Tag *id3v1;
};
}
}
#endif
#endif

View file

@ -0,0 +1,16 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ape \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
$(all_includes)
noinst_LTLIBRARIES = libmpc.la
libmpc_la_SOURCES = mpcfile.cpp mpcproperties.cpp
taglib_include_HEADERS = mpcfile.h mpcproperties.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libmpc_la_SOURCES) $(taglib_include_HEADERS)

View file

@ -0,0 +1,555 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ape \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
$(all_includes)
noinst_LTLIBRARIES = libmpc.la
libmpc_la_SOURCES = mpcfile.cpp mpcproperties.cpp
taglib_include_HEADERS = mpcfile.h mpcproperties.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libmpc_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/mpc
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libmpc_la_LDFLAGS =
libmpc_la_LIBADD =
am_libmpc_la_OBJECTS = mpcfile.lo mpcproperties.lo
#>- libmpc_la_OBJECTS = $(am_libmpc_la_OBJECTS)
#>+ 4
libmpc_la_final_OBJECTS = libmpc_la.all_cpp.lo
libmpc_la_nofinal_OBJECTS = mpcfile.lo mpcproperties.lo
@KDE_USE_FINAL_FALSE@libmpc_la_OBJECTS = $(libmpc_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libmpc_la_OBJECTS = $(libmpc_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/mpcfile.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/mpcproperties.Plo
#>+ 5
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libmpc_la.all_cpp.P ./$(DEPDIR)/mpcfile.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/mpcproperties.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/mpcfile.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/mpcproperties.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libmpc_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
SOURCES = $(libmpc_la_SOURCES)
#>- all: all-am
#>+ 1
all: docs-am all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/mpc/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpc/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpc/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libmpc.la: $(libmpc_la_OBJECTS) $(libmpc_la_DEPENDENCIES)
$(CXXLINK) $(libmpc_la_LDFLAGS) $(libmpc_la_OBJECTS) $(libmpc_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpcfile.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpcproperties.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
#>- DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
#>+ 4
KDE_DIST=combinedtag.h
DISTFILES= $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) $(KDE_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpc/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpc/Makefile.in
#>+ 11
libmpc_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/mpcfile.cpp $(srcdir)/mpcproperties.cpp
@echo 'creating libmpc_la.all_cpp.cpp ...'; \
rm -f libmpc_la.all_cpp.files libmpc_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libmpc_la.all_cpp.final; \
for file in mpcfile.cpp mpcproperties.cpp ; do \
echo "#include \"$$file\"" >> libmpc_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libmpc_la.all_cpp.final; \
done; \
cat libmpc_la.all_cpp.final libmpc_la.all_cpp.files > libmpc_la.all_cpp.cpp; \
rm -f libmpc_la.all_cpp.final libmpc_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libmpc_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libmpc_la_OBJECTS="$(libmpc_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libmpc_la_OBJECTS="$(libmpc_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libmpc_la_OBJECTS="$(libmpc_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libmpc_la_OBJECTS="$(libmpc_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,171 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef DO_NOT_DOCUMENT // Tell Doxygen not to document this header
#ifndef TAGLIB_COMBINEDTAG_H
#define TAGLIB_COMBINEDTAG_H
////////////////////////////////////////////////////////////////////////////////
// Note that this header is not installed.
////////////////////////////////////////////////////////////////////////////////
#include <tag.h>
namespace TagLib {
/*!
* A union of two TagLib::Tags.
*/
class CombinedTag : public TagLib::Tag
{
public:
CombinedTag(Tag *tag1 = 0, Tag *tag2 = 0)
: TagLib::Tag(),
tag1(tag1), tag2(tag2) {}
virtual String title() const {
if(tag1 && !tag1->title().isEmpty())
return tag1->title();
if(tag2)
return tag2->title();
return String::null;
}
virtual String artist() const {
if(tag1 && !tag1->artist().isEmpty())
return tag1->artist();
if(tag2)
return tag2->artist();
return String::null;
}
virtual String album() const {
if(tag1 && !tag1->album().isEmpty())
return tag1->album();
if(tag2)
return tag2->album();
return String::null;
}
virtual String comment() const {
if(tag1 && !tag1->comment().isEmpty())
return tag1->comment();
if(tag2)
return tag2->comment();
return String::null;
}
virtual String genre() const {
if(tag1 && !tag1->genre().isEmpty())
return tag1->genre();
if(tag2)
return tag2->genre();
return String::null;
}
virtual uint year() const {
if(tag1 && tag1->year() > 0)
return tag1->year();
if(tag2)
return tag2->year();
return 0;
}
virtual uint track() const {
if(tag1 && tag1->track() > 0)
return tag1->track();
if(tag2)
return tag2->track();
return 0;
}
virtual void setTitle(const String &s) {
if(tag1)
tag1->setTitle(s);
if(tag2)
tag2->setTitle(s);
}
virtual void setArtist(const String &s) {
if(tag1)
tag1->setArtist(s);
if(tag2)
tag2->setArtist(s);
}
virtual void setAlbum(const String &s) {
if(tag1)
tag1->setAlbum(s);
if(tag2)
tag2->setAlbum(s);
}
virtual void setComment(const String &s) {
if(tag1)
tag1->setComment(s);
if(tag2)
tag2->setComment(s);
}
virtual void setGenre(const String &s) {
if(tag1)
tag1->setGenre(s);
if(tag2)
tag2->setGenre(s);
}
virtual void setYear(uint i) {
if(tag1)
tag1->setYear(i);
if(tag2)
tag2->setYear(i);
}
virtual void setTrack(uint i) {
if(tag1)
tag1->setTrack(i);
if(tag2)
tag2->setTrack(i);
}
private:
Tag *tag1;
Tag *tag2;
};
}
#endif
#endif

View file

@ -0,0 +1,358 @@
/***************************************************************************
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 *
***************************************************************************/
#include <tbytevector.h>
#include <tstring.h>
#include <tdebug.h>
#include "mpcfile.h"
#include "id3v1tag.h"
#include "id3v2header.h"
#include "apetag.h"
#include "apefooter.h"
#include "combinedtag.h"
using namespace TagLib;
class MPC::File::FilePrivate
{
public:
FilePrivate() :
APETag(0),
APELocation(-1),
APESize(0),
ID3v1Tag(0),
ID3v1Location(-1),
ID3v2Header(0),
ID3v2Location(-1),
ID3v2Size(0),
tag(0),
properties(0),
scanned(false),
hasAPE(false),
hasID3v1(false),
hasID3v2(false) {}
~FilePrivate()
{
delete ID3v1Tag;
delete properties;
}
APE::Tag *APETag;
// long APEFooter;
long APELocation;
uint APESize;
ID3v1::Tag *ID3v1Tag;
long ID3v1Location;
ID3v2::Header *ID3v2Header;
long ID3v2Location;
uint ID3v2Size;
Tag *tag;
Properties *properties;
bool scanned;
// 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;
bool hasID3v2;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
MPC::File::File(const char *file, bool readProperties,
Properties::ReadStyle propertiesStyle) : TagLib::File(file)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
MPC::File::~File()
{
delete d;
}
TagLib::Tag *MPC::File::tag() const
{
return d->tag;
}
MPC::Properties *MPC::File::audioProperties() const
{
return d->properties;
}
bool MPC::File::save()
{
if(readOnly()) {
debug("MPC::File::save() -- File is read only.");
return false;
}
// Possibly strip ID3v2 tag
if(d->hasID3v2 && !d->ID3v2Header) {
removeBlock(d->ID3v2Location, d->ID3v2Size);
d->hasID3v2 = false;
if(d->hasID3v1)
d->ID3v1Location -= d->ID3v2Size;
if(d->hasAPE)
d->APELocation -= d->ID3v2Size;
}
// Update ID3v1 tag
if(d->ID3v1Tag) {
if(d->hasID3v1) {
seek(d->ID3v1Location);
writeBlock(d->ID3v1Tag->render());
}
else {
seek(0, End);
d->ID3v1Location = tell();
writeBlock(d->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(d->APETag) {
if(d->hasAPE)
insert(d->APETag->render(), d->APELocation, d->APESize);
else {
if(d->hasID3v1) {
insert(d->APETag->render(), d->ID3v1Location, 0);
d->APESize = d->APETag->footer()->completeTagSize();
d->hasAPE = true;
d->APELocation = d->ID3v1Location;
d->ID3v1Location += d->APESize;
}
else {
seek(0, End);
d->APELocation = tell();
writeBlock(d->APETag->render());
d->APESize = d->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 *MPC::File::ID3v1Tag(bool create)
{
if(!create || d->ID3v1Tag)
return d->ID3v1Tag;
// no ID3v1 tag exists and we've been asked to create one
d->ID3v1Tag = new ID3v1::Tag;
if(d->APETag)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
d->tag = d->ID3v1Tag;
return d->ID3v1Tag;
}
APE::Tag *MPC::File::APETag(bool create)
{
if(!create || d->APETag)
return d->APETag;
// no APE tag exists and we've been asked to create one
d->APETag = new APE::Tag;
if(d->ID3v1Tag)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else
d->tag = d->APETag;
return d->APETag;
}
void MPC::File::remove(int tags)
{
if(tags & ID3v1) {
delete d->ID3v1Tag;
d->ID3v1Tag = 0;
if(d->APETag)
d->tag = d->APETag;
else
d->tag = d->APETag = new APE::Tag();
}
if(tags & ID3v2) {
delete d->ID3v2Header;
d->ID3v2Header = 0;
}
if(tags & APE) {
delete d->APETag;
d->APETag = 0;
if(d->ID3v1Tag)
d->tag = d->ID3v1Tag;
else
d->tag = d->APETag = new APE::Tag();
}
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void MPC::File::read(bool readProperties, Properties::ReadStyle /* propertiesStyle */)
{
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for an APE tag
findAPE();
d->APELocation = findAPE();
if(d->APELocation >= 0) {
d->APETag = new APE::Tag(this, d->APELocation);
d->APESize = d->APETag->footer()->completeTagSize();
d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APESize;
d->hasAPE = true;
}
if(d->hasID3v1 && d->hasAPE)
d->tag = new CombinedTag(d->APETag, d->ID3v1Tag);
else {
if(d->hasID3v1)
d->tag = d->ID3v1Tag;
else {
if(d->hasAPE)
d->tag = d->APETag;
else
d->tag = d->APETag = new APE::Tag();
}
}
// Look for and skip an ID3v2 tag
d->ID3v2Location = findID3v2();
if(d->ID3v2Location >= 0) {
seek(d->ID3v2Location);
d->ID3v2Header = new ID3v2::Header(readBlock(ID3v2::Header::size()));
d->ID3v2Size = d->ID3v2Header->completeTagSize();
d->hasID3v2 = true;
}
if(d->hasID3v2)
seek(d->ID3v2Location + d->ID3v2Size);
else
seek(0);
// Look for MPC metadata
if(readProperties) {
d->properties = new Properties(readBlock(MPC::HeaderSize),
length() - d->ID3v2Size - d->APESize);
}
}
long MPC::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 MPC::File::findID3v1()
{
if(!isValid())
return -1;
seek(-128, End);
long p = tell();
if(readBlock(3) == ID3v1::Tag::fileIdentifier())
return p;
return -1;
}
long MPC::File::findID3v2()
{
if(!isValid())
return -1;
seek(0);
if(readBlock(3) == ID3v2::Header::fileIdentifier())
return 0;
return -1;
}

View file

@ -0,0 +1,162 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef TAGLIB_MPCFILE_H
#define TAGLIB_MPCFILE_H
#include "tfile.h"
#include "mpcproperties.h"
namespace TagLib {
class Tag;
namespace ID3v1 { class Tag; }
namespace APE { class Tag; }
//! An implementation of MPC metadata
/*!
* This is implementation of MPC metadata.
*
* This supports ID3v1 and APE (v1 and v2) style comments as well as reading stream
* properties from the file. ID3v2 tags are invalid in MPC-files, but will be skipped
* and ignored.
*/
namespace MPC {
//! An implementation of TagLib::File with MPC specific methods
/*!
* This implements and provides an interface for MPC 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 MPC files.
* The only invalid tag combination supported is an ID3v1 tag after an APE tag.
*/
class 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 ID3v2 tags.
ID3v2 = 0x0002,
//! Matches APE tags.
APE = 0x0004,
//! Matches all tag types.
AllTags = 0xffff
};
/*!
* Contructs an MPC 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(const char *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 MPC::Properties for this file. If no audio properties
* were read then this will return a null pointer.
*/
virtual Properties *audioProperties() const;
/*!
* Saves the file.
*/
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. If there is already an ID3v1 tag, thes
* new APE tag will be placed before 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.
*/
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 remove(int tags = AllTags);
private:
File(const File &);
File &operator=(const File &);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
void scan();
long findAPE();
long findID3v1();
long findID3v2();
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,140 @@
/***************************************************************************
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 *
***************************************************************************/
#include <tstring.h>
#include <tdebug.h>
#include <bitset>
#include "mpcproperties.h"
#include "mpcfile.h"
using namespace TagLib;
class MPC::Properties::PropertiesPrivate
{
public:
PropertiesPrivate(const ByteVector &d, long length, ReadStyle s) :
data(d),
streamLength(length),
style(s),
version(0),
length(0),
bitrate(0),
sampleRate(0),
channels(0) {}
ByteVector data;
long streamLength;
ReadStyle style;
int version;
int length;
int bitrate;
int sampleRate;
int channels;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
MPC::Properties::Properties(const ByteVector &data, long streamLength, ReadStyle style) : AudioProperties(style)
{
d = new PropertiesPrivate(data, streamLength, style);
read();
}
MPC::Properties::~Properties()
{
delete d;
}
int MPC::Properties::length() const
{
return d->length;
}
int MPC::Properties::bitrate() const
{
return d->bitrate;
}
int MPC::Properties::sampleRate() const
{
return d->sampleRate;
}
/*
int MPC::Properties::sampleWidth() const
{
return d->sampleWidth;
}
*/
int MPC::Properties::channels() const
{
return d->channels;
}
int MPC::Properties::mpcVersion() const
{
return d->version;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
static const unsigned short sftable [4] = { 44100, 48000, 37800, 32000 };
void MPC::Properties::read()
{
if(d->data.mid(0, 3) != "MP+")
return;
d->version = d->data[3] & 15;
unsigned int frames;
if(d->version >= 7) {
frames = d->data.mid(4, 4).toUInt(false);
std::bitset<32> flags = d->data.mid(8, 4).toUInt(true);
d->sampleRate = sftable[flags[17] * 2 + flags[16]];
d->channels = 2;
}
else {
unsigned int headerData = d->data.mid(0, 4).toUInt(false);
d->bitrate = (headerData >> 23) & 0x01ff;
d->version = (headerData >> 11) & 0x03ff;
d->sampleRate = 44100;
d->channels = 2;
if(d->version >= 5)
frames = d->data.mid(4, 4).toUInt(false);
else
frames = d->data.mid(4, 2).toUInt(false);
}
unsigned int samples = frames * 1152 - 576;
d->length = d->sampleRate > 0 ? (samples + (d->sampleRate / 2)) / d->sampleRate : 0;
if(!d->bitrate)
d->bitrate = d->length > 0 ? ((d->streamLength * 8L) / d->length) / 1000 : 0;
}

View file

@ -0,0 +1,77 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef TAGLIB_MPCPROPERTIES_H
#define TAGLIB_MPCPROPERTIES_H
#include "audioproperties.h"
namespace TagLib {
namespace MPC {
class File;
static const uint HeaderSize = 8*7;
//! An implementation of audio property reading for MPC
/*!
* This reads the data from an MPC stream found in the AudioProperties
* API.
*/
class Properties : public AudioProperties
{
public:
/*!
* Create an instance of MPC::Properties with the data read from the
* ByteVector \a data.
*/
Properties(const ByteVector &data, long streamLength, ReadStyle style = Average);
/*!
* Destroys this MPC::Properties instance.
*/
virtual ~Properties();
// Reimplementations.
virtual int length() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
/*!
* Returns the version of the bitstream (SV4-SV7)
*/
int mpcVersion() const;
private:
void read();
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,19 @@
SUBDIRS = id3v1 id3v2
INCLUDES = \
-I$(top_srcdir)/taglib\
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ape \
-I$(top_srcdir)/taglib/mpeg/id3v2 -I./id3v2 \
-I$(top_srcdir)/taglib/mpeg/id3v1 -I./id3v1 \
$(all_includes)
noinst_LTLIBRARIES = libmpeg.la
libmpeg_la_SOURCES = mpegfile.cpp mpegproperties.cpp mpegheader.cpp xingheader.cpp
taglib_include_HEADERS = mpegfile.h mpegproperties.h mpegheader.h xingheader.h
taglib_includedir = $(includedir)/taglib
libmpeg_la_LIBADD = ./id3v2/libid3v2.la ./id3v1/libid3v1.la
EXTRA_DIST = $(libmpeg_la_SOURCES) $(taglib_include_HEADERS)

View file

@ -0,0 +1,662 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
SUBDIRS = id3v1 id3v2
INCLUDES = \
-I$(top_srcdir)/taglib\
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ape \
-I$(top_srcdir)/taglib/mpeg/id3v2 -I./id3v2 \
-I$(top_srcdir)/taglib/mpeg/id3v1 -I./id3v1 \
$(all_includes)
noinst_LTLIBRARIES = libmpeg.la
libmpeg_la_SOURCES = mpegfile.cpp mpegproperties.cpp mpegheader.cpp xingheader.cpp
taglib_include_HEADERS = mpegfile.h mpegproperties.h mpegheader.h xingheader.h
taglib_includedir = $(includedir)/taglib
libmpeg_la_LIBADD = ./id3v2/libid3v2.la ./id3v1/libid3v1.la
EXTRA_DIST = $(libmpeg_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/mpeg
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libmpeg_la_LDFLAGS =
libmpeg_la_DEPENDENCIES = ./id3v2/libid3v2.la ./id3v1/libid3v1.la
am_libmpeg_la_OBJECTS = mpegfile.lo mpegproperties.lo mpegheader.lo \
xingheader.lo
#>- libmpeg_la_OBJECTS = $(am_libmpeg_la_OBJECTS)
#>+ 5
libmpeg_la_final_OBJECTS = libmpeg_la.all_cpp.lo
libmpeg_la_nofinal_OBJECTS = mpegfile.lo mpegproperties.lo mpegheader.lo \
xingheader.lo
@KDE_USE_FINAL_FALSE@libmpeg_la_OBJECTS = $(libmpeg_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libmpeg_la_OBJECTS = $(libmpeg_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/mpegfile.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/mpegheader.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/mpegproperties.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/xingheader.Plo
#>+ 9
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libmpeg_la.all_cpp.P ./$(DEPDIR)/mpegfile.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/mpegheader.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/mpegproperties.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/xingheader.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/mpegfile.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/mpegheader.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/mpegproperties.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/xingheader.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libmpeg_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(libmpeg_la_SOURCES)
#>- all: all-recursive
#>+ 1
all: docs-am all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/mpeg/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libmpeg.la: $(libmpeg_la_OBJECTS) $(libmpeg_la_DEPENDENCIES)
$(CXXLINK) $(libmpeg_la_LDFLAGS) $(libmpeg_la_OBJECTS) $(libmpeg_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpegfile.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpegheader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpegproperties.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xingheader.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-recursive
#>+ 1
clean: kde-rpo-clean clean-recursive
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-recursive
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-recursive ctags ctags-recursive distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-recursive distclean-tags distdir \
dvi dvi-am dvi-recursive info info-am info-recursive install \
install-am install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-recursive install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs installdirs-am \
installdirs-recursive maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \
tags-recursive uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/Makefile.in
#>+ 11
libmpeg_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/mpegfile.cpp $(srcdir)/mpegproperties.cpp $(srcdir)/mpegheader.cpp $(srcdir)/xingheader.cpp
@echo 'creating libmpeg_la.all_cpp.cpp ...'; \
rm -f libmpeg_la.all_cpp.files libmpeg_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libmpeg_la.all_cpp.final; \
for file in mpegfile.cpp mpegproperties.cpp mpegheader.cpp xingheader.cpp ; do \
echo "#include \"$$file\"" >> libmpeg_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libmpeg_la.all_cpp.final; \
done; \
cat libmpeg_la.all_cpp.final libmpeg_la.all_cpp.files > libmpeg_la.all_cpp.cpp; \
rm -f libmpeg_la.all_cpp.final libmpeg_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libmpeg_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libmpeg_la_OBJECTS="$(libmpeg_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libmpeg_la_OBJECTS="$(libmpeg_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libmpeg_la_OBJECTS="$(libmpeg_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libmpeg_la_OBJECTS="$(libmpeg_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,14 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg \
$(all_includes)
noinst_LTLIBRARIES = libid3v1.la
libid3v1_la_SOURCES = id3v1tag.cpp id3v1genres.cpp
taglib_include_HEADERS = id3v1tag.h id3v1genres.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libid3v1_la_SOURCES) $(taglib_include_HEADERS)

View file

@ -0,0 +1,548 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg \
$(all_includes)
noinst_LTLIBRARIES = libid3v1.la
libid3v1_la_SOURCES = id3v1tag.cpp id3v1genres.cpp
taglib_include_HEADERS = id3v1tag.h id3v1genres.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libid3v1_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/mpeg/id3v1
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libid3v1_la_LDFLAGS =
libid3v1_la_LIBADD =
am_libid3v1_la_OBJECTS = id3v1tag.lo id3v1genres.lo
#>- libid3v1_la_OBJECTS = $(am_libid3v1_la_OBJECTS)
#>+ 4
libid3v1_la_final_OBJECTS = libid3v1_la.all_cpp.lo
libid3v1_la_nofinal_OBJECTS = id3v1tag.lo id3v1genres.lo
@KDE_USE_FINAL_FALSE@libid3v1_la_OBJECTS = $(libid3v1_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libid3v1_la_OBJECTS = $(libid3v1_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/id3v1genres.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/id3v1tag.Plo
#>+ 5
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libid3v1_la.all_cpp.P ./$(DEPDIR)/id3v1genres.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v1tag.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/id3v1genres.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v1tag.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libid3v1_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
SOURCES = $(libid3v1_la_SOURCES)
#>- all: all-am
#>+ 1
all: docs-am all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/mpeg/id3v1/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/id3v1/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v1/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libid3v1.la: $(libid3v1_la_OBJECTS) $(libid3v1_la_DEPENDENCIES)
$(CXXLINK) $(libid3v1_la_LDFLAGS) $(libid3v1_la_OBJECTS) $(libid3v1_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v1genres.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v1tag.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/id3v1/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v1/Makefile.in
#>+ 11
libid3v1_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/id3v1tag.cpp $(srcdir)/id3v1genres.cpp
@echo 'creating libid3v1_la.all_cpp.cpp ...'; \
rm -f libid3v1_la.all_cpp.files libid3v1_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libid3v1_la.all_cpp.final; \
for file in id3v1tag.cpp id3v1genres.cpp ; do \
echo "#include \"$$file\"" >> libid3v1_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libid3v1_la.all_cpp.final; \
done; \
cat libid3v1_la.all_cpp.final libid3v1_la.all_cpp.files > libid3v1_la.all_cpp.cpp; \
rm -f libid3v1_la.all_cpp.final libid3v1_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libid3v1_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libid3v1_la_OBJECTS="$(libid3v1_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libid3v1_la_OBJECTS="$(libid3v1_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libid3v1_la_OBJECTS="$(libid3v1_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libid3v1_la_OBJECTS="$(libid3v1_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,215 @@
/***************************************************************************
copyright : (C) 2002 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 *
***************************************************************************/
#include "id3v1genres.h"
using namespace TagLib;
namespace TagLib {
namespace ID3v1 {
static const int genresSize = 148;
static const String genres[] = {
"Blues",
"Classic Rock",
"Country",
"Dance",
"Disco",
"Funk",
"Grunge",
"Hip-Hop",
"Jazz",
"Metal",
"New Age",
"Oldies",
"Other",
"Pop",
"R&B",
"Rap",
"Reggae",
"Rock",
"Techno",
"Industrial",
"Alternative",
"Ska",
"Death Metal",
"Pranks",
"Soundtrack",
"Euro-Techno",
"Ambient",
"Trip-Hop",
"Vocal",
"Jazz+Funk",
"Fusion",
"Trance",
"Classical",
"Instrumental",
"Acid",
"House",
"Game",
"Sound Clip",
"Gospel",
"Noise",
"Alternative Rock",
"Bass",
"Soul",
"Punk",
"Space",
"Meditative",
"Instrumental Pop",
"Instrumental Rock",
"Ethnic",
"Gothic",
"Darkwave",
"Techno-Industrial",
"Electronic",
"Pop-Folk",
"Eurodance",
"Dream",
"Southern Rock",
"Comedy",
"Cult",
"Gangsta",
"Top 40",
"Christian Rap",
"Pop/Funk",
"Jungle",
"Native American",
"Cabaret",
"New Wave",
"Psychedelic",
"Rave",
"Showtunes",
"Trailer",
"Lo-Fi",
"Tribal",
"Acid Punk",
"Acid Jazz",
"Polka",
"Retro",
"Musical",
"Rock & Roll",
"Hard Rock",
"Folk",
"Folk/Rock",
"National Folk",
"Swing",
"Fusion",
"Bebob",
"Latin",
"Revival",
"Celtic",
"Bluegrass",
"Avantgarde",
"Gothic Rock",
"Progressive Rock",
"Psychedelic Rock",
"Symphonic Rock",
"Slow Rock",
"Big Band",
"Chorus",
"Easy Listening",
"Acoustic",
"Humour",
"Speech",
"Chanson",
"Opera",
"Chamber Music",
"Sonata",
"Symphony",
"Booty Bass",
"Primus",
"Porn Groove",
"Satire",
"Slow Jam",
"Club",
"Tango",
"Samba",
"Folklore",
"Ballad",
"Power Ballad",
"Rhythmic Soul",
"Freestyle",
"Duet",
"Punk Rock",
"Drum Solo",
"A Capella",
"Euro-House",
"Dance Hall",
"Goa",
"Drum & Bass",
"Club-House",
"Hardcore",
"Terror",
"Indie",
"BritPop",
"Negerpunk",
"Polsk Punk",
"Beat",
"Christian Gangsta Rap",
"Heavy Metal",
"Black Metal",
"Crossover",
"Contemporary Christian",
"Christian Rock",
"Merengue",
"Salsa",
"Thrash Metal",
"Anime",
"Jpop",
"Synthpop"
};
}
}
StringList ID3v1::genreList()
{
static StringList l;
if(l.isEmpty()) {
for(int i = 0; i < genresSize; i++)
l.append(genres[i]);
}
return l;
}
ID3v1::GenreMap ID3v1::genreMap()
{
static GenreMap m;
if(m.isEmpty()) {
for(int i = 0; i < genresSize; i++)
m.insert(genres[i], i);
}
return m;
}
String ID3v1::genre(int i)
{
if(i >= 0 && i < genresSize)
return genres[i];
return String::null;
}
int ID3v1::genreIndex(const String &name)
{
if(genreMap().contains(name))
return genreMap()[name];
return 255;
}

View file

@ -0,0 +1,61 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V1GENRE_H
#define TAGLIB_ID3V1GENRE_H
#include <tmap.h>
#include <tstringlist.h>
namespace TagLib {
namespace ID3v1 {
typedef Map<String, int> GenreMap;
/*!
* Returns the list of canonical ID3v1 genre names in the order that they
* are listed in the standard.
*/
StringList genreList();
/*!
* A "reverse mapping" that goes from the canonical ID3v1 genre name to the
* respective genre number. genreMap()["Rock"] ==
*/
GenreMap genreMap();
/*!
* Returns the name of the genre at \a index in the ID3v1 genre list. If
* \a index is out of range -- less than zero or greater than 146 -- a null
* string will be returned.
*/
String genre(int index);
/*!
* Returns the genre index for the (case sensitive) genre \a name. If the
* genre is not in the list 255 (which signifies an unknown genre in ID3v1)
* will be returned.
*/
int genreIndex(const String &name);
}
}
#endif

View file

@ -0,0 +1,256 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <tdebug.h>
#include <tfile.h>
#include "id3v1tag.h"
#include "id3v1genres.h"
using namespace TagLib;
using namespace ID3v1;
class ID3v1::Tag::TagPrivate
{
public:
TagPrivate() : file(0), tagOffset(-1), track(0), genre(255) {}
File *file;
long tagOffset;
String title;
String artist;
String album;
String year;
String comment;
uchar track;
uchar genre;
static const StringHandler *stringHandler;
};
const ID3v1::StringHandler *ID3v1::Tag::TagPrivate::stringHandler = new StringHandler;
////////////////////////////////////////////////////////////////////////////////
// StringHandler implementation
////////////////////////////////////////////////////////////////////////////////
String ID3v1::StringHandler::parse(const ByteVector &data) const
{
return clean(String(data, String::Latin1));
}
ByteVector ID3v1::StringHandler::render(const String &s) const
{
return s.data(String::Latin1);
}
String ID3v1::StringHandler::clean(const String &s) const
{
String newString;
int i;
newString = s;
i = newString.size() - 1;
while (s[i] == ' ' && i >= 0)
{
newString[i] = '\0';
i--;
}
return newString;
}
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
ID3v1::Tag::Tag() : TagLib::Tag()
{
d = new TagPrivate;
}
ID3v1::Tag::Tag(File *file, long tagOffset) : TagLib::Tag()
{
d = new TagPrivate;
d->file = file;
d->tagOffset = tagOffset;
read();
}
ID3v1::Tag::~Tag()
{
delete d;
}
ByteVector ID3v1::Tag::render() const
{
ByteVector data;
data.append(fileIdentifier());
data.append(TagPrivate::stringHandler->render(d->title).resize(30));
data.append(TagPrivate::stringHandler->render(d->artist).resize(30));
data.append(TagPrivate::stringHandler->render(d->album).resize(30));
data.append(TagPrivate::stringHandler->render(d->year).resize(4));
data.append(TagPrivate::stringHandler->render(d->comment).resize(28));
data.append(char(0));
data.append(char(d->track));
data.append(char(d->genre));
return data;
}
ByteVector ID3v1::Tag::fileIdentifier()
{
return ByteVector::fromCString("TAG");
}
String ID3v1::Tag::title() const
{
return d->title;
}
String ID3v1::Tag::artist() const
{
return d->artist;
}
String ID3v1::Tag::album() const
{
return d->album;
}
String ID3v1::Tag::comment() const
{
return d->comment;
}
String ID3v1::Tag::genre() const
{
return ID3v1::genre(d->genre);
}
TagLib::uint ID3v1::Tag::year() const
{
return d->year.toInt();
}
TagLib::uint ID3v1::Tag::track() const
{
return d->track;
}
void ID3v1::Tag::setTitle(const String &s)
{
d->title = s;
}
void ID3v1::Tag::setArtist(const String &s)
{
d->artist = s;
}
void ID3v1::Tag::setAlbum(const String &s)
{
d->album = s;
}
void ID3v1::Tag::setComment(const String &s)
{
d->comment = s;
}
void ID3v1::Tag::setGenre(const String &s)
{
d->genre = ID3v1::genreIndex(s);
}
void ID3v1::Tag::setYear(uint i)
{
d->year = String::number(i);
}
void ID3v1::Tag::setTrack(uint i)
{
d->track = i < 256 ? i : 0;
}
void ID3v1::Tag::setStringHandler(const StringHandler *handler)
{
delete TagPrivate::stringHandler;
TagPrivate::stringHandler = handler;
}
////////////////////////////////////////////////////////////////////////////////
// protected methods
////////////////////////////////////////////////////////////////////////////////
void ID3v1::Tag::read()
{
if(d->file && d->file->isValid()) {
d->file->seek(d->tagOffset);
// read the tag -- always 128 bytes
ByteVector data = d->file->readBlock(128);
// some initial sanity checking
if(data.size() == 128 && data.mid(0, 3) == "TAG")
parse(data);
else
debug("ID3v1 tag is not valid or could not be read at the specified offset.");
}
}
void ID3v1::Tag::parse(const ByteVector &data)
{
int offset = 3;
d->title = TagPrivate::stringHandler->parse(data.mid(offset, 30));
offset += 30;
d->artist = TagPrivate::stringHandler->parse(data.mid(offset, 30));
offset += 30;
d->album = TagPrivate::stringHandler->parse(data.mid(offset, 30));
offset += 30;
d->year = TagPrivate::stringHandler->parse(data.mid(offset, 4));
offset += 4;
// Check for ID3v1.1 -- Note that ID3v1 *does not* support "track zero" -- this
// is not a bug in TagLib. Since a zeroed byte is what we would expect to
// indicate the end of a C-String, specifically the comment string, a value of
// zero must be assumed to be just that.
if(data[offset + 28] == 0 && data[offset + 29] != 0) {
// ID3v1.1 detected
d->comment = TagPrivate::stringHandler->parse(data.mid(offset, 28));
d->track = uchar(data[offset + 29]);
}
else
d->comment = data.mid(offset, 30);
offset += 30;
d->genre = uchar(data[offset]);
}

View file

@ -0,0 +1,176 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V1TAG_H
#define TAGLIB_ID3V1TAG_H
#include <tag.h>
#include <tbytevector.h>
namespace TagLib {
class File;
//! An ID3v1 implementation
namespace ID3v1 {
//! A abstraction for the string to data encoding in ID3v1 tags.
/*!
* ID3v1 should in theory always contain ISO-8859-1 (Latin1) data. In
* practice it does not. TagLib by default only supports ISO-8859-1 data
* in ID3v1 tags.
*
* However by subclassing this class and reimplementing parse() and render()
* and setting your reimplementation as the default with
* ID3v1::Tag::setStringHandler() you can define how you would like these
* transformations to be done.
*
* \warning It is advisable <b>not</b> to write non-ISO-8859-1 data to ID3v1
* tags. Please consider disabling the writing of ID3v1 tags in the case
* that the data is ISO-8859-1.
*
* \see ID3v1::Tag::setStringHandler()
*/
class StringHandler
{
public:
/*!
* Decode a string from \a data. The default implementation assumes that
* \a data is an ISO-8859-1 (Latin1) character array.
*/
virtual String parse(const ByteVector &data) const;
/*!
* Encode a ByteVector with the data from \a s. The default implementation
* assumes that \a s is an ISO-8859-1 (Latin1) string.
*
* \warning It is recommended that you <b>not</b> override this method, but
* instead do not write an ID3v1 tag in the case that the data is not
* ISO-8859-1.
*/
virtual ByteVector render(const String &s) const;
//Fixes buggy taggers which do spaces instead of 0s.
String ID3v1::StringHandler::clean(const String &s) const;
};
//! The main class in the ID3v1 implementation
/*!
* This is an implementation of the ID3v1 format. ID3v1 is both the simplist
* and most common of tag formats but is rather limited. Because of its
* pervasiveness and the way that applications have been written around the
* fields that it provides, the generic TagLib::Tag API is a mirror of what is
* provided by ID3v1.
*
* ID3v1 tags should generally only contain Latin1 information. However because
* many applications do not follow this rule there is now support for overriding
* the ID3v1 string handling using the ID3v1::StringHandler class. Please see
* the documentation for that class for more information.
*
* \see StringHandler
*
* \note Most fields are truncated to a maximum of 28-30 bytes. The
* truncation happens automatically when the tag is rendered.
*/
class Tag : public TagLib::Tag
{
public:
/*!
* Create an ID3v1 tag with default values.
*/
Tag();
/*!
* Create an ID3v1 tag and parse the data in \a file starting at
* \a tagOffset.
*/
Tag(File *file, long tagOffset);
/*!
* 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 "TAG" 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 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);
/*!
* Sets the string handler that decides how the ID3v1 data will be
* converted to and from binary data.
*
* \see StringHandler
*/
static void setStringHandler(const StringHandler *handler);
protected:
/*!
* Reads from the file specified in the constructor.
*/
void read();
/*!
* Pareses 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

View file

@ -0,0 +1,28 @@
SUBDIRS = frames
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
$(all_includes)
noinst_LTLIBRARIES = libid3v2.la
libid3v2_la_SOURCES = \
id3v2framefactory.cpp id3v2synchdata.cpp id3v2tag.cpp \
id3v2header.cpp id3v2frame.cpp id3v2footer.cpp \
id3v2extendedheader.cpp
taglib_include_HEADERS = \
id3v2extendedheader.h id3v2frame.h id3v2header.h \
id3v2synchdata.h id3v2footer.h id3v2framefactory.h id3v2tag.h
taglib_includedir = $(includedir)/taglib
if link_zlib
zlib = -lz
endif
libid3v2_la_LIBADD = ./frames/libframes.la $(zlib)
EXTRA_DIST = $(libid3v2_la_SOURCES) $(taglib_include_HEADERS) id3v2.4.0-frames.txt id3v2.4.0-structure.txt

View file

@ -0,0 +1,686 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
SUBDIRS = frames
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg \
-I$(top_srcdir)/taglib/mpeg/id3v1 \
$(all_includes)
noinst_LTLIBRARIES = libid3v2.la
libid3v2_la_SOURCES = \
id3v2framefactory.cpp id3v2synchdata.cpp id3v2tag.cpp \
id3v2header.cpp id3v2frame.cpp id3v2footer.cpp \
id3v2extendedheader.cpp
taglib_include_HEADERS = \
id3v2extendedheader.h id3v2frame.h id3v2header.h \
id3v2synchdata.h id3v2footer.h id3v2framefactory.h id3v2tag.h
taglib_includedir = $(includedir)/taglib
@link_zlib_TRUE@zlib = -lz
libid3v2_la_LIBADD = ./frames/libframes.la $(zlib)
EXTRA_DIST = $(libid3v2_la_SOURCES) $(taglib_include_HEADERS) id3v2.4.0-frames.txt id3v2.4.0-structure.txt
subdir = taglib/mpeg/id3v2
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libid3v2_la_LDFLAGS =
@link_zlib_TRUE@libid3v2_la_DEPENDENCIES = ./frames/libframes.la
@link_zlib_FALSE@libid3v2_la_DEPENDENCIES = ./frames/libframes.la
am_libid3v2_la_OBJECTS = id3v2framefactory.lo id3v2synchdata.lo \
id3v2tag.lo id3v2header.lo id3v2frame.lo id3v2footer.lo \
id3v2extendedheader.lo
#>- libid3v2_la_OBJECTS = $(am_libid3v2_la_OBJECTS)
#>+ 6
libid3v2_la_final_OBJECTS = libid3v2_la.all_cpp.lo
libid3v2_la_nofinal_OBJECTS = id3v2framefactory.lo id3v2synchdata.lo \
id3v2tag.lo id3v2header.lo id3v2frame.lo id3v2footer.lo \
id3v2extendedheader.lo
@KDE_USE_FINAL_FALSE@libid3v2_la_OBJECTS = $(libid3v2_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libid3v2_la_OBJECTS = $(libid3v2_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/id3v2extendedheader.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/id3v2footer.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/id3v2frame.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/id3v2framefactory.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/id3v2header.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/id3v2synchdata.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/id3v2tag.Plo
#>+ 15
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libid3v2_la.all_cpp.P ./$(DEPDIR)/id3v2extendedheader.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2footer.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2frame.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2framefactory.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2header.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2synchdata.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2tag.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/id3v2extendedheader.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2footer.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2frame.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2framefactory.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2header.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2synchdata.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/id3v2tag.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libid3v2_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(libid3v2_la_SOURCES)
#>- all: all-recursive
#>+ 1
all: docs-am all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libid3v2.la: $(libid3v2_la_OBJECTS) $(libid3v2_la_DEPENDENCIES)
$(CXXLINK) $(libid3v2_la_LDFLAGS) $(libid3v2_la_OBJECTS) $(libid3v2_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2extendedheader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2footer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2frame.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2framefactory.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2header.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2synchdata.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/id3v2tag.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-recursive
#>+ 1
clean: kde-rpo-clean clean-recursive
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-recursive
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-recursive ctags ctags-recursive distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-recursive distclean-tags distdir \
dvi dvi-am dvi-recursive info info-am info-recursive install \
install-am install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-recursive install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs installdirs-am \
installdirs-recursive maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \
tags-recursive uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/id3v2/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/Makefile.in
#>+ 11
libid3v2_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/id3v2framefactory.cpp $(srcdir)/id3v2synchdata.cpp $(srcdir)/id3v2tag.cpp $(srcdir)/id3v2header.cpp $(srcdir)/id3v2frame.cpp $(srcdir)/id3v2footer.cpp $(srcdir)/id3v2extendedheader.cpp
@echo 'creating libid3v2_la.all_cpp.cpp ...'; \
rm -f libid3v2_la.all_cpp.files libid3v2_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libid3v2_la.all_cpp.final; \
for file in id3v2framefactory.cpp id3v2synchdata.cpp id3v2tag.cpp id3v2header.cpp id3v2frame.cpp id3v2footer.cpp id3v2extendedheader.cpp ; do \
echo "#include \"$$file\"" >> libid3v2_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libid3v2_la.all_cpp.final; \
done; \
cat libid3v2_la.all_cpp.final libid3v2_la.all_cpp.files > libid3v2_la.all_cpp.cpp; \
rm -f libid3v2_la.all_cpp.final libid3v2_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libid3v2_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libid3v2_la_OBJECTS="$(libid3v2_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,27 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
$(all_includes)
noinst_LTLIBRARIES = libframes.la
libframes_la_SOURCES = \
attachedpictureframe.cpp \
commentsframe.cpp \
relativevolumeframe.cpp \
textidentificationframe.cpp \
uniquefileidentifierframe.cpp \
unknownframe.cpp
taglib_include_HEADERS = \
attachedpictureframe.h \
commentsframe.h \
relativevolumeframe.h \
textidentificationframe.h \
uniquefileidentifierframe.h \
unknownframe.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libframes_la_SOURCES) $(taglib_include_HEADERS)

View file

@ -0,0 +1,583 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/mpeg/id3v2 \
$(all_includes)
noinst_LTLIBRARIES = libframes.la
libframes_la_SOURCES = \
attachedpictureframe.cpp \
commentsframe.cpp \
relativevolumeframe.cpp \
textidentificationframe.cpp \
uniquefileidentifierframe.cpp \
unknownframe.cpp
taglib_include_HEADERS = \
attachedpictureframe.h \
commentsframe.h \
relativevolumeframe.h \
textidentificationframe.h \
uniquefileidentifierframe.h \
unknownframe.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(libframes_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/mpeg/id3v2/frames
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libframes_la_LDFLAGS =
libframes_la_LIBADD =
am_libframes_la_OBJECTS = attachedpictureframe.lo commentsframe.lo \
relativevolumeframe.lo textidentificationframe.lo \
uniquefileidentifierframe.lo unknownframe.lo
#>- libframes_la_OBJECTS = $(am_libframes_la_OBJECTS)
#>+ 6
libframes_la_final_OBJECTS = libframes_la.all_cpp.lo
libframes_la_nofinal_OBJECTS = attachedpictureframe.lo commentsframe.lo \
relativevolumeframe.lo textidentificationframe.lo \
uniquefileidentifierframe.lo unknownframe.lo
@KDE_USE_FINAL_FALSE@libframes_la_OBJECTS = $(libframes_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libframes_la_OBJECTS = $(libframes_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/attachedpictureframe.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/commentsframe.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/relativevolumeframe.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/textidentificationframe.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/uniquefileidentifierframe.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/unknownframe.Plo
#>+ 13
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libframes_la.all_cpp.P ./$(DEPDIR)/attachedpictureframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/commentsframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/relativevolumeframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/textidentificationframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/uniquefileidentifierframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/unknownframe.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/attachedpictureframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/commentsframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/relativevolumeframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/textidentificationframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/uniquefileidentifierframe.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/unknownframe.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libframes_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
SOURCES = $(libframes_la_SOURCES)
#>- all: all-am
#>+ 1
all: docs-am all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/frames/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libframes.la: $(libframes_la_OBJECTS) $(libframes_la_DEPENDENCIES)
$(CXXLINK) $(libframes_la_LDFLAGS) $(libframes_la_OBJECTS) $(libframes_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/attachedpictureframe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/commentsframe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/relativevolumeframe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/textidentificationframe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/uniquefileidentifierframe.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknownframe.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/mpeg/id3v2/frames/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/mpeg/id3v2/frames/Makefile.in
#>+ 11
libframes_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/attachedpictureframe.cpp $(srcdir)/commentsframe.cpp $(srcdir)/relativevolumeframe.cpp $(srcdir)/textidentificationframe.cpp $(srcdir)/uniquefileidentifierframe.cpp $(srcdir)/unknownframe.cpp
@echo 'creating libframes_la.all_cpp.cpp ...'; \
rm -f libframes_la.all_cpp.files libframes_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libframes_la.all_cpp.final; \
for file in attachedpictureframe.cpp commentsframe.cpp relativevolumeframe.cpp textidentificationframe.cpp uniquefileidentifierframe.cpp unknownframe.cpp ; do \
echo "#include \"$$file\"" >> libframes_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libframes_la.all_cpp.final; \
done; \
cat libframes_la.all_cpp.final libframes_la.all_cpp.files > libframes_la.all_cpp.cpp; \
rm -f libframes_la.all_cpp.final libframes_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libframes_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libframes_la_OBJECTS="$(libframes_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libframes_la_OBJECTS="$(libframes_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libframes_la_OBJECTS="$(libframes_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libframes_la_OBJECTS="$(libframes_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,165 @@
/***************************************************************************
copyright : (C) 2004 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 *
***************************************************************************/
#include <tdebug.h>
#include "attachedpictureframe.h"
using namespace TagLib;
using namespace ID3v2;
class AttachedPictureFrame::AttachedPictureFramePrivate
{
public:
AttachedPictureFramePrivate() : textEncoding(String::Latin1),
type(AttachedPictureFrame::Other) {}
String::Type textEncoding;
String mimeType;
AttachedPictureFrame::Type type;
String description;
ByteVector data;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
AttachedPictureFrame::AttachedPictureFrame() : Frame("APIC")
{
d = new AttachedPictureFramePrivate;
}
AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data) : Frame(data)
{
setData(data);
d = new AttachedPictureFramePrivate;
}
AttachedPictureFrame::~AttachedPictureFrame()
{
delete d;
}
String AttachedPictureFrame::toString() const
{
String s = "[" + d->mimeType + "]";
return d->description.isEmpty() ? s : d->description + " " + s;
}
String::Type AttachedPictureFrame::textEncoding() const
{
return d->textEncoding;
}
void AttachedPictureFrame::setTextEncoding(String::Type t)
{
d->textEncoding = t;
}
String AttachedPictureFrame::mimeType() const
{
return d->mimeType;
}
void AttachedPictureFrame::setMimeType(const String &m)
{
d->mimeType = m;
}
AttachedPictureFrame::Type AttachedPictureFrame::type() const
{
return d->type;
}
void AttachedPictureFrame::setType(Type t)
{
d->type = t;
}
ByteVector AttachedPictureFrame::picture() const
{
return d->data;
}
void AttachedPictureFrame::setPicture(const ByteVector &p)
{
d->data = p;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void AttachedPictureFrame::parseFields(const ByteVector &data)
{
if(data.size() < 5) {
debug("A picture frame must contain at least 5 bytes.");
return;
}
int pos = 0;
d->textEncoding = String::Type(data[pos]);
pos += 1;
int offset = data.find(textDelimiter(String::Latin1), pos);
if(offset < pos)
return;
d->mimeType = String(data.mid(pos, offset - pos), String::Latin1);
pos = offset + 1;
d->type = Type(data[pos]);
pos += 1;
offset = data.find(textDelimiter(d->textEncoding), pos);
if(offset < pos)
return;
d->description = String(data.mid(pos, offset - pos), d->textEncoding);
pos = offset + 1;
d->data = data.mid(pos);
}
ByteVector AttachedPictureFrame::renderFields() const
{
ByteVector data;
data.append(char(d->textEncoding));
data.append(d->mimeType.data(String::Latin1));
data.append(textDelimiter(String::Latin1));
data.append(char(d->type));
data.append(d->description.data(d->textEncoding));
data.append(textDelimiter(d->textEncoding));
data.append(d->data);
return data;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
AttachedPictureFrame::AttachedPictureFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new AttachedPictureFramePrivate;
parseFields(fieldData(data));
}

View file

@ -0,0 +1,195 @@
/***************************************************************************
copyright : (C) 2004 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 *
***************************************************************************/
#ifndef TAGLIB_ATTACHEDPICTUREFRAME_H
#define TAGLIB_ATTACHEDPICTUREFRAME_H
#include <id3v2frame.h>
#include <id3v2header.h>
namespace TagLib {
namespace ID3v2 {
//! An ID3v2 attached picture frame 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
* PNG format.
*/
class AttachedPictureFrame : public Frame
{
friend class FrameFactory;
public:
/*!
* This describes the function or content of the picture.
*/
enum Type {
//! A type not enumerated below
Other = 0x00,
//! 32x32 PNG image that should be used as the file icon
FileIcon = 0x01,
//! File icon of a different size or format
OtherFileIcon = 0x02,
//! Front cover image of the album
FrontCover = 0x03,
//! Back cover image of the album
BackCover = 0x04,
//! Inside leaflet page of the album
LeafletPage = 0x05,
//! Image from the album itself
Media = 0x06,
//! Picture of the lead artist or soloist
LeadArtist = 0x07,
//! Picture of the artist or performer
Artist = 0x08,
//! Picture of the conductor
Conductor = 0x09,
//! Picture of the band or orchestra
Band = 0x0A,
//! Picture of the composer
Composer = 0x0B,
//! Picture of the lyricist or text writer
Lyricist = 0x0C,
//! Picture of the recording location or studio
RecordingLocation = 0x0D,
//! Picture of the artists during recording
DuringRecording = 0x0E,
//! Picture of the artists during performance
DuringPerformance = 0x0F,
//! Picture from a movie or video related to the track
MovieScreenCapture = 0x10,
//! Picture of a large, coloured fish
ColouredFish = 0x11,
//! Illustration related to the track
Illustration = 0x12,
//! Logo of the band or performer
BandLogo = 0x13,
//! Logo of the publisher (record company)
PublisherLogo = 0x14
};
/*!
* Constructs an empty picture frame. The description, content and text
* encoding should be set manually.
*/
AttachedPictureFrame();
/*!
* Constructs an AttachedPicture frame based on \a data.
*/
explicit AttachedPictureFrame(const ByteVector &data);
/*!
* Destroys the AttahcedPictureFrame instance.
*/
virtual ~AttachedPictureFrame();
/*!
* Returns a string containing the description and mime-type
*/
virtual String toString() const;
/*!
* Returns the text encoding used for the description.
*
* \see setTextEncoding()
* \see description()
*/
String::Type textEncoding() 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
* "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 the type of the image.
*
* \see Type
* \see setType()
*/
Type type() const;
/*!
* Sets the type for the image.
*
* \see Type
* \see type()
*/
void setType(Type t);
/*!
* Returns the image data as a ByteVector.
*
* \note ByteVector has a data() method that returns a const char * which
* should make it easy to export this data to external programs.
*
* \see setPicture()
* \see mimeType()
*/
ByteVector picture() const;
/*!
* Sets the image data to \a p. \a p should be of the type specified in
* this frame's mime-type specification.
*
* \see picture()
* \see mimeType()
* \see setMimeType()
*/
void setPicture(const ByteVector &p);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
private:
AttachedPictureFrame(const ByteVector &data, Header *h);
AttachedPictureFrame(const AttachedPictureFrame &);
AttachedPictureFrame &operator=(const AttachedPictureFrame &);
class AttachedPictureFramePrivate;
AttachedPictureFramePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,152 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <tbytevectorlist.h>
#include <tdebug.h>
#include "commentsframe.h"
using namespace TagLib;
using namespace ID3v2;
class CommentsFrame::CommentsFramePrivate
{
public:
CommentsFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
ByteVector language;
String description;
String text;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
CommentsFrame::CommentsFrame(String::Type encoding) : Frame("COMM")
{
d = new CommentsFramePrivate;
d->textEncoding = encoding;
}
CommentsFrame::CommentsFrame(const ByteVector &data) : Frame(data)
{
d = new CommentsFramePrivate;
setData(data);
}
CommentsFrame::~CommentsFrame()
{
delete d;
}
String CommentsFrame::toString() const
{
return d->text;
}
ByteVector CommentsFrame::language() const
{
return d->language;
}
String CommentsFrame::description() const
{
return d->description;
}
String CommentsFrame::text() const
{
return d->text;
}
void CommentsFrame::setLanguage(const ByteVector &languageEncoding)
{
d->language = languageEncoding.mid(0, 3);
}
void CommentsFrame::setDescription(const String &s)
{
d->description = s;
}
void CommentsFrame::setText(const String &s)
{
d->text = s;
}
String::Type CommentsFrame::textEncoding() const
{
return d->textEncoding;
}
void CommentsFrame::setTextEncoding(String::Type encoding)
{
d->textEncoding = encoding;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void CommentsFrame::parseFields(const ByteVector &data)
{
if(data.size() < 5) {
debug("A comment frame must contain at least 5 bytes.");
return;
}
d->textEncoding = String::Type(data[0]);
d->language = data.mid(1, 3);
int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
ByteVectorList l = ByteVectorList::split(data.mid(4), textDelimiter(d->textEncoding), byteAlign);
if(l.size() == 2) {
d->description = String(l.front(), d->textEncoding);
d->text = String(l.back(), d->textEncoding);
}
}
ByteVector CommentsFrame::renderFields() const
{
ByteVector v;
v.append(char(d->textEncoding));
v.append(d->language.size() == 3 ? d->language : " ");
v.append(d->description.data(d->textEncoding));
v.append(textDelimiter(d->textEncoding));
v.append(d->text.data(d->textEncoding));
return v;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
CommentsFrame::CommentsFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new CommentsFramePrivate();
parseFields(fieldData(data));
}

View file

@ -0,0 +1,154 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_COMMENTSFRAME_H
#define TAGLIB_COMMENTSFRAME_H
#include <id3v2frame.h>
namespace TagLib {
namespace ID3v2 {
//! An implementation of ID3v2 comments
/*!
* This implements the ID3v2 comment format. An ID3v2 comment concists of
* a language encoding, a description and a single text field.
*/
class CommentsFrame : public Frame
{
friend class FrameFactory;
public:
/*!
* Construct an empty comment frame that will use the text encoding
* \a encoding.
*/
explicit CommentsFrame(String::Type encoding = String::Latin1);
/*!
* Construct a comment based on the data in \a data.
*/
explicit CommentsFrame(const ByteVector &data);
/*!
* Destroys this CommentFrame instance.
*/
virtual ~CommentsFrame();
/*!
* Returns the text of this comment.
*
* \see text()
*/
virtual String toString() const;
/*!
* Returns the language encoding as a 3 byte encoding as specified by
* <a href="http://en.wikipedia.org/wiki/ISO_639">ISO-639-2</a>.
*
* \note Most taggers simply ignore this value.
*
* \see setLanguage()
*/
ByteVector language() const;
/*!
* Returns the description of this comment.
*
* \note Most taggers simply ignore this value.
*
* \see setDescription()
*/
String description() const;
/*!
* Returns the text of this comment.
*
* \see setText()
*/
String text() const;
/*!
* Set the language using the 3 byte language code from
* <a href="http://en.wikipedia.org/wiki/ISO_639">ISO-639-2</a> to
* \a languageCode.
*
* \see language()
*/
void setLanguage(const ByteVector &languageCode);
/*!
* Sets the description of the comment to \a s.
*
* \see decription()
*/
void setDescription(const String &s);
/*!
* Sets the text portion of the comment to \a s.
*
* \see text()
*/
virtual void setText(const String &s);
/*!
* Returns the text encoding that will be used in rendering this frame.
* This defaults to the type that was either specified in the constructor
* or read from the frame when parsed.
*
* \see setTextEncoding()
* \see render()
*/
String::Type textEncoding() const;
/*!
* Sets the text encoding to be used when rendering this frame to
* \a encoding.
*
* \see textEncoding()
* \see render()
*/
void setTextEncoding(String::Type encoding);
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
private:
/*!
* The constructor used by the FrameFactory.
*/
CommentsFrame(const ByteVector &data, Header *h);
CommentsFrame(const CommentsFrame &);
CommentsFrame &operator=(const CommentsFrame &);
class CommentsFramePrivate;
CommentsFramePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,137 @@
/***************************************************************************
copyright : (C) 2004 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 *
***************************************************************************/
#include "relativevolumeframe.h"
using namespace TagLib;
using namespace ID3v2;
class RelativeVolumeFrame::RelativeVolumeFramePrivate
{
public:
RelativeVolumeFramePrivate() : channelType(Other), volumeAdjustment(0) {}
String identification;
ChannelType channelType;
short volumeAdjustment;
PeakVolume peakVolume;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
RelativeVolumeFrame::RelativeVolumeFrame(const ByteVector &data) : Frame(data)
{
d = new RelativeVolumeFramePrivate;
setData(data);
}
RelativeVolumeFrame::~RelativeVolumeFrame()
{
delete d;
}
String RelativeVolumeFrame::toString() const
{
return d->identification;
}
RelativeVolumeFrame::ChannelType RelativeVolumeFrame::channelType() const
{
return d->channelType;
}
void RelativeVolumeFrame::setChannelType(ChannelType t)
{
d->channelType = t;
}
short RelativeVolumeFrame::volumeAdjustmentIndex() const
{
return d->volumeAdjustment;
}
void RelativeVolumeFrame::setVolumeAdjustmentIndex(short index)
{
d->volumeAdjustment = index;
}
float RelativeVolumeFrame::volumeAdjustment() const
{
return float(d->volumeAdjustment) / float(512);
}
void RelativeVolumeFrame::setVolumeAdjustment(float adjustment)
{
d->volumeAdjustment = short(adjustment / float(512));
}
RelativeVolumeFrame::PeakVolume RelativeVolumeFrame::peakVolume() const
{
return d->peakVolume;
}
void RelativeVolumeFrame::setPeakVolume(const PeakVolume &peak)
{
d->peakVolume = peak;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void RelativeVolumeFrame::parseFields(const ByteVector &data)
{
int pos = data.find(textDelimiter(String::Latin1));
d->identification = String(data.mid(0, pos), String::Latin1);
d->volumeAdjustment = data.mid(pos, 2).toShort();
pos += 2;
d->peakVolume.bitsRepresentingPeak = data[pos];
pos += 1;
d->peakVolume.peakVolume = data.mid(pos, d->peakVolume.bitsRepresentingPeak);
}
ByteVector RelativeVolumeFrame::renderFields() const
{
ByteVector data;
data.append(d->identification.data(String::Latin1));
data.append(textDelimiter(String::Latin1));
data.append(ByteVector::fromShort(d->volumeAdjustment));
data.append(char(d->peakVolume.bitsRepresentingPeak));
data.append(d->peakVolume.peakVolume);
return data;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
RelativeVolumeFrame::RelativeVolumeFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new RelativeVolumeFramePrivate;
parseFields(fieldData(data));
}

View file

@ -0,0 +1,207 @@
/***************************************************************************
copyright : (C) 2004 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 *
***************************************************************************/
#ifndef TAGLIB_RELATIVEVOLUMEFRAME_H
#define TAGLIB_RELATIVEVOLUMEFRAME_H
#include <id3v2frame.h>
namespace TagLib {
namespace ID3v2 {
//! An ID3v2 relative volume adjustment frame implementation
/*!
* This is an implementation of ID3v2 relative volume adjustment. The
* presense of this frame makes it possible to specify an increase in volume
* for an audio file or specific audio tracks in that file.
*
* Multiple relative volume adjustment frames may be present in the tag
* each with a unique identification and describing volume adjustment for
* different channel types.
*/
class RelativeVolumeFrame : public Frame
{
friend class FrameFactory;
public:
/*!
* This indicates the type of volume adjustment that should be applied.
*/
enum ChannelType {
//! A type not enumerated below
Other = 0x00,
//! The master volume for the track
MasterVolume = 0x01,
//! The front right audio channel
FrontRight = 0x02,
//! The front left audio channel
FrontLeft = 0x03,
//! The back right audio channel
BackRight = 0x04,
//! The back left audio channel
BackLeft = 0x05,
//! The front center audio channel
FrontCentre = 0x06,
//! The back center audio channel
BackCentre = 0x07,
//! The subwoofer audio channel
Subwoofer = 0x08
};
//! Struct that stores the relevant values for ID3v2 peak volume
/*!
* The peak volume is described as a series of bits that is padded to fill
* a block of bytes. These two values should always be updated in tandem.
*/
struct PeakVolume
{
/*!
* Constructs an empty peak volume description.
*/
PeakVolume() : bitsRepresentingPeak(0) {}
/*!
* The number of bits (in the range of 0 to 255) used to describe the
* peak volume.
*/
unsigned char bitsRepresentingPeak;
/*!
* The array of bits (represented as a series of bytes) used to describe
* the peak volume.
*/
ByteVector peakVolume;
};
/*!
* Constructs a RelativeVolumeFrame. The relevant data should be set
* manually.
*/
RelativeVolumeFrame();
/*!
* Constructs a RelativeVolumeFrame based on the contents of \a data.
*/
RelativeVolumeFrame(const ByteVector &data);
/*!
* Destroys the RelativeVolumeFrame instance.
*/
virtual ~RelativeVolumeFrame();
/*!
* Returns the frame's identification.
*
* \see identification()
*/
virtual String toString() const;
/*!
* Returns the channel type that this frame refers to.
*
* \see setChannelType()
*/
ChannelType channelType() const;
/*!
* Sets the channel type that this frame refers to.
*
* \see channelType()
*/
void setChannelType(ChannelType t);
/*!
* Returns the relative volume adjustment "index". As indicated by the
* ID3v2 standard this is a 16-bit signed integer that reflects the
* decibils of adjustment when divided by 512.
*
* \see setVolumeAdjustmentIndex()
* \see volumeAjustment()
*/
short volumeAdjustmentIndex() const;
/*!
* Set the volume adjustment to \a index. As indicated by the ID3v2
* standard this is a 16-bit signed integer that reflects the decibils of
* adjustment when divided by 512.
*
* \see volumeAdjustmentIndex()
* \see setVolumeAjustment()
*/
void setVolumeAdjustmentIndex(short index);
/*!
* Returns the relative volume adjustment in decibels.
*
* \note Because this is actually stored internally as an "index" to this
* value the value returned by this method may not be identical to the
* value set using setVolumeAdjustment().
*
* \see setVolumeAdjustment()
* \see volumeAdjustmentIndex()
*/
float volumeAdjustment() const;
/*!
* Set the relative volume adjustment in decibels to \a adjustment.
*
* \note Because this is actually stored internally as an "index" to this
* value the value set by this method may not be identical to the one
* returned by volumeAdjustment().
*
* \see setVolumeAdjustment()
* \see volumeAdjustmentIndex()
*/
void setVolumeAdjustment(float adjustment);
/*!
* Returns the peak volume (represented as a length and a string of bits).
*
* \see setPeakVolume()
*/
PeakVolume peakVolume() const;
/*!
* Sets the peak volume to \a peak.
*
* \see peakVolume()
*/
void setPeakVolume(const PeakVolume &peak);
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
private:
RelativeVolumeFrame(const ByteVector &data, Header *h);
RelativeVolumeFrame(const RelativeVolumeFrame &);
RelativeVolumeFrame &operator=(const RelativeVolumeFrame &);
class RelativeVolumeFramePrivate;
RelativeVolumeFramePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,245 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <tbytevectorlist.h>
#include <id3v2tag.h>
#include "textidentificationframe.h"
using namespace TagLib;
using namespace ID3v2;
class TextIdentificationFrame::TextIdentificationFramePrivate
{
public:
TextIdentificationFramePrivate() : textEncoding(String::Latin1) {}
String::Type textEncoding;
StringList fieldList;
};
////////////////////////////////////////////////////////////////////////////////
// TextIdentificationFrame public members
////////////////////////////////////////////////////////////////////////////////
TextIdentificationFrame::TextIdentificationFrame(const ByteVector &type, String::Type encoding) :
Frame(type)
{
d = new TextIdentificationFramePrivate;
d->textEncoding = encoding;
}
TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data) :
Frame(data)
{
d = new TextIdentificationFramePrivate;
setData(data);
}
TextIdentificationFrame::~TextIdentificationFrame()
{
delete d;
}
void TextIdentificationFrame::setText(const StringList &l)
{
d->fieldList = l;
}
void TextIdentificationFrame::setText(const String &s)
{
d->fieldList = s;
}
String TextIdentificationFrame::toString() const
{
return d->fieldList.toString();
}
StringList TextIdentificationFrame::fieldList() const
{
return d->fieldList;
}
String::Type TextIdentificationFrame::textEncoding() const
{
return d->textEncoding;
}
void TextIdentificationFrame::setTextEncoding(String::Type encoding)
{
d->textEncoding = encoding;
}
////////////////////////////////////////////////////////////////////////////////
// TextIdentificationFrame protected members
////////////////////////////////////////////////////////////////////////////////
void TextIdentificationFrame::parseFields(const ByteVector &data)
{
// read the string data type (the first byte of the field data)
d->textEncoding = String::Type(data[0]);
// split the byte array into chunks based on the string type (two byte delimiter
// for unicode encodings)
int byteAlign = d->textEncoding == String::Latin1 || d->textEncoding == String::UTF8 ? 1 : 2;
ByteVectorList l = ByteVectorList::split(data.mid(1), textDelimiter(d->textEncoding), byteAlign);
d->fieldList.clear();
// append those split values to the list and make sure that the new string's
// type is the same specified for this frame
for(ByteVectorList::Iterator it = l.begin(); it != l.end(); it++) {
String s(*it, d->textEncoding);
d->fieldList.append(s);
}
}
ByteVector TextIdentificationFrame::renderFields() const
{
ByteVector v;
if(d->fieldList.size() > 0) {
v.append(char(d->textEncoding));
for(StringList::Iterator it = d->fieldList.begin(); it != d->fieldList.end(); it++) {
// Since the field list is null delimited, if this is not the first
// element in the list, append the appropriate delimiter for this
// encoding.
if(it != d->fieldList.begin())
v.append(textDelimiter(d->textEncoding));
v.append((*it).data(d->textEncoding));
}
}
return v;
}
////////////////////////////////////////////////////////////////////////////////
// TextIdentificationFrame private members
////////////////////////////////////////////////////////////////////////////////
TextIdentificationFrame::TextIdentificationFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new TextIdentificationFramePrivate;
parseFields(fieldData(data));
}
////////////////////////////////////////////////////////////////////////////////
// UserTextIdentificationFrame public members
////////////////////////////////////////////////////////////////////////////////
UserTextIdentificationFrame::UserTextIdentificationFrame(String::Type encoding) :
TextIdentificationFrame("TXXX", encoding),
d(0)
{
StringList l;
l.append(String::null);
l.append(String::null);
setText(l);
}
UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data) :
TextIdentificationFrame(data)
{
}
String UserTextIdentificationFrame::toString() const
{
return "[" + description() + "] " + fieldList().toString();
}
String UserTextIdentificationFrame::description() const
{
return !TextIdentificationFrame::fieldList().isEmpty()
? TextIdentificationFrame::fieldList().front()
: String::null;
}
StringList UserTextIdentificationFrame::fieldList() const
{
StringList l = TextIdentificationFrame::fieldList();
if(!l.isEmpty()) {
StringList::Iterator it = l.begin();
l.erase(it);
}
return l;
}
void UserTextIdentificationFrame::setText(const String &text)
{
if(description().isEmpty())
setDescription(String::null);
TextIdentificationFrame::setText(StringList(description()).append(text));
}
void UserTextIdentificationFrame::setText(const StringList &fields)
{
if(description().isEmpty())
setDescription(String::null);
TextIdentificationFrame::setText(StringList(description()).append(fields));
}
void UserTextIdentificationFrame::setDescription(const String &s)
{
StringList l = fieldList();
if(l.isEmpty())
l.append(s);
else
l[0] = s;
TextIdentificationFrame::setText(l);
}
UserTextIdentificationFrame *find(ID3v2::Tag *tag, const String &description) // static
{
FrameList l = tag->frameList("TXXX");
for(FrameList::Iterator it = l.begin(); it != l.end(); ++it) {
UserTextIdentificationFrame *f = dynamic_cast<UserTextIdentificationFrame *>(*it);
if(f && f->description() == description)
return f;
}
return 0;
}
////////////////////////////////////////////////////////////////////////////////
// UserTextIdentificationFrame private members
////////////////////////////////////////////////////////////////////////////////
UserTextIdentificationFrame::UserTextIdentificationFrame(const ByteVector &data, Header *h) :
TextIdentificationFrame(data, h)
{
}

View file

@ -0,0 +1,241 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_TEXTIDENTIFICATIONFRAME_H
#define TAGLIB_TEXTIDENTIFICATIONFRAME_H
#include <tstringlist.h>
#include <id3v2frame.h>
namespace TagLib {
namespace ID3v2 {
class Tag;
//! An ID3v2 text identification frame implementation
/*!
* This is an implementation of the most common type of ID3v2 frame -- text
* identification frames. There are a number of variations on this. Those
* enumerated in the ID3v2.4 standard are:
*
* <ul>
* <li><b>TALB</b> Album/Movie/Show title</li>
* <li><b>TBPM</b> BPM (beats per minute)</li>
* <li><b>TCOM</b> Composer</li>
* <li><b>TCON</b> Content type</li>
* <li><b>TCOP</b> Copyright message</li>
* <li><b>TDEN</b> Encoding time</li>
* <li><b>TDLY</b> Playlist delay</li>
* <li><b>TDOR</b> Original release time</li>
* <li><b>TDRC</b> Recording time</li>
* <li><b>TDRL</b> Release time</li>
* <li><b>TDTG</b> Tagging time</li>
* <li><b>TENC</b> Encoded by</li>
* <li><b>TEXT</b> Lyricist/Text writer</li>
* <li><b>TFLT</b> File type</li>
* <li><b>TIPL</b> Involved people list</li>
* <li><b>TIT1</b> Content group description</li>
* <li><b>TIT2</b> Title/songname/content description</li>
* <li><b>TIT3</b> Subtitle/Description refinement</li>
* <li><b>TKEY</b> Initial key</li>
* <li><b>TLAN</b> Language(s)</li>
* <li><b>TLEN</b> Length</li>
* <li><b>TMCL</b> Musician credits list</li>
* <li><b>TMED</b> Media type</li>
* <li><b>TMOO</b> Mood</li>
* <li><b>TOAL</b> Original album/movie/show title</li>
* <li><b>TOFN</b> Original filename</li>
* <li><b>TOLY</b> Original lyricist(s)/text writer(s)</li>
* <li><b>TOPE</b> Original artist(s)/performer(s)</li>
* <li><b>TOWN</b> File owner/licensee</li>
* <li><b>TPE1</b> Lead performer(s)/Soloist(s)</li>
* <li><b>TPE2</b> Band/orchestra/accompaniment</li>
* <li><b>TPE3</b> Conductor/performer refinement</li>
* <li><b>TPE4</b> Interpreted, remixed, or otherwise modified by</li>
* <li><b>TPOS</b> Part of a set</li>
* <li><b>TPRO</b> Produced notice</li>
* <li><b>TPUB</b> Publisher</li>
* <li><b>TRCK</b> Track number/Position in set</li>
* <li><b>TRSN</b> Internet radio station name</li>
* <li><b>TRSO</b> Internet radio station owner</li>
* <li><b>TSOA</b> Album sort order</li>
* <li><b>TSOP</b> Performer sort order</li>
* <li><b>TSOT</b> Title sort order</li>
* <li><b>TSRC</b> ISRC (international standard recording code)</li>
* <li><b>TSSE</b> Software/Hardware and settings used for encoding</li>
* <li><b>TSST</b> Set subtitle</li>
* </ul>
*
* The ID3v2 Frames document gives a description of each of these formats
* and the expected order of strings in each. ID3v2::Header::frameID() can
* be used to determine the frame type.
*/
class TextIdentificationFrame : public Frame
{
friend class FrameFactory;
public:
/*!
* Construct an empty frame of type \a type. Uses \a encoding as the
* default text encoding.
*
* \note In this case you must specify the text encoding as it
* resolves the ambiguity between constructors.
*/
TextIdentificationFrame(const ByteVector &type, String::Type encoding);
/*!
* This is a dual purpose constructor. \a data can either be binary data
* that should be parsed or (at a minimum) the frame ID.
*/
explicit TextIdentificationFrame(const ByteVector &data);
/*!
* Destroys this TextIdentificationFrame instance.
*/
virtual ~TextIdentificationFrame();
/*!
* Text identification frames are a list of string fields.
*
* This function will accept either a StringList or a String (using the
* StringList constructor that accepts a single String).
*
* \note This will not change the text encoding of the frame even if the
* strings passed in are not of the same encoding. Please use
* setEncoding(s.type()) if you wish to change the encoding of the frame.
*/
void setText(const StringList &l);
// Reimplementations.
virtual void setText(const String &s);
virtual String toString() const;
/*!
* Returns the text encoding that will be used in rendering this frame.
* This defaults to the type that was either specified in the constructor
* or read from the frame when parsed.
*
* \see setTextEncoding()
* \see render()
*/
String::Type textEncoding() const;
/*!
* Sets the text encoding to be used when rendering this frame to
* \a encoding.
*
* \see textEncoding()
* \see render()
*/
void setTextEncoding(String::Type encoding);
/*!
* Returns a list of the strings in this frame.
*/
StringList fieldList() const;
protected:
// Reimplementations.
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
/*!
* The constructor used by the FrameFactory.
*/
TextIdentificationFrame(const ByteVector &data, Header *h);
private:
TextIdentificationFrame(const TextIdentificationFrame &);
TextIdentificationFrame &operator=(const TextIdentificationFrame &);
class TextIdentificationFramePrivate;
TextIdentificationFramePrivate *d;
};
/*!
* This is a specialization of text identification frames that allows for
* user defined entries. Each entry has a description in addition to the
* normal list of fields that a text identification frame has.
*
* This description identifies the frame and must be unique.
*/
//! An ID3v2 custom text identification frame implementationx
class UserTextIdentificationFrame : public TextIdentificationFrame
{
friend class FrameFactory;
public:
/*!
* Constructs an empty user defined text identification frame. For this to be
* a useful frame both a description and text must be set.
*/
explicit UserTextIdentificationFrame(String::Type encoding = String::Latin1);
/*!
* Creates a frame based on \a data.
*/
explicit UserTextIdentificationFrame(const ByteVector &data);
virtual String toString() const;
/*!
* Returns the description for this frame.
*/
String description() const;
/*!
* Sets the description of the frame to \a s. \a s must be unique. You can
* check for the presense of another user defined text frame of the same type
* using find() and testing for null.
*/
void setDescription(const String &s);
StringList fieldList() const;
void setText(const String &text);
void setText(const StringList &fields);
/*!
* Searches for the user defined text frame with the description \a description
* in \a tag. This returns null if no matching frames were found.
*/
static UserTextIdentificationFrame *find(Tag *tag, const String &description);
private:
UserTextIdentificationFrame(const ByteVector &data, Header *h);
UserTextIdentificationFrame(const TextIdentificationFrame &);
UserTextIdentificationFrame &operator=(const UserTextIdentificationFrame &);
class UserTextIdentificationFramePrivate;
UserTextIdentificationFramePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,107 @@
/***************************************************************************
copyright : (C) 2004 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 *
***************************************************************************/
#include <tbytevectorlist.h>
#include "uniquefileidentifierframe.h"
using namespace TagLib;
using namespace ID3v2;
class UniqueFileIdentifierFrame::UniqueFileIdentifierFramePrivate
{
public:
String owner;
ByteVector identifier;
};
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
UniqueFileIdentifierFrame::UniqueFileIdentifierFrame(const ByteVector &data) :
ID3v2::Frame(data)
{
d = new UniqueFileIdentifierFramePrivate;
setData(data);
}
UniqueFileIdentifierFrame::UniqueFileIdentifierFrame(const String &owner, const ByteVector &id) :
ID3v2::Frame("UFID")
{
d = new UniqueFileIdentifierFramePrivate;
d->owner = owner;
d->identifier = id;
}
String UniqueFileIdentifierFrame::owner() const
{
return d->owner;
}
ByteVector UniqueFileIdentifierFrame::identifier() const
{
return d->identifier;
}
void UniqueFileIdentifierFrame::setOwner(const String &s)
{
d->owner = s;
}
void UniqueFileIdentifierFrame::setIdentifier(const ByteVector &v)
{
d->identifier = v;
}
String UniqueFileIdentifierFrame::toString() const
{
return String::null;
}
void UniqueFileIdentifierFrame::parseFields(const ByteVector &data)
{
ByteVectorList fields = ByteVectorList::split(data, char(0));
if(fields.size() != 2)
return;
d->owner = fields.front();
d->identifier = fields.back();
}
ByteVector UniqueFileIdentifierFrame::renderFields() const
{
ByteVector data;
data.append(d->owner.data(String::Latin1));
data.append(char(0));
data.append(d->identifier);
return data;
}
UniqueFileIdentifierFrame::UniqueFileIdentifierFrame(const ByteVector &data, Header *h) :
Frame(h)
{
d = new UniqueFileIdentifierFramePrivate;
parseFields(fieldData(data));
}

View file

@ -0,0 +1,101 @@
/***************************************************************************
copyright : (C) 2004 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 *
***************************************************************************/
#ifndef TAGLIB_UNIQUEFILEIDENTIFIERFRAME
#define TAGLIB_UNIQUEFILEIDENTIFIERFRAME
#include <id3v2frame.h>
namespace TagLib {
namespace ID3v2 {
/*!
* This is an implementation of ID3v2 unique file identifier frames. This
* frame is used to identify the file in an arbitrary database identified
* by the owner field.
*/
//! An implementation of ID3v2 unique identifier frames
class UniqueFileIdentifierFrame : public ID3v2::Frame
{
friend class FrameFactory;
public:
/*!
* Creates a uniqe file identifier frame based on \a data.
*/
UniqueFileIdentifierFrame(const ByteVector &data);
/*!
* Creates a unique file identifier frame with the owner \a owner and
* the identification \a id.
*/
UniqueFileIdentifierFrame(const String &owner, const ByteVector &id);
/*!
* Returns the owner for the frame; essentially this is the key for
* determining which identification scheme this key belongs to. This
* will usually either be an email address or URL for the person or tool
* used to create the unique identifier.
*
* \see setOwner()
*/
String owner() const;
/*!
* Returns the unique identifier. Though sometimes this is a text string
* it also may be binary data and as much should be assumed when handling
* it.
*/
ByteVector identifier() const;
/*!
* Sets the owner of the identification scheme to \a s.
*
* \see owner()
*/
void setOwner(const String &s);
/*!
* Sets the unique file identifier to \a v.
*
* \see identifier()
*/
void setIdentifier(const ByteVector &v);
virtual String toString() const;
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
private:
UniqueFileIdentifierFrame(const ByteVector &data, Header *h);
class UniqueFileIdentifierFramePrivate;
UniqueFileIdentifierFramePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,80 @@
/***************************************************************************
copyright : (C) 2002 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 *
***************************************************************************/
#include "unknownframe.h"
using namespace TagLib;
using namespace ID3v2;
class UnknownFrame::UnknownFramePrivate
{
public:
ByteVector fieldData;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
UnknownFrame::UnknownFrame(const ByteVector &data) : Frame(data)
{
d = new UnknownFramePrivate;
setData(data);
}
UnknownFrame::~UnknownFrame()
{
delete d;
}
String UnknownFrame::toString() const
{
return String::null;
}
ByteVector UnknownFrame::data() const
{
return d->fieldData;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void UnknownFrame::parseFields(const ByteVector &data)
{
d->fieldData = data;
}
ByteVector UnknownFrame::renderFields() const
{
return d->fieldData;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
UnknownFrame::UnknownFrame(const ByteVector &data, Header *h) : Frame(h)
{
d = new UnknownFramePrivate;
parseFields(fieldData(data));
}

View file

@ -0,0 +1,74 @@
/***************************************************************************
copyright : (C) 2002 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 *
***************************************************************************/
#ifndef TAGLIB_UNKNOWNFRAME_H
#define TAGLIB_UNKNOWNFRAME_H
#include <id3v2frame.h>
namespace TagLib {
namespace ID3v2 {
//! A frame type \e unknown to TagLib.
/*!
* This class represents a frame type not known (or more often simply
* unimplemented) in TagLib. This is here provide a basic API for
* manipulating the binary data of unknown frames and to provide a means
* of rendering such \e unknown frames.
*
* Please note that a cleaner way of handling frame types that TagLib
* does not understand is to subclass ID3v2::Frame and ID3v2::FrameFactory
* to have your frame type supported through the standard ID3v2 mechanism.
*/
class UnknownFrame : public Frame
{
friend class FrameFactory;
public:
UnknownFrame(const ByteVector &data);
virtual ~UnknownFrame();
virtual String toString() const;
/*!
* Returns the field data (everything but the header) for this frame.
*/
ByteVector data() const;
protected:
virtual void parseFields(const ByteVector &data);
virtual ByteVector renderFields() const;
private:
UnknownFrame(const ByteVector &data, Header *h);
UnknownFrame(const UnknownFrame &);
UnknownFrame &operator=(const UnknownFrame &);
class UnknownFramePrivate;
UnknownFramePrivate *d;
};
}
}
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,733 @@
Informal standard M. Nilsson
Document: id3v2.4.0-structure.txt 16 September 2001
ID3 tag version 2.4.0 - Main Structure
Status of this document
This document is an informal standard and replaces the ID3v2.3.0
standard [ID3v2]. A formal standard will use another revision number
even if the content is identical to document. The contents in this
document may change for clarifications but never for added or altered
functionallity.
Distribution of this document is unlimited.
Abstract
This document describes the main structure of ID3v2.4.0, which is a
revised version of the ID3v2 informal standard [ID3v2] version
2.3.0. The ID3v2 offers a flexible way of storing audio meta
information within the audio file itself. The information may be
technical information, such as equalisation curves, as well as
title, performer, copyright etc.
ID3v2.4.0 is meant to be as close as possible to ID3v2.3.0 in order
to allow for implementations to be revised as easily as possible.
1. Table of contents
Status of this document
Abstract
1. Table of contents
2. Conventions in this document
2. Standard overview
3. ID3v2 overview
3.1. ID3v2 header
3.2. ID3v2 extended header
3.3. Padding
3.4. ID3v2 footer
4. ID3v2 frames overview
4.1. Frame header flags
4.1.1. Frame status flags
4.1.2. Frame format flags
5. Tag location
6. Unsynchronisation
6.1. The unsynchronisation scheme
6.2. Synchsafe integers
7. Copyright
8. References
9. Author's Address
2. Conventions in this document
Text within "" is a text string exactly as it appears in a tag.
Numbers preceded with $ are hexadecimal and numbers preceded with %
are binary. $xx is used to indicate a byte with unknown content. %x
is used to indicate a bit with unknown content. The most significant
bit (MSB) of a byte is called 'bit 7' and the least significant bit
(LSB) is called 'bit 0'.
A tag is the whole tag described in this document. A frame is a block
of information in the tag. The tag consists of a header, frames and
optional padding. A field is a piece of information; one value, a
string etc. A numeric string is a string that consists of the
characters "0123456789" only.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
document are to be interpreted as described in RFC 2119 [KEYWORDS].
3. ID3v2 overview
ID3v2 is a general tagging format for audio, which makes it possible
to store meta data about the audio inside the audio file itself. The
ID3 tag described in this document is mainly targeted at files
encoded with MPEG-1/2 layer I, MPEG-1/2 layer II, MPEG-1/2 layer III
and MPEG-2.5, but may work with other types of encoded audio or as a
stand alone format for audio meta data.
ID3v2 is designed to be as flexible and expandable as possible to
meet new meta information needs that might arise. To achieve that
ID3v2 is constructed as a container for several information blocks,
called frames, whose format need not be known to the software that
encounters them. At the start of every frame is an unique and
predefined identifier, a size descriptor that allows software to skip
unknown frames and a flags field. The flags describes encoding
details and if the frame should remain in the tag, should it be
unknown to the software, if the file is altered.
The bitorder in ID3v2 is most significant bit first (MSB). The
byteorder in multibyte numbers is most significant byte first (e.g.
$12345678 would be encoded $12 34 56 78), also known as big endian
and network byte order.
Overall tag structure:
+-----------------------------+
| Header (10 bytes) |
+-----------------------------+
| Extended Header |
| (variable length, OPTIONAL) |
+-----------------------------+
| Frames (variable length) |
+-----------------------------+
| Padding |
| (variable length, OPTIONAL) |
+-----------------------------+
| Footer (10 bytes, OPTIONAL) |
+-----------------------------+
In general, padding and footer are mutually exclusive. See details in
sections 3.3, 3.4 and 5.
3.1. ID3v2 header
The first part of the ID3v2 tag is the 10 byte tag header, laid out
as follows:
ID3v2/file identifier "ID3"
ID3v2 version $04 00
ID3v2 flags %abcd0000
ID3v2 size 4 * %0xxxxxxx
The first three bytes of the tag are always "ID3", to indicate that
this is an ID3v2 tag, directly followed by the two version bytes. The
first byte of ID3v2 version is its major version, while the second
byte is its revision number. In this case this is ID3v2.4.0. All
revisions are backwards compatible while major versions are not. If
software with ID3v2.4.0 and below support should encounter version
five or higher it should simply ignore the whole tag. Version or
revision will never be $FF.
The version is followed by the ID3v2 flags field, of which currently
four flags are used.
a - Unsynchronisation
Bit 7 in the 'ID3v2 flags' indicates whether or not
unsynchronisation is applied on all frames (see section 6.1 for
details); a set bit indicates usage.
b - Extended header
The second bit (bit 6) indicates whether or not the header is
followed by an extended header. The extended header is described in
section 3.2. A set bit indicates the presence of an extended
header.
c - Experimental indicator
The third bit (bit 5) is used as an 'experimental indicator'. This
flag SHALL always be set when the tag is in an experimental stage.
d - Footer present
Bit 4 indicates that a footer (section 3.4) is present at the very
end of the tag. A set bit indicates the presence of a footer.
All the other flags MUST be cleared. If one of these undefined flags
are set, the tag might not be readable for a parser that does not
know the flags function.
The ID3v2 tag size is stored as a 32 bit synchsafe integer (section
6.2), making a total of 28 effective bits (representing up to 256MB).
The ID3v2 tag size is the sum of the byte length of the extended
header, the padding and the frames after unsynchronisation. If a
footer is present this equals to ('total size' - 20) bytes, otherwise
('total size' - 10) bytes.
An ID3v2 tag can be detected with the following pattern:
$49 44 33 yy yy xx zz zz zz zz
Where yy is less than $FF, xx is the 'flags' byte and zz is less than
$80.
3.2. Extended header
The extended header contains information that can provide further
insight in the structure of the tag, but is not vital to the correct
parsing of the tag information; hence the extended header is
optional.
Extended header size 4 * %0xxxxxxx
Number of flag bytes $01
Extended Flags $xx
Where the 'Extended header size' is the size of the whole extended
header, stored as a 32 bit synchsafe integer. An extended header can
thus never have a size of fewer than six bytes.
The extended flags field, with its size described by 'number of flag
bytes', is defined as:
%0bcd0000
Each flag that is set in the extended header has data attached, which
comes in the order in which the flags are encountered (i.e. the data
for flag 'b' comes before the data for flag 'c'). Unset flags cannot
have any attached data. All unknown flags MUST be unset and their
corresponding data removed when a tag is modified.
Every set flag's data starts with a length byte, which contains a
value between 0 and 127 ($00 - $7f), followed by data that has the
field length indicated by the length byte. If a flag has no attached
data, the value $00 is used as length byte.
b - Tag is an update
If this flag is set, the present tag is an update of a tag found
earlier in the present file or stream. If frames defined as unique
are found in the present tag, they are to override any
corresponding ones found in the earlier tag. This flag has no
corresponding data.
Flag data length $00
c - CRC data present
If this flag is set, a CRC-32 [ISO-3309] data is included in the
extended header. The CRC is calculated on all the data between the
header and footer as indicated by the header's tag length field,
minus the extended header. Note that this includes the padding (if
there is any), but excludes the footer. The CRC-32 is stored as an
35 bit synchsafe integer, leaving the upper four bits always
zeroed.
Flag data length $05
Total frame CRC 5 * %0xxxxxxx
d - Tag restrictions
For some applications it might be desired to restrict a tag in more
ways than imposed by the ID3v2 specification. Note that the
presence of these restrictions does not affect how the tag is
decoded, merely how it was restricted before encoding. If this flag
is set the tag is restricted as follows:
Flag data length $01
Restrictions %ppqrrstt
p - Tag size restrictions
00 No more than 128 frames and 1 MB total tag size.
01 No more than 64 frames and 128 KB total tag size.
10 No more than 32 frames and 40 KB total tag size.
11 No more than 32 frames and 4 KB total tag size.
q - Text encoding restrictions
0 No restrictions
1 Strings are only encoded with ISO-8859-1 [ISO-8859-1] or
UTF-8 [UTF-8].
r - Text fields size restrictions
00 No restrictions
01 No string is longer than 1024 characters.
10 No string is longer than 128 characters.
11 No string is longer than 30 characters.
Note that nothing is said about how many bytes is used to
represent those characters, since it is encoding dependent. If a
text frame consists of more than one string, the sum of the
strungs is restricted as stated.
s - Image encoding restrictions
0 No restrictions
1 Images are encoded only with PNG [PNG] or JPEG [JFIF].
t - Image size restrictions
00 No restrictions
01 All images are 256x256 pixels or smaller.
10 All images are 64x64 pixels or smaller.
11 All images are exactly 64x64 pixels, unless required
otherwise.
3.3. Padding
It is OPTIONAL to include padding after the final frame (at the end
of the ID3 tag), making the size of all the frames together smaller
than the size given in the tag header. A possible purpose of this
padding is to allow for adding a few additional frames or enlarge
existing frames within the tag without having to rewrite the entire
file. The value of the padding bytes must be $00. A tag MUST NOT have
any padding between the frames or between the tag header and the
frames. Furthermore it MUST NOT have any padding when a tag footer is
added to the tag.
3.4. ID3v2 footer
To speed up the process of locating an ID3v2 tag when searching from
the end of a file, a footer can be added to the tag. It is REQUIRED
to add a footer to an appended tag, i.e. a tag located after all
audio data. The footer is a copy of the header, but with a different
identifier.
ID3v2 identifier "3DI"
ID3v2 version $04 00
ID3v2 flags %abcd0000
ID3v2 size 4 * %0xxxxxxx
4. ID3v2 frame overview
All ID3v2 frames consists of one frame header followed by one or more
fields containing the actual information. The header is always 10
bytes and laid out as follows:
Frame ID $xx xx xx xx (four characters)
Size 4 * %0xxxxxxx
Flags $xx xx
The frame ID is made out of the characters capital A-Z and 0-9.
Identifiers beginning with "X", "Y" and "Z" are for experimental
frames and free for everyone to use, without the need to set the
experimental bit in the tag header. Bear in mind that someone else
might have used the same identifier as you. All other identifiers are
either used or reserved for future use.
The frame ID is followed by a size descriptor containing the size of
the data in the final frame, after encryption, compression and
unsynchronisation. The size is excluding the frame header ('total
frame size' - 10 bytes) and stored as a 32 bit synchsafe integer.
In the frame header the size descriptor is followed by two flag
bytes. These flags are described in section 4.1.
There is no fixed order of the frames' appearance in the tag,
although it is desired that the frames are arranged in order of
significance concerning the recognition of the file. An example of
such order: UFID, TIT2, MCDI, TRCK ...
A tag MUST contain at least one frame. A frame must be at least 1
byte big, excluding the header.
If nothing else is said, strings, including numeric strings and URLs
[URL], are represented as ISO-8859-1 [ISO-8859-1] characters in the
range $20 - $FF. Such strings are represented in frame descriptions
as <text string>, or <full text string> if newlines are allowed. If
nothing else is said newline character is forbidden. In ISO-8859-1 a
newline is represented, when allowed, with $0A only.
Frames that allow different types of text encoding contains a text
encoding description byte. Possible encodings:
$00 ISO-8859-1 [ISO-8859-1]. Terminated with $00.
$01 UTF-16 [UTF-16] encoded Unicode [UNICODE] with BOM. All
strings in the same frame SHALL have the same byteorder.
Terminated with $00 00.
$02 UTF-16BE [UTF-16] encoded Unicode [UNICODE] without BOM.
Terminated with $00 00.
$03 UTF-8 [UTF-8] encoded Unicode [UNICODE]. Terminated with $00.
Strings dependent on encoding are represented in frame descriptions
as <text string according to encoding>, or <full text string
according to encoding> if newlines are allowed. Any empty strings of
type $01 which are NULL-terminated may have the Unicode BOM followed
by a Unicode NULL ($FF FE 00 00 or $FE FF 00 00).
The timestamp fields are based on a subset of ISO 8601. When being as
precise as possible the format of a time string is
yyyy-MM-ddTHH:mm:ss (year, "-", month, "-", day, "T", hour (out of
24), ":", minutes, ":", seconds), but the precision may be reduced by
removing as many time indicators as wanted. Hence valid timestamps
are
yyyy, yyyy-MM, yyyy-MM-dd, yyyy-MM-ddTHH, yyyy-MM-ddTHH:mm and
yyyy-MM-ddTHH:mm:ss. All time stamps are UTC. For durations, use
the slash character as described in 8601, and for multiple non-
contiguous dates, use multiple strings, if allowed by the frame
definition.
The three byte language field, present in several frames, is used to
describe the language of the frame's content, according to ISO-639-2
[ISO-639-2]. The language should be represented in lower case. If the
language is not known the string "XXX" should be used.
All URLs [URL] MAY be relative, e.g. "picture.png", "../doc.txt".
If a frame is longer than it should be, e.g. having more fields than
specified in this document, that indicates that additions to the
frame have been made in a later version of the ID3v2 standard. This
is reflected by the revision number in the header of the tag.
4.1. Frame header flags
In the frame header the size descriptor is followed by two flag
bytes. All unused flags MUST be cleared. The first byte is for
'status messages' and the second byte is a format description. If an
unknown flag is set in the first byte the frame MUST NOT be changed
without that bit cleared. If an unknown flag is set in the second
byte the frame is likely to not be readable. Some flags in the second
byte indicates that extra information is added to the header. These
fields of extra information is ordered as the flags that indicates
them. The flags field is defined as follows (l and o left out because
ther resemblence to one and zero):
%0abc0000 %0h00kmnp
Some frame format flags indicate that additional information fields
are added to the frame. This information is added after the frame
header and before the frame data in the same order as the flags that
indicates them. I.e. the four bytes of decompressed size will precede
the encryption method byte. These additions affects the 'frame size'
field, but are not subject to encryption or compression.
The default status flags setting for a frame is, unless stated
otherwise, 'preserved if tag is altered' and 'preserved if file is
altered', i.e. %00000000.
4.1.1. Frame status flags
a - Tag alter preservation
This flag tells the tag parser what to do with this frame if it is
unknown and the tag is altered in any way. This applies to all
kinds of alterations, including adding more padding and reordering
the frames.
0 Frame should be preserved.
1 Frame should be discarded.
b - File alter preservation
This flag tells the tag parser what to do with this frame if it is
unknown and the file, excluding the tag, is altered. This does not
apply when the audio is completely replaced with other audio data.
0 Frame should be preserved.
1 Frame should be discarded.
c - Read only
This flag, if set, tells the software that the contents of this
frame are intended to be read only. Changing the contents might
break something, e.g. a signature. If the contents are changed,
without knowledge of why the frame was flagged read only and
without taking the proper means to compensate, e.g. recalculating
the signature, the bit MUST be cleared.
4.1.2. Frame format flags
h - Grouping identity
This flag indicates whether or not this frame belongs in a group
with other frames. If set, a group identifier byte is added to the
frame. Every frame with the same group identifier belongs to the
same group.
0 Frame does not contain group information
1 Frame contains group information
k - Compression
This flag indicates whether or not the frame is compressed.
A 'Data Length Indicator' byte MUST be included in the frame.
0 Frame is not compressed.
1 Frame is compressed using zlib [zlib] deflate method.
If set, this requires the 'Data Length Indicator' bit
to be set as well.
m - Encryption
This flag indicates whether or not the frame is encrypted. If set,
one byte indicating with which method it was encrypted will be
added to the frame. See description of the ENCR frame for more
information about encryption method registration. Encryption
should be done after compression. Whether or not setting this flag
requires the presence of a 'Data Length Indicator' depends on the
specific algorithm used.
0 Frame is not encrypted.
1 Frame is encrypted.
n - Unsynchronisation
This flag indicates whether or not unsynchronisation was applied
to this frame. See section 6 for details on unsynchronisation.
If this flag is set all data from the end of this header to the
end of this frame has been unsynchronised. Although desirable, the
presence of a 'Data Length Indicator' is not made mandatory by
unsynchronisation.
0 Frame has not been unsynchronised.
1 Frame has been unsyrchronised.
p - Data length indicator
This flag indicates that a data length indicator has been added to
the frame. The data length indicator is the value one would write
as the 'Frame length' if all of the frame format flags were
zeroed, represented as a 32 bit synchsafe integer.
0 There is no Data Length Indicator.
1 A data length Indicator has been added to the frame.
5. Tag location
The default location of an ID3v2 tag is prepended to the audio so
that players can benefit from the information when the data is
streamed. It is however possible to append the tag, or make a
prepend/append combination. When deciding upon where an unembedded
tag should be located, the following order of preference SHOULD be
considered.
1. Prepend the tag.
2. Prepend a tag with all vital information and add a second tag at
the end of the file, before tags from other tagging systems. The
first tag is required to have a SEEK frame.
3. Add a tag at the end of the file, before tags from other tagging
systems.
In case 2 and 3 the tag can simply be appended if no other known tags
are present. The suggested method to find ID3v2 tags are:
1. Look for a prepended tag using the pattern found in section 3.1.
2. If a SEEK frame was found, use its values to guide further
searching.
3. Look for a tag footer, scanning from the back of the file.
For every new tag that is found, the old tag should be discarded
unless the update flag in the extended header (section 3.2) is set.
6. Unsynchronisation
The only purpose of unsynchronisation is to make the ID3v2 tag as
compatible as possible with existing software and hardware. There is
no use in 'unsynchronising' tags if the file is only to be processed
only by ID3v2 aware software and hardware. Unsynchronisation is only
useful with tags in MPEG 1/2 layer I, II and III, MPEG 2.5 and AAC
files.
6.1. The unsynchronisation scheme
Whenever a false synchronisation is found within the tag, one zeroed
byte is inserted after the first false synchronisation byte. The
format of synchronisations that should be altered by ID3 encoders is
as follows:
%11111111 111xxxxx
and should be replaced with:
%11111111 00000000 111xxxxx
This has the side effect that all $FF 00 combinations have to be
altered, so they will not be affected by the decoding process.
Therefore all the $FF 00 combinations have to be replaced with the
$FF 00 00 combination during the unsynchronisation.
To indicate usage of the unsynchronisation, the unsynchronisation
flag in the frame header should be set. This bit MUST be set if the
frame was altered by the unsynchronisation and SHOULD NOT be set if
unaltered. If all frames in the tag are unsynchronised the
unsynchronisation flag in the tag header SHOULD be set. It MUST NOT
be set if the tag has a frame which is not unsynchronised.
Assume the first byte of the audio to be $FF. The special case when
the last byte of the last frame is $FF and no padding nor footer is
used will then introduce a false synchronisation. This can be solved
by adding a footer, adding padding or unsynchronising the frame and
add $00 to the end of the frame data, thus adding more byte to the
frame size than a normal unsynchronisation would. Although not
preferred, it is allowed to apply the last method on all frames
ending with $FF.
It is preferred that the tag is either completely unsynchronised or
not unsynchronised at all. A completely unsynchronised tag has no
false synchonisations in it, as defined above, and does not end with
$FF. A completely non-unsynchronised tag contains no unsynchronised
frames, and thus the unsynchronisation flag in the header is cleared.
Do bear in mind, that if compression or encryption is used, the
unsynchronisation scheme MUST be applied afterwards. When decoding an
unsynchronised frame, the unsynchronisation scheme MUST be reversed
first, encryption and decompression afterwards.
6.2. Synchsafe integers
In some parts of the tag it is inconvenient to use the
unsychronisation scheme because the size of unsynchronised data is
not known in advance, which is particularly problematic with size
descriptors. The solution in ID3v2 is to use synchsafe integers, in
which there can never be any false synchs. Synchsafe integers are
integers that keep its highest bit (bit 7) zeroed, making seven bits
out of eight available. Thus a 32 bit synchsafe integer can store 28
bits of information.
Example:
255 (%11111111) encoded as a 16 bit synchsafe integer is 383
(%00000001 01111111).
7. Copyright
Copyright (C) Martin Nilsson 2000. All Rights Reserved.
This document and translations of it may be copied and furnished to
others, and derivative works that comment on or otherwise explain it
or assist in its implementation may be prepared, copied, published
and distributed, in whole or in part, without restriction of any
kind, provided that a reference to this document is included on all
such copies and derivative works. However, this document itself may
not be modified in any way and reissued as the original document.
The limited permissions granted above are perpetual and will not be
revoked.
This document and the information contained herein is provided on an
'AS IS' basis and THE AUTHORS DISCLAIMS ALL WARRANTIES, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF
THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
8. References
[ID3v2] Martin Nilsson, 'ID3v2 informal standard'.
<url:http://www.id3.org/id3v2.3.0.txt>
[ISO-639-2] ISO/FDIS 639-2.
'Codes for the representation of names of languages, Part 2: Alpha-3
code.' Technical committee / subcommittee: TC 37 / SC 2
[ISO-3309] ISO 3309
'Information Processing Systems--Data Communication High-Level Data
Link Control Procedure--Frame Structure', IS 3309, October 1984, 3rd
Edition.
[ISO-8859-1] ISO/IEC DIS 8859-1.
'8-bit single-byte coded graphic character sets, Part 1: Latin
alphabet No. 1.' Technical committee / subcommittee: JTC 1 / SC 2
[JFIF] 'JPEG File Interchange Format, version 1.02'
<url:http://www.w3.org/Graphics/JPEG/jfif.txt>
[KEYWORDS] S. Bradner, 'Key words for use in RFCs to Indicate
Requirement Levels', RFC 2119, March 1997.
<url:ftp://ftp.isi.edu/in-notes/rfc2119.txt>
[MPEG] ISO/IEC 11172-3:1993.
'Coding of moving pictures and associated audio for digital storage
media at up to about 1,5 Mbit/s, Part 3: Audio.'
Technical committee / subcommittee: JTC 1 / SC 29
and
ISO/IEC 13818-3:1995
'Generic coding of moving pictures and associated audio information,
Part 3: Audio.'
Technical committee / subcommittee: JTC 1 / SC 29
and
ISO/IEC DIS 13818-3
'Generic coding of moving pictures and associated audio information,
Part 3: Audio (Revision of ISO/IEC 13818-3:1995)'
[PNG] 'Portable Network Graphics, version 1.0'
<url:http://www.w3.org/TR/REC-png-multi.html>
[UNICODE] The Unicode Consortium,
'The Unicode Standard Version 3.0', ISBN 0-201-61633-5.
<url:http://www.unicode.org/unicode/standard/versions/Unicode3.0.htm>
[URL] T. Berners-Lee, L. Masinter & M. McCahill, 'Uniform Resource
Locators (URL)', RFC 1738, December 1994.
<url:ftp://ftp.isi.edu/in-notes/rfc1738.txt>
[UTF-8] F. Yergeau, 'UTF-8, a transformation format of ISO 10646',
RFC 2279, January 1998.
<url:ftp://ftp.isi.edu/in-notes/rfc2279.txt>
[UTF-16] F. Yergeau, 'UTF-16, an encoding of ISO 10646', RFC 2781,
February 2000.
<url:ftp://ftp.isi.edu/in-notes/rfc2781.txt>
[ZLIB] P. Deutsch, Aladdin Enterprises & J-L. Gailly, 'ZLIB
Compressed Data Format Specification version 3.3', RFC 1950,
May 1996.
<url:ftp://ftp.isi.edu/in-notes/rfc1950.txt>
9. Author's Address
Written by
Martin Nilsson
Rydsvägen 246 C. 30
SE-584 34 Linköping
Sweden
Email: nilsson@id3.org

View file

@ -0,0 +1,67 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include "id3v2extendedheader.h"
#include "id3v2synchdata.h"
using namespace TagLib;
using namespace ID3v2;
class ExtendedHeader::ExtendedHeaderPrivate
{
public:
ExtendedHeaderPrivate() : size(0) {}
uint size;
};
////////////////////////////////////////////////////////////////////////////////
// public methods
////////////////////////////////////////////////////////////////////////////////
ExtendedHeader::ExtendedHeader()
{
d = new ExtendedHeaderPrivate();
}
ExtendedHeader::~ExtendedHeader()
{
delete d;
}
TagLib::uint ExtendedHeader::size() const
{
return d->size;
}
void ExtendedHeader::setData(const ByteVector &data)
{
parse(data);
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void ExtendedHeader::parse(const ByteVector &data)
{
d->size = SynchData::toUInt(data.mid(0, 4)); // (structure 3.2 "Extended header size")
}

View file

@ -0,0 +1,88 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V2EXTENDEDHEADER_H
#define TAGLIB_ID3V2EXTENDEDHEADER_H
#include <tbytevector.h>
#include <taglib.h>
namespace TagLib {
namespace ID3v2 {
//! ID3v2 extended header implementation
/*!
* This class implements ID3v2 extended headers. It attempts to follow,
* both semantically and programatically, the structure specified in
* the ID3v2 standard. The API is based on the properties of ID3v2 extended
* headers specified there. If any of the terms used in this documentation
* are unclear please check the specification in the linked section.
* (Structure, <a href="id3v2-structure.html#3.2">3.2</a>)
*/
class ExtendedHeader
{
public:
/*!
* Constructs an empty ID3v2 extended header.
*/
ExtendedHeader();
/*!
* Destroys the extended header.
*/
virtual ~ExtendedHeader();
/*!
* Returns the size of the extended header. This is variable for the
* extended header.
*/
uint size() const;
/*!
* Sets the data that will be used as the extended header. Since the
* length is not known before the extended header has been parsed, this
* should just be a pointer to the first byte of the extended header. It
* will determine the length internally and make that available through
* size().
*/
void setData(const ByteVector &data);
protected:
/*!
* Called by setData() to parse the extended header data. It makes this
* information available through the public API.
*/
void parse(const ByteVector &data);
private:
ExtendedHeader(const ExtendedHeader &);
ExtendedHeader &operator=(const ExtendedHeader &);
class ExtendedHeaderPrivate;
ExtendedHeaderPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,56 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include "id3v2footer.h"
#include "id3v2header.h"
using namespace TagLib;
using namespace ID3v2;
class Footer::FooterPrivate
{
public:
static const uint size = 10;
};
Footer::Footer()
{
}
Footer::~Footer()
{
}
const unsigned int Footer::size()
{
return FooterPrivate::size;
}
ByteVector Footer::render(const Header *header) const
{
ByteVector headerData = header->render();
headerData[0] = '3';
headerData[1] = 'D';
headerData[2] = 'I';
return headerData;
}

View file

@ -0,0 +1,77 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V2FOOTER_H
#define TAGLIB_ID3V2FOOTER_H
#include <tbytevector.h>
namespace TagLib {
namespace ID3v2 {
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 Footer
{
public:
/*!
* Constructs an empty ID3v2 footer.
*/
Footer();
/*!
* Destroys the footer.
*/
virtual ~Footer();
/*!
* Returns the size of the footer. Presently this is always 10 bytes.
*/
static const unsigned int size();
/*!
* Renders the footer based on the data in \a header.
*/
ByteVector render(const Header *header) const;
private:
Footer(const Footer &);
Footer &operator=(const Footer &);
class FooterPrivate;
FooterPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,467 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <config.h>
#include <bitset>
#if HAVE_ZLIB
#include <zlib.h>
#endif
#include <tdebug.h>
#include "id3v2frame.h"
#include "id3v2synchdata.h"
using namespace TagLib;
using namespace ID3v2;
class Frame::FramePrivate
{
public:
FramePrivate() :
header(0)
{}
~FramePrivate()
{
delete header;
}
Frame::Header *header;
};
////////////////////////////////////////////////////////////////////////////////
// static methods
////////////////////////////////////////////////////////////////////////////////
TagLib::uint Frame::headerSize()
{
return Header::size();
}
TagLib::uint Frame::headerSize(uint version)
{
return Header::size(version);
}
ByteVector Frame::textDelimiter(String::Type t)
{
ByteVector d = char(0);
if(t == String::UTF16 || t == String::UTF16BE)
d.append(char(0));
return d;
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Frame::~Frame()
{
delete d;
}
ByteVector Frame::frameID() const
{
if(d->header)
return d->header->frameID();
else
return ByteVector::null;
}
TagLib::uint Frame::size() const
{
if(d->header)
return d->header->frameSize();
else
return 0;
}
void Frame::setData(const ByteVector &data)
{
parse(data);
}
void Frame::setText(const String &)
{
}
ByteVector Frame::render() const
{
ByteVector fieldData = renderFields();
d->header->setFrameSize(fieldData.size());
ByteVector headerData = d->header->render();
return headerData + fieldData;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
Frame::Frame(const ByteVector &data)
{
d = new FramePrivate;
d->header = new Header(data);
}
Frame::Frame(Header *h)
{
d = new FramePrivate;
d->header = h;
}
Frame::Header *Frame::header() const
{
return d->header;
}
void Frame::setHeader(Header *h, bool deleteCurrent)
{
if(deleteCurrent)
delete d->header;
d->header = h;
}
void Frame::parse(const ByteVector &data)
{
if(d->header)
d->header->setData(data);
else
d->header = new Header(data);
parseFields(fieldData(data));
}
ByteVector Frame::fieldData(const ByteVector &frameData) const
{
uint headerSize = Header::size(d->header->version());
uint frameDataOffset = headerSize;
uint frameDataLength = size();
if(d->header->compression() || d->header->dataLengthIndicator()) {
frameDataLength = frameData.mid(headerSize, 4).toUInt();
frameDataOffset += 4;
}
#if HAVE_ZLIB
if(d->header->compression()) {
ByteVector data(frameDataLength);
uLongf uLongTmp = frameDataLength;
::uncompress((Bytef *) data.data(),
(uLongf *) &uLongTmp,
(Bytef *) frameData.data() + frameDataOffset,
size());
return data;
}
else
#endif
return frameData.mid(frameDataOffset, frameDataLength);
}
////////////////////////////////////////////////////////////////////////////////
// Frame::Header class
////////////////////////////////////////////////////////////////////////////////
class Frame::Header::HeaderPrivate
{
public:
HeaderPrivate() :
frameSize(0),
version(4),
tagAlterPreservation(false),
fileAlterPreservation(false),
readOnly(false),
groupingIdentity(false),
compression(false),
encryption(false),
unsyncronisation(false),
dataLengthIndicator(false)
{}
ByteVector frameID;
uint frameSize;
uint version;
// flags
bool tagAlterPreservation;
bool fileAlterPreservation;
bool readOnly;
bool groupingIdentity;
bool compression;
bool encryption;
bool unsyncronisation;
bool dataLengthIndicator;
};
////////////////////////////////////////////////////////////////////////////////
// static members (Frame::Header)
////////////////////////////////////////////////////////////////////////////////
TagLib::uint Frame::Header::size()
{
return size(4);
}
TagLib::uint Frame::Header::size(uint version)
{
switch(version) {
case 0:
case 1:
case 2:
return 6;
case 3:
case 4:
default:
return 10;
}
}
////////////////////////////////////////////////////////////////////////////////
// public members (Frame::Header)
////////////////////////////////////////////////////////////////////////////////
Frame::Header::Header(const ByteVector &data, bool synchSafeInts)
{
d = new HeaderPrivate;
setData(data, synchSafeInts);
}
Frame::Header::Header(const ByteVector &data, uint version)
{
d = new HeaderPrivate;
setData(data, version);
}
Frame::Header::~Header()
{
delete d;
}
void Frame::Header::setData(const ByteVector &data, bool synchSafeInts)
{
setData(data, uint(synchSafeInts ? 4 : 3));
}
void Frame::Header::setData(const ByteVector &data, uint version)
{
d->version = version;
switch(version) {
case 0:
case 1:
case 2:
{
// ID3v2.2
if(data.size() < 3) {
debug("You must at least specify a frame ID.");
return;
}
// Set the frame ID -- the first three bytes
d->frameID = data.mid(0, 3);
// If the full header information was not passed in, do not continue to the
// steps to parse the frame size and flags.
if(data.size() < 6) {
d->frameSize = 0;
return;
}
d->frameSize = data.mid(3, 3).toUInt();
break;
}
case 3:
{
// ID3v2.3
if(data.size() < 4) {
debug("You must at least specify a frame ID.");
return;
}
// Set the frame ID -- the first four bytes
d->frameID = data.mid(0, 4);
// If the full header information was not passed in, do not continue to the
// steps to parse the frame size and flags.
if(data.size() < 10) {
d->frameSize = 0;
return;
}
// Set the size -- the frame size is the four bytes starting at byte four in
// the frame header (structure 4)
d->frameSize = data.mid(4, 4).toUInt();
{ // read the first byte of flags
std::bitset<8> flags(data[8]);
d->tagAlterPreservation = flags[7]; // (structure 3.3.1.a)
d->fileAlterPreservation = flags[6]; // (structure 3.3.1.b)
d->readOnly = flags[5]; // (structure 3.3.1.c)
}
{ // read the second byte of flags
std::bitset<8> flags(data[9]);
d->compression = flags[7]; // (structure 3.3.1.i)
d->encryption = flags[6]; // (structure 3.3.1.j)
d->groupingIdentity = flags[5]; // (structure 3.3.1.k)
}
break;
}
case 4:
default:
{
// ID3v2.4
if(data.size() < 4) {
debug("You must at least specify a frame ID.");
return;
}
// Set the frame ID -- the first four bytes
d->frameID = data.mid(0, 4);
// If the full header information was not passed in, do not continue to the
// steps to parse the frame size and flags.
if(data.size() < 10) {
d->frameSize = 0;
return;
}
// Set the size -- the frame size is the four bytes starting at byte four in
// the frame header (structure 4)
d->frameSize = SynchData::toUInt(data.mid(4, 4));
{ // read the first byte of flags
std::bitset<8> flags(data[8]);
d->tagAlterPreservation = flags[6]; // (structure 4.1.1.a)
d->fileAlterPreservation = flags[5]; // (structure 4.1.1.b)
d->readOnly = flags[4]; // (structure 4.1.1.c)
}
{ // read the second byte of flags
std::bitset<8> flags(data[9]);
d->groupingIdentity = flags[6]; // (structure 4.1.2.h)
d->compression = flags[3]; // (structure 4.1.2.k)
d->encryption = flags[2]; // (structure 4.1.2.m)
d->unsyncronisation = flags[1]; // (structure 4.1.2.n)
d->dataLengthIndicator = flags[0]; // (structure 4.1.2.p)
}
break;
}
}
}
ByteVector Frame::Header::frameID() const
{
return d->frameID;
}
void Frame::Header::setFrameID(const ByteVector &id)
{
d->frameID = id.mid(0, 4);
}
TagLib::uint Frame::Header::frameSize() const
{
return d->frameSize;
}
void Frame::Header::setFrameSize(uint size)
{
d->frameSize = size;
}
TagLib::uint Frame::Header::version() const
{
return d->version;
}
bool Frame::Header::tagAlterPreservation() const
{
return d->tagAlterPreservation;
}
bool Frame::Header::fileAlterPreservation() const
{
return d->fileAlterPreservation;
}
bool Frame::Header::readOnly() const
{
return d->readOnly;
}
bool Frame::Header::groupingIdentity() const
{
return d->groupingIdentity;
}
bool Frame::Header::compression() const
{
return d->compression;
}
bool Frame::Header::encryption() const
{
return d->encryption;
}
bool Frame::Header::unsycronisation() const
{
return d->unsyncronisation;
}
bool Frame::Header::dataLengthIndicator() const
{
return d->dataLengthIndicator;
}
ByteVector Frame::Header::render() const
{
ByteVector flags(2, char(0)); // just blank for the moment
ByteVector v = d->frameID + SynchData::fromUInt(d->frameSize) + flags;
return v;
}
bool Frame::Header::frameAlterPreservation() const // deprecated
{
return fileAlterPreservation();
}

View file

@ -0,0 +1,369 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V2FRAME_H
#define TAGLIB_ID3V2FRAME_H
#include <tstring.h>
#include <tbytevector.h>
namespace TagLib {
namespace ID3v2 {
class FrameFactory;
//! ID3v2 frame implementation
/*!
* This class is the main ID3v2 frame implementation. In ID3v2, a tag is
* split between a collection of frames (which are in turn split into fields
* (Structure, <a href="id3v2-structure.html#4">4</a>)
* (<a href="id3v2-frames.html">Frames</a>). This class provides an API for
* gathering information about and modifying ID3v2 frames. Funtionallity
* specific to a given frame type is handed in one of the many subclasses.
*/
class Frame
{
friend class FrameFactory;
public:
/*!
* Destroys this Frame instance.
*/
virtual ~Frame();
/*!
* Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
* (Frames, <a href="id3v2-frames.html#4">4</a>)
*/
ByteVector frameID() const;
/*!
* Returns the size of the frame.
*/
uint size() const;
/*!
* Returns the size of the frame header
*
* \deprecated This is only accurate for ID3v2.3 or ID3v2.4. Please use
* the call below which accepts an ID3v2 version number. In the next
* non-binary compatible release this will be made into a non-static
* member that checks the internal ID3v2 version.
*/
static uint headerSize(); // BIC: remove and make non-static
/*!
* Returns the size of the frame header for the given ID3v2 version.
*
* \deprecated Please see the explanation above.
*/
static uint headerSize(uint version); // BIC: remove and make non-static
/*!
* Sets the data that will be used as the frame. Since the length is not
* known before the frame has been parsed, this should just be a pointer to
* the first byte of the frame. It will determine the length internally
* and make that available through size().
*/
void setData(const ByteVector &data);
/*!
* Set the text of frame in the sanest way possible. This should only be
* reimplemented in frames where there is some logical mapping to text.
*
* \note If the frame type supports multiple text encodings, this will not
* change the text encoding of the frame; the string will be converted to
* that frame's encoding. Please use the specific APIs of the frame types
* to set the encoding if that is desired.
*/
virtual void setText(const String &text);
/*!
* This returns the textual representation of the data in the frame.
* Subclasses must reimplement this method to provide a string
* representation of the frame's data.
*/
virtual String toString() const = 0;
/*!
* Render the frame back to its binary format in a ByteVector.
*/
ByteVector render() const;
/*!
* Returns the text delimiter that is used between fields for the string
* type \a t.
*/
static ByteVector textDelimiter(String::Type t);
protected:
class Header;
/*!
* Constructs an ID3v2 frame using \a data to read the header information.
* All other processing of \a data should be handled in a subclass.
*
* \note This need not contain anything more than a frame ID, but
* \e must constain at least that.
*/
explicit Frame(const ByteVector &data);
/*!
* This creates an Frame using the header \a h.
*
* The ownership of this header will be assigned to the frame and the
* header will be deleted when the frame is destroyed.
*/
Frame(Header *h);
/*!
* Returns a pointer to the frame header.
*/
Header *header() const;
/*!
* Sets the header to \a h. If \a deleteCurrent is true, this will free
* the memory of the current header.
*
* The ownership of this header will be assigned to the frame and the
* header will be deleted when the frame is destroyed.
*/
void setHeader(Header *h, bool deleteCurrent = true);
/*!
* Called by setData() to parse the frame data. It makes this information
* available through the public API.
*/
void parse(const ByteVector &data);
/*!
* Called by parse() to parse the field data. It makes this information
* available through the public API. This must be overridden by the
* subclasses.
*/
virtual void parseFields(const ByteVector &data) = 0;
/*!
* Render the field data back to a binary format in a ByteVector. This
* must be overridden by subclasses.
*/
virtual ByteVector renderFields() const = 0;
/*!
* Returns a ByteVector containing the field data given the frame data.
* This correctly adjusts for the header size plus any additional frame
* data that's specified in the frame header flags.
*/
ByteVector fieldData(const ByteVector &frameData) const;
private:
Frame(const Frame &);
Frame &operator=(const Frame &);
class FramePrivate;
FramePrivate *d;
};
//! ID3v2 frame header implementation
/*!
* The ID3v2 Frame Header (Structure, <a href="id3v2-structure.html#4">4</a>)
*
* Every ID3v2::Frame has an associated header that gives some general
* properties of the frame and also makes it possible to identify the frame
* type.
*
* As such when reading an ID3v2 tag ID3v2::FrameFactory first creates the
* frame headers and then creates the appropriate Frame subclass based on
* the type and attaches the header.
*/
class Frame::Header
{
public:
/*!
* Construct a Frame Header based on \a data. \a data must at least
* contain a 4 byte frame ID, and optionally can contain flag data and the
* frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
*
* \deprecated Please use the constructor below that accepts a version
* number.
*/
Header(const ByteVector &data, bool synchSafeInts);
/*!
* Construct a Frame Header based on \a data. \a data must at least
* contain a 4 byte frame ID, and optionally can contain flag data and the
* frame size. i.e. Just the frame id -- "TALB" -- is a valid value.
*
* \a version should be the ID3v2 version of the tag.
*/
explicit Header(const ByteVector &data, uint version = 4);
/*!
* Destroys this Header instance.
*/
virtual ~Header();
/*!
* Sets the data for the Header.
*
* \deprecated Please use the version below that accepts an ID3v2 version
* number.
*/
void setData(const ByteVector &data, bool synchSafeInts);
/*!
* Sets the data for the Header. \a version should indicate the ID3v2
* version number of the tag that this frame is contained in.
*/
void setData(const ByteVector &data, uint version = 4);
/*!
* Returns the Frame ID (Structure, <a href="id3v2-structure.html#4">4</a>)
* (Frames, <a href="id3v2-frames.html#4">4</a>)
*/
ByteVector frameID() const;
/*!
* Sets the frame's ID to \a id. Only the first four bytes of \a id will
* be used.
*
* \warning This method should in general be avoided. It exists simply to
* provide a mechanism for transforming frames from a deprecated frame type
* to a newer one -- i.e. TYER to TDRC from ID3v2.3 to ID3v2.4.
*/
void setFrameID(const ByteVector &id);
/*!
* Returns the size of the frame data portion, as set when setData() was
* called or set explicity via setFrameSize().
*/
uint frameSize() const;
/*!
* Sets the size of the frame data portion.
*/
void setFrameSize(uint size);
/*!
* Returns the ID3v2 version of the header (as passed in from the
* construction of the header).
*/
uint version() const;
/*!
* Returns the size of the frame header in bytes.
*
* \deprecated Please use the version of this method that accepts a
* version. This is only accurate for ID3v2.3 and ID3v2.4. This will be
* removed in the next binary incompatible release (2.0) and will be
* replaced with a non-static method that checks the frame version.
*/
static uint size();
/*!
* Returns the size of the frame header in bytes for the ID3v2 version
* that's given.
*
* \deprecated Please see the explanation in the version above.
*/
static uint size(uint version);
/*!
* Returns true if the flag for tag alter preservation is set.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool tagAlterPreservation() const;
/*!
* Returns true if the flag for file alter preservation is set.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool fileAlterPreservation() const;
/*!
* Returns true if the frame is meant to be read only.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool readOnly() const;
/*!
* Returns true if the flag for the grouping identifity is set.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool groupingIdentity() const;
/*!
* Returns true if compression is enabled for this frame.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool compression() const;
/*!
* Returns true if encryption is enabled for this frame.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool encryption() const;
/*!
* Returns true if unsyncronisation is enabled for this frame.
*
* \note This flag is currently ignored internally in TagLib.
*/
bool unsycronisation() const;
/*!
* Returns true if the flag for a data lenght indicator is set.
*/
bool dataLengthIndicator() const;
/*!
* Render the Header back to binary format in a ByteVector.
*/
ByteVector render() const;
/*!
* @deprecated
*/
bool frameAlterPreservation() const;
private:
Header(const Header &);
Header &operator=(const Header &);
class HeaderPrivate;
HeaderPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,309 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <config.h>
#include <tdebug.h>
#include "id3v2framefactory.h"
#include "frames/attachedpictureframe.h"
#include "frames/commentsframe.h"
#include "frames/relativevolumeframe.h"
#include "frames/textidentificationframe.h"
#include "frames/uniquefileidentifierframe.h"
#include "frames/unknownframe.h"
using namespace TagLib;
using namespace ID3v2;
class FrameFactory::FrameFactoryPrivate
{
public:
FrameFactoryPrivate() :
defaultEncoding(String::Latin1),
useDefaultEncoding(false) {}
String::Type defaultEncoding;
bool useDefaultEncoding;
};
FrameFactory *FrameFactory::factory = 0;
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
FrameFactory *FrameFactory::instance()
{
if(!factory)
factory = new FrameFactory;
return factory;
}
Frame *FrameFactory::createFrame(const ByteVector &data, bool synchSafeInts) const
{
return createFrame(data, uint(synchSafeInts ? 4 : 3));
}
Frame *FrameFactory::createFrame(const ByteVector &data, uint version) const
{
Frame::Header *header = new Frame::Header(data, version);
ByteVector frameID = header->frameID();
// A quick sanity check -- make sure that the frameID is 4 uppercase Latin1
// characters. Also make sure that there is data in the frame.
if(!frameID.size() == (version < 3 ? 3 : 4) || header->frameSize() <= 0) {
delete header;
return 0;
}
for(ByteVector::ConstIterator it = frameID.begin(); it != frameID.end(); it++) {
if( (*it < 'A' || *it > 'Z') && (*it < '1' || *it > '9') ) {
delete header;
return 0;
}
}
// TagLib doesn't mess with encrypted frames, so just treat them
// as unknown frames.
#if HAVE_ZLIB == 0
if(header->compression()) {
debug("Compressed frames are currently not supported.");
return new UnknownFrame(data, header);
}
#endif
if(header->encryption()) {
debug("Encrypted frames are currently not supported.");
return new UnknownFrame(data, header);
}
if(!updateFrame(header)) {
delete header;
return 0;
}
// This is where things get necissarily nasty. Here we determine which
// Frame subclass (or if none is found simply an Frame) based
// on the frame ID. Since there are a lot of possibilities, that means
// a lot of if blocks.
// Text Identification (frames 4.2)
if(frameID.startsWith("T")) {
TextIdentificationFrame *f = frameID != "TXXX"
? new TextIdentificationFrame(data, header)
: new UserTextIdentificationFrame(data, header);
if(d->useDefaultEncoding)
f->setTextEncoding(d->defaultEncoding);
return f;
}
// Comments (frames 4.10)
if(frameID == "COMM") {
CommentsFrame *f = new CommentsFrame(data, header);
if(d->useDefaultEncoding)
f->setTextEncoding(d->defaultEncoding);
return f;
}
// Attached Picture (frames 4.14)
if(frameID == "APIC") {
AttachedPictureFrame *f = new AttachedPictureFrame(data, header);
if(d->useDefaultEncoding)
f->setTextEncoding(d->defaultEncoding);
return f;
}
// Relative Volume Adjustment (frames 4.11)
if(frameID == "RVA2")
return new RelativeVolumeFrame(data, header);
// Unique File Identifier (frames 4.1)
if(frameID == "UFID")
return new UniqueFileIdentifierFrame(data, header);
return new UnknownFrame(data, header);
}
String::Type FrameFactory::defaultTextEncoding() const
{
return d->defaultEncoding;
}
void FrameFactory::setDefaultTextEncoding(String::Type encoding)
{
d->useDefaultEncoding = true;
d->defaultEncoding = encoding;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
FrameFactory::FrameFactory()
{
d = new FrameFactoryPrivate;
}
FrameFactory::~FrameFactory()
{
delete d;
}
bool FrameFactory::updateFrame(Frame::Header *header) const
{
TagLib::ByteVector frameID = header->frameID();
switch(header->version()) {
case 2: // ID3v2.2
{
if(frameID == "CRM" ||
frameID == "EQU" ||
frameID == "LNK" ||
frameID == "RVA" ||
frameID == "TIM" ||
frameID == "TSI")
{
debug("ID3v2.4 no longer supports the frame type " + String(frameID) +
". It will be discarded from the tag.");
return false;
}
// ID3v2.2 only used 3 bytes for the frame ID, so we need to convert all of
// the frames to their 4 byte ID3v2.4 equivalent.
convertFrame("BUF", "RBUF", header);
convertFrame("CNT", "PCNT", header);
convertFrame("COM", "COMM", header);
convertFrame("CRA", "AENC", header);
convertFrame("ETC", "ETCO", header);
convertFrame("GEO", "GEOB", header);
convertFrame("IPL", "TIPL", header);
convertFrame("MCI", "MCDI", header);
convertFrame("MLL", "MLLT", header);
convertFrame("PIC", "APIC", header);
convertFrame("POP", "POPM", header);
convertFrame("REV", "RVRB", header);
convertFrame("SLT", "SYLT", header);
convertFrame("STC", "SYTC", header);
convertFrame("TAL", "TALB", header);
convertFrame("TBP", "TBPM", header);
convertFrame("TCM", "TCOM", header);
convertFrame("TCO", "TCON", header);
convertFrame("TCR", "TCOP", header);
convertFrame("TDA", "TDRC", header);
convertFrame("TDY", "TDLY", header);
convertFrame("TEN", "TENC", header);
convertFrame("TFT", "TFLT", header);
convertFrame("TKE", "TKEY", header);
convertFrame("TLA", "TLAN", header);
convertFrame("TLE", "TLEN", header);
convertFrame("TMT", "TMED", header);
convertFrame("TOA", "TOAL", header);
convertFrame("TOF", "TOFN", header);
convertFrame("TOL", "TOLY", header);
convertFrame("TOR", "TDOR", header);
convertFrame("TOT", "TOAL", header);
convertFrame("TP1", "TPE1", header);
convertFrame("TP2", "TPE2", header);
convertFrame("TP3", "TPE3", header);
convertFrame("TP4", "TPE4", header);
convertFrame("TPA", "TPOS", header);
convertFrame("TPB", "TPUB", header);
convertFrame("TRC", "TSRC", header);
convertFrame("TRD", "TDRC", header);
convertFrame("TRK", "TRCK", header);
convertFrame("TSS", "TSSE", header);
convertFrame("TT1", "TIT1", header);
convertFrame("TT2", "TIT2", header);
convertFrame("TT3", "TIT3", header);
convertFrame("TXT", "TOLY", header);
convertFrame("TXX", "TXXX", header);
convertFrame("TYE", "TDRC", header);
convertFrame("UFI", "UFID", header);
convertFrame("ULT", "USLT", header);
convertFrame("WAF", "WOAF", header);
convertFrame("WAR", "WOAR", header);
convertFrame("WAS", "WOAS", header);
convertFrame("WCM", "WCOM", header);
convertFrame("WCP", "WCOP", header);
convertFrame("WPB", "WPUB", header);
convertFrame("WXX", "WXXX", header);
break;
}
case 3: // ID3v2.3
{
if(frameID == "EQUA" ||
frameID == "RVAD" ||
frameID == "TIME" ||
frameID == "TRDA" ||
frameID == "TSIZ")
{
debug("ID3v2.4 no longer supports the frame type " + String(frameID) +
". It will be discarded from the tag.");
return false;
}
convertFrame("TDAT", "TDRC", header);
convertFrame("TORY", "TDOR", header);
convertFrame("TYER", "TDRC", header);
break;
}
default:
// This should catch a typo that existed in TagLib up to and including
// version 1.1 where TRDC was used for the year rather than TDRC.
convertFrame("TRDC", "TDRC", header);
break;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void FrameFactory::convertFrame(const char *from, const char *to,
Frame::Header *header) const
{
if(header->frameID() != from)
return;
// debug("ID3v2.4 no longer supports the frame type " + String(from) + " It has" +
// "been converted to the type " + String(to) + ".");
header->setFrameID(to);
}

View file

@ -0,0 +1,140 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V2FRAMEFACTORY_H
#define TAGLIB_ID3V2FRAMEFACTORY_H
#include <tbytevector.h>
#include "id3v2frame.h"
namespace TagLib {
namespace ID3v2 {
//! A factory for creating ID3v2 frames
/*!
* This factory abstracts away the frame creation process and instantiates
* the appropriate ID3v2::Frame subclasses based on the contents of the
* data.
*
* Reimplementing this factory is the key to adding support for frame types
* not directly supported by TagLib to your application. To do so you would
* subclass this factory reimplement createFrame(). Then by setting your
* factory to be the default factory in ID3v2::Tag constructor or with
* MPEG::File::setID3v2FrameFactory() you can implement behavior that will
* allow for new ID3v2::Frame subclasses (also provided by you) to be used.
*
* This implements both <i>abstract factory</i> and <i>singleton</i> patterns
* of which more information is available on the web and in software design
* textbooks (Notably <i>Design Patters</i>).
*/
class FrameFactory
{
public:
static FrameFactory *instance();
/*!
* Create a frame based on \a data. \a synchSafeInts should only be set
* false if we are parsing an old tag (v2.3 or older) that does not support
* synchsafe ints.
*
* \deprecated Please use the method below that accepts an ID3 version
* number in new code.
*/
Frame *createFrame(const ByteVector &data, bool synchSafeInts) const;
/*!
* Create a frame based on \a data. \a version should indicate the ID3v2
* version of the tag. As ID3v2.4 is the most current version of the
* standard 4 is the default.
*/
// BIC: make virtual
Frame *createFrame(const ByteVector &data, uint version = 4) const;
/*!
* Returns the default text encoding for text frames. If setTextEncoding()
* has not been explicitly called this will only be used for new text
* frames. However, if this value has been set explicitly all frames will be
* converted to this type (unless it's explitly set differently for the
* individual frame) when being rendered.
*
* \see setDefaultTextEncoding()
*/
String::Type defaultTextEncoding() const;
/*!
* Set the default text encoding for all text frames that are created to
* \a encoding. If no value is set the frames with either default to the
* encoding type that was parsed and new frames default to Latin1.
*
* \see defaultTextEncoding()
*/
void setDefaultTextEncoding(String::Type encoding);
protected:
/*!
* Constructs a frame factory. Because this is a singleton this method is
* protected, but may be used for subclasses.
*/
FrameFactory();
/*!
* Destroys the frame factory. In most cases this will never be called (as
* is typical of singletons).
*/
virtual ~FrameFactory();
/*!
* This method checks for compliance to the current ID3v2 standard (2.4)
* and does nothing in the common case. However if a frame is found that
* is not compatible with the current standard, this method either updates
* the frame or indicates that it should be discarded.
*
* This method with return true (with or without changes to the frame) if
* this frame should be kept or false if it should be discarded.
*
* See the id3v2.4.0-changes.txt document for further information.
*/
virtual bool updateFrame(Frame::Header *header) const;
private:
FrameFactory(const FrameFactory &);
FrameFactory &operator=(const FrameFactory &);
/*!
* This method is used internally to convert a frame from ID \a from to ID
* \a to. If the frame matches the \a from pattern and converts the frame
* ID in the \a header or simply does nothing if the frame ID does not match.
*/
void convertFrame(const char *from, const char *to,
Frame::Header *header) const;
static FrameFactory *factory;
class FrameFactoryPrivate;
FrameFactoryPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,227 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <iostream>
#include <bitset>
#include <tstring.h>
#include <tdebug.h>
#include "id3v2header.h"
#include "id3v2footer.h"
#include "id3v2synchdata.h"
using namespace TagLib;
using namespace ID3v2;
class Header::HeaderPrivate
{
public:
HeaderPrivate() : majorVersion(0),
revisionNumber(0),
unsynchronisation(false),
extendedHeader(false),
experimentalIndicator(false),
footerPresent(false),
tagSize(0) {}
~HeaderPrivate() {}
uint majorVersion;
uint revisionNumber;
bool unsynchronisation;
bool extendedHeader;
bool experimentalIndicator;
bool footerPresent;
uint tagSize;
static const uint size = 10;
};
////////////////////////////////////////////////////////////////////////////////
// static members
////////////////////////////////////////////////////////////////////////////////
TagLib::uint Header::size()
{
return HeaderPrivate::size;
}
ByteVector Header::fileIdentifier()
{
return ByteVector::fromCString("ID3");
}
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Header::Header()
{
d = new HeaderPrivate;
}
Header::Header(const ByteVector &data)
{
d = new HeaderPrivate;
parse(data);
}
Header::~Header()
{
delete d;
}
TagLib::uint Header::majorVersion() const
{
return d->majorVersion;
}
TagLib::uint Header::revisionNumber() const
{
return d->revisionNumber;
}
bool Header::unsynchronisation() const
{
return d->unsynchronisation;
}
bool Header::extendedHeader() const
{
return d->extendedHeader;
}
bool Header::experimentalIndicator() const
{
return d->experimentalIndicator;
}
bool Header::footerPresent() const
{
return d->footerPresent;
}
TagLib::uint Header::tagSize() const
{
return d->tagSize;
}
TagLib::uint Header::completeTagSize() const
{
if(d->footerPresent)
return d->tagSize + d->size + Footer::size();
else
return d->tagSize + d->size;
}
void Header::setTagSize(uint s)
{
d->tagSize = s;
}
void Header::setData(const ByteVector &data)
{
parse(data);
}
ByteVector Header::render() const
{
ByteVector v;
// add the file identifier -- "ID3"
v.append(fileIdentifier());
// add the version number -- we always render a 2.4.0 tag regardless of what
// the tag originally was.
v.append(char(4));
v.append(char(0));
// render and add the flags
std::bitset<8> flags;
flags[7] = d->unsynchronisation;
flags[6] = d->extendedHeader;
flags[5] = d->experimentalIndicator;
flags[4] = d->footerPresent;
v.append(char(flags.to_ulong()));
// add the size
v.append(SynchData::fromUInt(d->tagSize));
return v;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void Header::parse(const ByteVector &data)
{
if(data.size() < size())
return;
// do some sanity checking -- even in ID3v2.3.0 and less the tag size is a
// synch-safe integer, so all bytes must be less than 128. If this is not
// true then this is an invalid tag.
// note that we're doing things a little out of order here -- the size is
// later in the bytestream than the version
ByteVector sizeData = data.mid(6, 4);
if(sizeData.size() != 4) {
d->tagSize = 0;
debug("TagLib::ID3v2::Header::parse() - The tag size as read was 0 bytes!");
return;
}
for(ByteVector::Iterator it = sizeData.begin(); it != sizeData.end(); it++) {
if(uchar(*it) >= 128) {
d->tagSize = 0;
debug("TagLib::ID3v2::Header::parse() - One of the size bytes in the id3v2 header was greater than the allowed 128.");
return;
}
}
// The first three bytes, data[0..2], are the File Identifier, "ID3". (structure 3.1 "file identifier")
// Read the version number from the fourth and fifth bytes.
d->majorVersion = data[3]; // (structure 3.1 "major version")
d->revisionNumber = data[4]; // (structure 3.1 "revision number")
// Read the flags, the first four bits of the sixth byte.
std::bitset<8> flags(data[5]);
d->unsynchronisation = flags[7]; // (structure 3.1.a)
d->extendedHeader = flags[6]; // (structure 3.1.b)
d->experimentalIndicator = flags[5]; // (structure 3.1.c)
d->footerPresent = flags[4]; // (structure 3.1.d)
// Get the size from the remaining four bytes (read above)
d->tagSize = SynchData::toUInt(sizeData); // (structure 3.1 "size")
}

View file

@ -0,0 +1,159 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V2HEADER_H
#define TAGLIB_ID3V2HEADER_H
#include <tbytevector.h>
namespace TagLib {
namespace ID3v2 {
//! An implementation of ID3v2 headers
/*!
* This class implements ID3v2 headers. It attempts to follow, both
* semantically and programatically, the structure specified in
* the ID3v2 standard. The API is based on the properties of ID3v2 headers
* specified there. If any of the terms used in this documentation are
* unclear please check the specification in the linked section.
* (Structure, <a href="id3v2-structure.html#3.1">3.1</a>)
*/
class Header
{
public:
/*!
* Constructs an empty ID3v2 header.
*/
Header();
/*!
* Constructs an ID3v2 header based on \a data. parse() is called
* immediately.
*/
Header(const ByteVector &data);
/*!
* Destroys the header.
*/
virtual ~Header();
/*!
* Returns the major version number. (Note: This is the 4, not the 2 in
* ID3v2.4.0. The 2 is implied.)
*/
uint majorVersion() const;
/*!
* Returns the revision number. (Note: This is the 0, not the 4 in
* ID3v2.4.0. The 2 is implied.)
*/
uint revisionNumber() const;
/*!
* Returns true if unsynchronisation has been applied to all frames.
*/
bool unsynchronisation() const;
/*!
* Returns true if an extended header is present in the tag.
*/
bool extendedHeader() const;
/*!
* Returns true if the experimental indicator flag is set.
*/
bool experimentalIndicator() const;
/*!
* Returns true if a footer is present in the tag.
*/
bool footerPresent() const;
/*!
* Returns the tag size in bytes. This is the size of the frame content.
* The size of the \e entire tag will be this plus the header size (10
* bytes) and, if present, the footer size (potentially another 10 bytes).
*
* \note This is the value as read from the header to which TagLib attempts
* to provide an API to; it was not a design decision on the part of TagLib
* to not include the mentioned portions of the tag in the \e size.
*
* \see completeTagSize()
*/
uint tagSize() const;
/*!
* Returns the tag size, including the header and, if present, the footer
* size.
*
* \see tagSize()
*/
uint completeTagSize() const;
/*!
* Set the tag size to \a s.
* \see tagSize()
*/
void setTagSize(uint s);
/*!
* Returns the size of the header. Presently this is always 10 bytes.
*/
static uint size();
/*!
* Returns the string used to identify and ID3v2 tag inside of a file.
* Presently this is always "ID3".
*/
static ByteVector fileIdentifier();
/*!
* Sets the data that will be used as the extended header. 10 bytes,
* starting from \a data will be used.
*/
void setData(const ByteVector &data);
/*!
* Renders the Header back to binary format.
*/
ByteVector render() const;
protected:
/*!
* Called by setData() to parse the header data. It makes this information
* available through the public API.
*/
void parse(const ByteVector &data);
private:
Header(const Header &);
Header &operator=(const Header &);
class HeaderPrivate;
HeaderPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,48 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <iostream>
#include "id3v2synchdata.h"
using namespace TagLib;
using namespace ID3v2;
TagLib::uint SynchData::toUInt(const ByteVector &data)
{
uint sum = 0;
int last = data.size() > 4 ? 3 : data.size() - 1;
for(int i = 0; i <= last; i++)
sum |= (data[i] & 0x7f) << ((last - i) * 7);
return sum;
}
ByteVector SynchData::fromUInt(uint value)
{
ByteVector v(4, 0);
for(int i = 0; i < 4; i++)
v[i] = uchar(value >> ((3 - i) * 7) & 0x7f);
return v;
}

View file

@ -0,0 +1,61 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V2SYNCHDATA_H
#define TAGLIB_ID3V2SYNCHDATA_H
#include <tbytevector.h>
#include <taglib.h>
namespace TagLib {
namespace ID3v2 {
//! A few functions for ID3v2 synch safe integer conversion
/*!
* In the ID3v2.4 standard most integer values are encoded as "synch safe"
* integers which are encoded in such a way that they will not give false
* MPEG syncs and confuse MPEG decoders. This namespace provides some
* methods for converting to and from these values to ByteVectors for
* things rendering and parsing ID3v2 data.
*/
namespace SynchData
{
/*!
* This returns the unsigned integer value of \a data where \a data is a
* ByteVector that contains a \e synchsafe integer (Structure,
* <a href="id3v2-structure.html#6.2">6.2</a>). The default \a length of
* 4 is used if another value is not specified.
*/
uint toUInt(const ByteVector &data);
/*!
* Returns a 4 byte (32 bit) synchsafe integer based on \a value.
*/
ByteVector fromUInt(uint value);
}
}
}
#endif

View file

@ -0,0 +1,464 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <tfile.h>
#include <tdebug.h>
#include "id3v2tag.h"
#include "id3v2header.h"
#include "id3v2extendedheader.h"
#include "id3v2footer.h"
#include "id3v1genres.h"
#include "frames/textidentificationframe.h"
#include "frames/commentsframe.h"
using namespace TagLib;
using namespace ID3v2;
class ID3v2::Tag::TagPrivate
{
public:
TagPrivate() : file(0), tagOffset(-1), extendedHeader(0), footer(0), paddingSize(0)
{
frameList.setAutoDelete(true);
}
~TagPrivate()
{
delete extendedHeader;
delete footer;
}
File *file;
long tagOffset;
const FrameFactory *factory;
Header header;
ExtendedHeader *extendedHeader;
Footer *footer;
int paddingSize;
FrameListMap frameListMap;
FrameList frameList;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
ID3v2::Tag::Tag() : TagLib::Tag()
{
d = new TagPrivate;
d->factory = FrameFactory::instance();
}
ID3v2::Tag::Tag(File *file, long tagOffset, const FrameFactory *factory) :
TagLib::Tag()
{
d = new TagPrivate;
d->file = file;
d->tagOffset = tagOffset;
d->factory = factory;
read();
}
ID3v2::Tag::~Tag()
{
delete d;
}
String ID3v2::Tag::title() const
{
if(!d->frameListMap["TIT2"].isEmpty())
return d->frameListMap["TIT2"].front()->toString();
return String::null;
}
String ID3v2::Tag::artist() const
{
if(!d->frameListMap["TPE1"].isEmpty())
return d->frameListMap["TPE1"].front()->toString();
return String::null;
}
String ID3v2::Tag::album() const
{
if(!d->frameListMap["TALB"].isEmpty())
return d->frameListMap["TALB"].front()->toString();
return String::null;
}
String ID3v2::Tag::comment() const
{
if(!d->frameListMap["COMM"].isEmpty())
return d->frameListMap["COMM"].front()->toString();
return String::null;
}
String ID3v2::Tag::genre() const
{
// TODO: In the next major version (TagLib 2.0) a list of multiple genres
// should be separated by " / " instead of " ". For the moment to keep
// the behavior the same as released versions it is being left with " ".
if(!d->frameListMap["TCON"].isEmpty() &&
dynamic_cast<TextIdentificationFrame *>(d->frameListMap["TCON"].front()))
{
Frame *frame = d->frameListMap["TCON"].front();
// ID3v2.4 lists genres as the fields in its frames field list. If the field
// is simply a number it can be assumed that it is an ID3v1 genre number.
// Here was assume that if an ID3v1 string is present that it should be
// appended to the genre string. Multiple fields will be appended as the
// string is built.
if(d->header.majorVersion() == 4) {
TextIdentificationFrame *f = static_cast<TextIdentificationFrame *>(frame);
StringList fields = f->fieldList();
String genreString;
bool hasNumber = false;
for(StringList::ConstIterator it = fields.begin(); it != fields.end(); ++it) {
bool isNumber = true;
for(String::ConstIterator charIt = (*it).begin();
isNumber && charIt != (*it).end();
++charIt)
{
isNumber = *charIt >= '0' && *charIt <= '9';
}
if(!genreString.isEmpty())
genreString.append(' ');
if(isNumber) {
int number = (*it).toInt();
if(number >= 0 && number <= 255) {
hasNumber = true;
genreString.append(ID3v1::genre(number));
}
}
else
genreString.append(*it);
}
if(hasNumber)
return genreString;
}
String s = frame->toString();
// ID3v2.3 "content type" can contain a ID3v1 genre number in parenthesis at
// the beginning of the field. If this is all that the field contains, do a
// translation from that number to the name and return that. If there is a
// string folloing the ID3v1 genre number, that is considered to be
// authoritative and we return that instead. Or finally, the field may
// simply be free text, in which case we just return the value.
int closing = s.find(")");
if(s.substr(0, 1) == "(" && closing > 0) {
if(closing == int(s.size() - 1))
return ID3v1::genre(s.substr(1, s.size() - 2).toInt());
else
return s.substr(closing + 1);
}
return s;
}
return String::null;
}
TagLib::uint ID3v2::Tag::year() const
{
if(!d->frameListMap["TDRC"].isEmpty())
return d->frameListMap["TDRC"].front()->toString().substr(0, 4).toInt();
return 0;
}
TagLib::uint ID3v2::Tag::track() const
{
if(!d->frameListMap["TRCK"].isEmpty())
return d->frameListMap["TRCK"].front()->toString().toInt();
return 0;
}
void ID3v2::Tag::setTitle(const String &s)
{
setTextFrame("TIT2", s);
}
void ID3v2::Tag::setArtist(const String &s)
{
setTextFrame("TPE1", s);
}
void ID3v2::Tag::setAlbum(const String &s)
{
setTextFrame("TALB", s);
}
void ID3v2::Tag::setComment(const String &s)
{
if(s.isEmpty()) {
removeFrames("COMM");
return;
}
if(!d->frameListMap["COMM"].isEmpty())
d->frameListMap["COMM"].front()->setText(s);
else {
CommentsFrame *f = new CommentsFrame(d->factory->defaultTextEncoding());
addFrame(f);
f->setText(s);
}
}
void ID3v2::Tag::setGenre(const String &s)
{
if(s.isEmpty()) {
removeFrames("TCON");
return;
}
int index = ID3v1::genreIndex(s);
if(index != 255)
setTextFrame("TCON", String::number(index));
else
setTextFrame("TCON", s);
}
void ID3v2::Tag::setYear(uint i)
{
if(i <= 0) {
removeFrames("TDRC");
return;
}
setTextFrame("TDRC", String::number(i));
}
void ID3v2::Tag::setTrack(uint i)
{
if(i <= 0) {
removeFrames("TRCK");
return;
}
setTextFrame("TRCK", String::number(i));
}
bool ID3v2::Tag::isEmpty() const
{
return d->frameList.isEmpty();
}
Header *ID3v2::Tag::header() const
{
return &(d->header);
}
ExtendedHeader *ID3v2::Tag::extendedHeader() const
{
return d->extendedHeader;
}
Footer *ID3v2::Tag::footer() const
{
return d->footer;
}
const FrameListMap &ID3v2::Tag::frameListMap() const
{
return d->frameListMap;
}
const FrameList &ID3v2::Tag::frameList() const
{
return d->frameList;
}
const FrameList &ID3v2::Tag::frameList(const ByteVector &frameID) const
{
return d->frameListMap[frameID];
}
void ID3v2::Tag::addFrame(Frame *frame)
{
d->frameList.append(frame);
d->frameListMap[frame->frameID()].append(frame);
}
void ID3v2::Tag::removeFrame(Frame *frame, bool del)
{
// remove the frame from the frame list
FrameList::Iterator it = d->frameList.find(frame);
d->frameList.erase(it);
// ...and from the frame list map
it = d->frameListMap[frame->frameID()].find(frame);
d->frameListMap[frame->frameID()].erase(it);
// ...and delete as desired
if(del)
delete *it;
}
void ID3v2::Tag::removeFrames(const ByteVector &id)
{
FrameList l = d->frameListMap[id];
for(FrameList::Iterator it = l.begin(); it != l.end(); ++it)
removeFrame(*it, true);
}
ByteVector ID3v2::Tag::render() const
{
// We need to render the "tag data" first so that we have to correct size to
// render in the tag's header. The "tag data" -- everything that is included
// in ID3v2::Header::tagSize() -- includes the extended header, frames and
// padding, but does not include the tag's header or footer.
ByteVector tagData;
// TODO: Render the extended header.
// Loop through the frames rendering them and adding them to the tagData.
for(FrameList::Iterator it = d->frameList.begin(); it != d->frameList.end(); it++)
tagData.append((*it)->render());
// Compute the amount of padding, and append that to tagData.
uint paddingSize = 0;
uint originalSize = d->header.tagSize();
if(tagData.size() < originalSize)
paddingSize = originalSize - tagData.size();
else
paddingSize = 1024;
tagData.append(ByteVector(paddingSize, char(0)));
// Set the tag size.
d->header.setTagSize(tagData.size());
// TODO: This should eventually include d->footer->render().
return d->header.render() + tagData;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
void ID3v2::Tag::read()
{
if(d->file && d->file->isOpen()) {
d->file->seek(d->tagOffset);
d->header.setData(d->file->readBlock(Header::size()));
// if the tag size is 0, then this is an invalid tag (tags must contain at
// least one frame)
if(d->header.tagSize() == 0)
return;
parse(d->file->readBlock(d->header.tagSize()));
}
}
void ID3v2::Tag::parse(const ByteVector &data)
{
uint frameDataPosition = 0;
uint frameDataLength = data.size();
// check for extended header
if(d->header.extendedHeader()) {
if(!d->extendedHeader)
d->extendedHeader = new ExtendedHeader;
d->extendedHeader->setData(data);
if(d->extendedHeader->size() <= data.size()) {
frameDataPosition += d->extendedHeader->size();
frameDataLength -= d->extendedHeader->size();
}
}
// check for footer -- we don't actually need to parse it, as it *must*
// contain the same data as the header, but we do need to account for its
// size.
if(d->header.footerPresent() && Footer::size() <= frameDataLength)
frameDataLength -= Footer::size();
// parse frames
// Make sure that there is at least enough room in the remaining frame data for
// a frame header.
while(frameDataPosition < frameDataLength - Frame::headerSize(d->header.majorVersion())) {
// If the next data is position is 0, assume that we've hit the padding
// portion of the frame data.
if(data.at(frameDataPosition) == 0) {
if(d->header.footerPresent())
debug("Padding *and* a footer found. This is not allowed by the spec.");
d->paddingSize = frameDataLength - frameDataPosition;
return;
}
Frame *frame = d->factory->createFrame(data.mid(frameDataPosition),
d->header.majorVersion());
if(!frame)
return;
// Checks to make sure that frame parsed correctly.
if(frame->size() <= 0) {
delete frame;
return;
}
frameDataPosition += frame->size() + Frame::headerSize(d->header.majorVersion());
addFrame(frame);
}
}
void ID3v2::Tag::setTextFrame(const ByteVector &id, const String &value)
{
if(value.isEmpty()) {
removeFrames(id);
return;
}
if(!d->frameListMap[id].isEmpty())
d->frameListMap[id].front()->setText(value);
else {
const String::Type encoding = d->factory->defaultTextEncoding();
TextIdentificationFrame *f = new TextIdentificationFrame(id, encoding);
addFrame(f);
f->setText(value);
}
}

View file

@ -0,0 +1,295 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_ID3V2TAG_H
#define TAGLIB_ID3V2TAG_H
#include <tag.h>
#include <tbytevector.h>
#include <tstring.h>
#include <tlist.h>
#include <tmap.h>
#include "id3v2framefactory.h"
namespace TagLib {
class File;
//! An ID3v2 implementation
/*!
* This is a relatively complete and flexible framework for working with ID3v2
* tags.
*
* \see ID3v2::Tag
*/
namespace ID3v2 {
class Header;
class ExtendedHeader;
class Footer;
typedef List<Frame *> FrameList;
typedef Map<ByteVector, FrameList> FrameListMap;
//! The main class in the ID3v2 implementation
/*!
* This is the main class in the ID3v2 implementation. It serves two
* functions. This first, as is obvious from the public API, is to provide a
* container for the other ID3v2 related classes. In addition, through the
* read() and parse() protected methods, it provides the most basic level of
* parsing. In these methods the ID3v2 tag is extracted from the file and
* split into data components.
*
* ID3v2 tags have several parts, TagLib attempts to provide an interface
* for them all. header(), footer() and extendedHeader() corespond to those
* data structures in the ID3v2 standard and the APIs for the classes that
* they return attempt to reflect this.
*
* Also ID3v2 tags are built up from a list of frames, which are in turn
* have a header and a list of fields. TagLib provides two ways of accessing
* the list of frames that are in a given ID3v2 tag. The first is simply
* via the frameList() method. This is just a list of pointers to the frames.
* The second is a map from the frame type -- i.e. "COMM" for comments -- and
* a list of frames of that type. (In some cases ID3v2 allows for multiple
* frames of the same type, hence this being a map to a list rather than just
* a map to an individual frame.)
*
* More information on the structure of frames can be found in the ID3v2::Frame
* class.
*
* read() and parse() pass binary data to the other ID3v2 class structures,
* they do not handle parsing of flags or fields, for instace. Those are
* handled by similar functions within those classes.
*
* \note All pointers to data structures within the tag will become invalid
* when the tag is destroyed.
*
* \warning Dealing with the nasty details of ID3v2 is not for the faint of
* heart and should not be done without much meditation on the spec. It's
* rather long, but if you're planning on messing with this class and others
* that deal with the details of ID3v2 (rather than the nice, safe, abstract
* TagLib::Tag and friends), it's worth your time to familiarize yourself
* with said spec (which is distrubuted with the TagLib sources). TagLib
* tries to do most of the work, but with a little luck, you can still
* convince it to generate invalid ID3v2 tags. The APIs for ID3v2 assume a
* working knowledge of ID3v2 structure. You're been warned.
*/
class Tag : public TagLib::Tag
{
public:
/*!
* Constructs an empty ID3v2 tag.
*
* \note You must create at least one frame for this tag to be valid.
*/
Tag();
/*!
* Constructs an ID3v2 tag read from \a file starting at \a tagOffset.
* \a factory specifies which FrameFactory will be used for the
* construction of new frames.
*
* \note You should be able to ignore the \a factory parameter in almost
* all situations. You would want to specify your own FrameFactory
* subclass in the case that you are extending TagLib to support additional
* frame types, which would be incorperated into your factory.
*
* \see FrameFactory
*/
Tag(File *file, long tagOffset,
const FrameFactory *factory = FrameFactory::instance());
/*!
* 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 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 bool isEmpty() const;
/*!
* Returns a pointer to the tag's header.
*/
Header *header() const;
/*!
* Returns a pointer to the tag's extended header or null if there is no
* extended header.
*/
ExtendedHeader *extendedHeader() const;
/*!
* Returns a pointer to the tag's footer or null if there is no footer.
*
* \deprecated I don't see any reason to keep this around since there's
* nothing useful to be retrieved from the footer, but well, again, I'm
* prone to change my mind, so this gets to stay around until near a
* release.
*/
Footer *footer() const;
/*!
* Returns a reference to the frame list map. This is an FrameListMap of
* all of the frames in the tag.
*
* This is the most convenient structure for accessing the tag's frames.
* Many frame types allow multiple instances of the same frame type so this
* is a map of lists. In most cases however there will only be a single
* frame of a certain type.
*
* Let's say for instance that you wanted to access the frame for total
* beats per minute -- the TBPM frame.
*
* \code
* TagLib::MPEG::File f("foo.mp3");
*
* // Check to make sure that it has an ID3v2 tag
*
* if(f.ID3v2Tag()) {
*
* // Get the list of frames for a specific frame type
*
* TagLib::ID3v2::FrameList l = f.ID3v2Tag()->frameListMap()["TBPM"];
*
* if(!l.isEmpty())
* std::cout << l.front().toString() << std::endl;
* }
*
* \endcode
*
* \warning You should not modify this data structure directly, instead
* use addFrame() and removeFrame().
*
* \see frameList()
*/
const FrameListMap &frameListMap() const;
/*!
* Returns a reference to the frame list. This is an FrameList of all of
* the frames in the tag in the order that they were parsed.
*
* This can be useful if for example you want iterate over the tag's frames
* in the order that they occur in the tag.
*
* \warning You should not modify this data structure directly, instead
* use addFrame() and removeFrame().
*/
const FrameList &frameList() const;
/*!
* Returns the frame list for frames with the id \a frameID or an empty
* list if there are no frames of that type. This is just a convenience
* and is equivalent to:
*
* \code
* frameListMap()[frameID];
* \endcode
*
* \see frameListMap()
*/
const FrameList &frameList(const ByteVector &frameID) const;
/*!
* Add a frame to the tag. At this point the tag takes ownership of
* the frame and will handle freeing its memory.
*
* \note Using this method will invalidate any pointers on the list
* returned by frameList()
*/
void addFrame(Frame *frame);
/*!
* Remove a frame from the tag. If \a del is true the frame's memory
* will be freed; if it is false, it must be deleted by the user.
*
* \note Using this method will invalidate any pointers on the list
* returned by frameList()
*/
void removeFrame(Frame *frame, bool del = true);
/*!
* Remove all frames of type \a id from the tag and free their memory.
*
* \note Using this method will invalidate any pointers on the list
* returned by frameList()
*/
void removeFrames(const ByteVector &id);
/*!
* Render the tag back to binary data, suitable to be written to disk.
*/
ByteVector render() const;
protected:
/*!
* Reads data from the file specified in the constructor. It does basic
* parsing of the data in the largest chunks. It partitions the tag into
* the Header, the body of the tag (which contains the ExtendedHeader and
* frames) and Footer.
*/
void read();
/*!
* This is called by read to parse the body of the tag. It determines if an
* extended header exists and adds frames to the FrameListMap.
*/
void parse(const ByteVector &data);
/*!
* Sets the value of the text frame with the Frame ID \a id to \a value.
* If the frame does not exist, it is created.
*/
void setTextFrame(const ByteVector &id, const String &value);
private:
Tag(const Tag &);
Tag &operator=(const Tag &);
class TagPrivate;
TagPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,698 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#include <id3v2tag.h>
#include <id3v2header.h>
#include <id3v1tag.h>
#include <apefooter.h>
#include <apetag.h>
#include <tdebug.h>
#include <bitset>
#include "mpegfile.h"
#include "mpegheader.h"
using namespace TagLib;
namespace TagLib {
/*!
* A union of the ID3v2 and ID3v1 tags.
*/
class MPEGTag : public TagLib::Tag
{
public:
MPEGTag(MPEG::File *f) : TagLib::Tag(), file(f) {}
virtual String title() const
{
if(file->ID3v2Tag() && !file->ID3v2Tag()->title().isEmpty())
return file->ID3v2Tag()->title();
if(file->ID3v1Tag())
return file->ID3v1Tag()->title();
return String::null;
}
virtual String artist() const
{
if(file->ID3v2Tag() && !file->ID3v2Tag()->artist().isEmpty())
return file->ID3v2Tag()->artist();
if(file->ID3v1Tag())
return file->ID3v1Tag()->artist();
return String::null;
}
virtual String album() const
{
if(file->ID3v2Tag() && !file->ID3v2Tag()->album().isEmpty())
return file->ID3v2Tag()->album();
if(file->ID3v1Tag())
return file->ID3v1Tag()->album();
return String::null;
}
virtual String comment() const
{
if(file->ID3v2Tag() && !file->ID3v2Tag()->comment().isEmpty())
return file->ID3v2Tag()->comment();
if(file->ID3v1Tag())
return file->ID3v1Tag()->comment();
return String::null;
}
virtual String genre() const
{
if(file->ID3v2Tag() && !file->ID3v2Tag()->genre().isEmpty())
return file->ID3v2Tag()->genre();
if(file->ID3v1Tag())
return file->ID3v1Tag()->genre();
return String::null;
}
virtual uint year() const
{
if(file->ID3v2Tag() && file->ID3v2Tag()->year() > 0)
return file->ID3v2Tag()->year();
if(file->ID3v1Tag())
return file->ID3v1Tag()->year();
return 0;
}
virtual uint track() const
{
if(file->ID3v2Tag() && file->ID3v2Tag()->track() > 0)
return file->ID3v2Tag()->track();
if(file->ID3v1Tag())
return file->ID3v1Tag()->track();
return 0;
}
virtual void setTitle(const String &s)
{
file->ID3v2Tag(true)->setTitle(s);
file->ID3v1Tag(true)->setTitle(s);
}
virtual void setArtist(const String &s)
{
file->ID3v2Tag(true)->setArtist(s);
file->ID3v1Tag(true)->setArtist(s);
}
virtual void setAlbum(const String &s)
{
file->ID3v2Tag(true)->setAlbum(s);
file->ID3v1Tag(true)->setAlbum(s);
}
virtual void setComment(const String &s)
{
file->ID3v2Tag(true)->setComment(s);
file->ID3v1Tag(true)->setComment(s);
}
virtual void setGenre(const String &s)
{
file->ID3v2Tag(true)->setGenre(s);
file->ID3v1Tag(true)->setGenre(s);
}
virtual void setYear(uint i)
{
file->ID3v2Tag(true)->setYear(i);
file->ID3v1Tag(true)->setYear(i);
}
virtual void setTrack(uint i)
{
file->ID3v2Tag(true)->setTrack(i);
file->ID3v1Tag(true)->setTrack(i);
}
private:
MPEG::File *file;
};
}
class MPEG::File::FilePrivate
{
public:
FilePrivate(ID3v2::FrameFactory *frameFactory = ID3v2::FrameFactory::instance()) :
ID3v2FrameFactory(frameFactory),
ID3v2Tag(0),
ID3v2Location(-1),
ID3v2OriginalSize(0),
APETag(0),
APELocation(-1),
APEOriginalSize(0),
ID3v1Tag(0),
ID3v1Location(-1),
tag(0),
hasID3v2(false),
hasID3v1(false),
hasAPE(false),
properties(0) {}
~FilePrivate() {
delete ID3v2Tag;
delete ID3v1Tag;
delete tag;
delete properties;
}
const ID3v2::FrameFactory *ID3v2FrameFactory;
ID3v2::Tag *ID3v2Tag;
long ID3v2Location;
uint ID3v2OriginalSize;
APE::Tag *APETag;
long APELocation;
uint APEOriginalSize;
ID3v1::Tag *ID3v1Tag;
long ID3v1Location;
MPEGTag *tag;
// These indicate whether the file *on disk* has these tags, not if
// this data structure does. This is used in computing offsets.
bool hasID3v2;
bool hasID3v1;
bool hasAPE;
Properties *properties;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
MPEG::File::File(const char *file, bool readProperties,
Properties::ReadStyle propertiesStyle) : TagLib::File(file)
{
d = new FilePrivate;
if(isOpen()) {
d->tag = new MPEGTag(this);
read(readProperties, propertiesStyle);
}
}
MPEG::File::File(const char *file, ID3v2::FrameFactory *frameFactory,
bool readProperties, Properties::ReadStyle propertiesStyle) :
TagLib::File(file)
{
d = new FilePrivate(frameFactory);
if(isOpen()) {
d->tag = new MPEGTag(this);
read(readProperties, propertiesStyle);
}
}
MPEG::File::~File()
{
delete d;
}
TagLib::Tag *MPEG::File::tag() const
{
return d->tag;
}
MPEG::Properties *MPEG::File::audioProperties() const
{
return d->properties;
}
bool MPEG::File::save()
{
return save(AllTags);
}
bool MPEG::File::save(int tags)
{
if(tags == NoTags)
return strip(AllTags);
if(!d->ID3v2Tag && !d->ID3v1Tag && !d->APETag) {
if(d->hasID3v1 || d->hasID3v2 || d->hasAPE)
return strip(AllTags);
return true;
}
if(readOnly()) {
debug("MPEG::File::save() -- File is read only.");
return false;
}
// Create the tags if we've been asked to. Copy the values from the tag that
// does exist into the new tag.
if((tags & ID3v2) && d->ID3v1Tag)
Tag::duplicate(d->ID3v1Tag, ID3v2Tag(true), false);
if((tags & ID3v1) && d->ID3v2Tag)
Tag::duplicate(d->ID3v2Tag, ID3v1Tag(true), false);
bool success = true;
if(ID3v2 & tags) {
if(d->ID3v2Tag && !d->ID3v2Tag->isEmpty()) {
if(!d->hasID3v2)
d->ID3v2Location = 0;
insert(d->ID3v2Tag->render(), d->ID3v2Location, d->ID3v2OriginalSize);
}
else
success = strip(ID3v2, false) && success;
}
else if(d->hasID3v2)
success = strip(ID3v2) && success;
if(ID3v1 & tags) {
if(d->ID3v1Tag && !d->ID3v1Tag->isEmpty()) {
int offset = d->hasID3v1 ? -128 : 0;
seek(offset, End);
writeBlock(d->ID3v1Tag->render());
}
else
success = strip(ID3v1) && success;
}
else if(d->hasID3v1)
success = strip(ID3v1, false) && success;
// Dont save an APE-tag unless one has been created
if((APE & tags) && d->APETag) {
if(d->hasAPE)
insert(d->APETag->render(), d->APELocation, d->APEOriginalSize);
else {
if(d->hasID3v1) {
insert(d->APETag->render(), d->ID3v1Location, 0);
d->APEOriginalSize = d->APETag->footer()->completeTagSize();
d->hasAPE = true;
d->APELocation = d->ID3v1Location;
d->ID3v1Location += d->APEOriginalSize;
}
else {
seek(0, End);
d->APELocation = tell();
writeBlock(d->APETag->render());
d->APEOriginalSize = d->APETag->footer()->completeTagSize();
d->hasAPE = true;
}
}
}
else if(d->hasAPE)
success = strip(APE, false) && success;
return success;
}
ID3v2::Tag *MPEG::File::ID3v2Tag(bool create)
{
if(!create || d->ID3v2Tag)
return d->ID3v2Tag;
// no ID3v2 tag exists and we've been asked to create one
d->ID3v2Tag = new ID3v2::Tag;
return d->ID3v2Tag;
}
ID3v1::Tag *MPEG::File::ID3v1Tag(bool create)
{
if(!create || d->ID3v1Tag)
return d->ID3v1Tag;
// no ID3v1 tag exists and we've been asked to create one
d->ID3v1Tag = new ID3v1::Tag;
return d->ID3v1Tag;
}
APE::Tag *MPEG::File::APETag(bool create)
{
if(!create || d->APETag)
return d->APETag;
// no APE tag exists and we've been asked to create one
d->APETag = new APE::Tag;
return d->APETag;
}
bool MPEG::File::strip(int tags)
{
return strip(tags, true);
}
bool MPEG::File::strip(int tags, bool freeMemory)
{
if(readOnly()) {
debug("MPEG::File::strip() - Cannot strip tags from a read only file.");
return false;
}
if((tags & ID3v2) && d->hasID3v2) {
removeBlock(d->ID3v2Location, d->ID3v2OriginalSize);
d->ID3v2Location = -1;
d->ID3v2OriginalSize = 0;
d->hasID3v2 = false;
if(freeMemory) {
delete d->ID3v2Tag;
d->ID3v2Tag = 0;
}
// v1 tag location has changed, update if it exists
if(d->ID3v1Tag)
d->ID3v1Location = findID3v1();
}
if((tags & ID3v1) && d->hasID3v1) {
truncate(d->ID3v1Location);
d->ID3v1Location = -1;
d->hasID3v1 = false;
if(freeMemory) {
delete d->ID3v1Tag;
d->ID3v1Tag = 0;
}
}
if((tags & APE) && d->hasAPE) {
removeBlock(d->APELocation, d->APEOriginalSize);
d->APELocation = -1;
d->hasAPE = false;
if(d->hasID3v1) {
if (d->ID3v1Location > d->APELocation)
d->ID3v1Location -= d->APEOriginalSize;
}
if(freeMemory) {
delete d->APETag;
d->APETag = 0;
}
}
return true;
}
void MPEG::File::setID3v2FrameFactory(const ID3v2::FrameFactory *factory)
{
d->ID3v2FrameFactory = factory;
}
long MPEG::File::nextFrameOffset(long position)
{
// TODO: This will miss syncs spanning buffer read boundaries.
ByteVector buffer = readBlock(bufferSize());
while(buffer.size() > 0) {
seek(position);
ByteVector buffer = readBlock(bufferSize());
for(uint i = 0; i < buffer.size(); i++) {
if(uchar(buffer[i]) == 0xff && secondSynchByte(buffer[i + 1]))
return position + i;
}
position += bufferSize();
}
return -1;
}
long MPEG::File::previousFrameOffset(long position)
{
// TODO: This will miss syncs spanning buffer read boundaries.
while(int(position - bufferSize()) > int(bufferSize())) {
position -= bufferSize();
seek(position);
ByteVector buffer = readBlock(bufferSize());
// If the amount of data is smaller than an MPEG header (4 bytes) there's no
// chance of this being valid.
if(buffer.size() < 4)
return -1;
for(int i = buffer.size() - 2; i >= 0; i--) {
if(uchar(buffer[i]) == 0xff && secondSynchByte(buffer[i + 1]))
return position + i;
}
}
return -1;
}
long MPEG::File::firstFrameOffset()
{
long position = 0;
if(d->ID3v2Tag)
position = d->ID3v2Location + d->ID3v2Tag->header()->completeTagSize();
return nextFrameOffset(position);
}
long MPEG::File::lastFrameOffset()
{
return previousFrameOffset(d->ID3v1Tag ? d->ID3v1Location - 1 : length());
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void MPEG::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
{
// Look for an ID3v2 tag
d->ID3v2Location = findID3v2();
if(d->ID3v2Location >= 0) {
d->ID3v2Tag = new ID3v2::Tag(this, d->ID3v2Location, d->ID3v2FrameFactory);
d->ID3v2OriginalSize = d->ID3v2Tag->header()->completeTagSize();
if(d->ID3v2Tag->header()->tagSize() <= 0) {
delete d->ID3v2Tag;
d->ID3v2Tag = 0;
}
else
d->hasID3v2 = true;
}
// Look for an ID3v1 tag
d->ID3v1Location = findID3v1();
if(d->ID3v1Location >= 0) {
d->ID3v1Tag = new ID3v1::Tag(this, d->ID3v1Location);
d->hasID3v1 = true;
}
// Look for an APE tag
d->APELocation = findAPE();
if(d->APELocation >= 0) {
d->APETag = new APE::Tag(this, d->APELocation);
d->APEOriginalSize = d->APETag->footer()->completeTagSize();
d->APELocation = d->APELocation + d->APETag->footer()->size() - d->APEOriginalSize;
d->hasAPE = true;
}
if(readProperties)
d->properties = new Properties(this, propertiesStyle);
}
long MPEG::File::findID3v2()
{
// This method is based on the contents of TagLib::File::find(), but because
// of some subtlteies -- specifically the need to look for the bit pattern of
// an MPEG sync, it has been modified for use here.
if(isValid() && ID3v2::Header::fileIdentifier().size() <= bufferSize()) {
// The position in the file that the current buffer starts at.
long bufferOffset = 0;
ByteVector buffer;
// These variables are used to keep track of a partial match that happens at
// the end of a buffer.
int previousPartialMatch = -1;
bool previousPartialSynchMatch = false;
// Save the location of the current read pointer. We will restore the
// position using seek() before all returns.
long originalPosition = tell();
// Start the search at the beginning of the file.
seek(0);
// This loop is the crux of the find method. There are three cases that we
// want to account for:
// (1) The previously searched buffer contained a partial match of the search
// pattern and we want to see if the next one starts with the remainder of
// that pattern.
//
// (2) The search pattern is wholly contained within the current buffer.
//
// (3) The current buffer ends with a partial match of the pattern. We will
// note this for use in the next itteration, where we will check for the rest
// of the pattern.
for(buffer = readBlock(bufferSize()); buffer.size() > 0; buffer = readBlock(bufferSize())) {
// (1) previous partial match
if(previousPartialSynchMatch && secondSynchByte(buffer[0]))
return -1;
if(previousPartialMatch >= 0 && int(bufferSize()) > previousPartialMatch) {
const int patternOffset = (bufferSize() - previousPartialMatch);
if(buffer.containsAt(ID3v2::Header::fileIdentifier(), 0, patternOffset)) {
seek(originalPosition);
return bufferOffset - bufferSize() + previousPartialMatch;
}
}
// (2) pattern contained in current buffer
long location = buffer.find(ID3v2::Header::fileIdentifier());
if(location >= 0) {
seek(originalPosition);
return bufferOffset + location;
}
int firstSynchByte = buffer.find(char(uchar(255)));
// Here we have to loop because there could be several of the first
// (11111111) byte, and we want to check all such instances until we find
// a full match (11111111 111) or hit the end of the buffer.
while(firstSynchByte >= 0) {
// if this *is not* at the end of the buffer
if(firstSynchByte < int(buffer.size()) - 1) {
if(secondSynchByte(buffer[firstSynchByte + 1])) {
// We've found the frame synch pattern.
seek(originalPosition);
return -1;
}
else {
// We found 11111111 at the end of the current buffer indicating a
// partial match of the synch pattern. The find() below should
// return -1 and break out of the loop.
previousPartialSynchMatch = true;
}
}
// Check in the rest of the buffer.
firstSynchByte = buffer.find(char(uchar(255)), firstSynchByte + 1);
}
// (3) partial match
previousPartialMatch = buffer.endsWithPartialMatch(ID3v2::Header::fileIdentifier());
bufferOffset += bufferSize();
}
// Since we hit the end of the file, reset the status before continuing.
clear();
seek(originalPosition);
}
return -1;
}
long MPEG::File::findID3v1()
{
if(isValid()) {
seek(-128, End);
long p = tell();
if(readBlock(3) == ID3v1::Tag::fileIdentifier())
return p;
}
return -1;
}
long MPEG::File::findAPE()
{
if(isValid()) {
if (d->hasID3v1)
seek(-160, End);
else
seek(-32, End);
long p = tell();
if(readBlock(8) == APE::Tag::fileIdentifier())
return p;
}
return -1;
}
bool MPEG::File::secondSynchByte(char byte)
{
if(uchar(byte) == 0xff)
return false;
std::bitset<8> b(byte);
// check to see if the byte matches 111xxxxx
return b.test(7) && b.test(6) && b.test(5);
}

View file

@ -0,0 +1,260 @@
/***************************************************************************
copyright : (C) 2002, 2003 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 *
***************************************************************************/
#ifndef TAGLIB_MPEGFILE_H
#define TAGLIB_MPEGFILE_H
#include <tfile.h>
#include "mpegproperties.h"
namespace TagLib {
namespace ID3v2 { class Tag; class FrameFactory; }
namespace ID3v1 { class Tag; }
namespace APE { class Tag; }
//! An implementation of TagLib::File with MPEG (MP3) specific methods
namespace MPEG {
//! An MPEG file class with some useful methods specific to MPEG
/*!
* This implements the generic TagLib::File API and additionally provides
* access to properties that are distinct to MPEG files, notably access
* to the different ID3 tags.
*/
class 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 ID3v2 tags.
ID3v2 = 0x0002,
//! Matches APE tags.
APE = 0x0004,
//! Matches all tag types.
AllTags = 0xffff
};
/*!
* Contructs an MPEG 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(const char *file, bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Contructs an MPEG 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. The frames will be created using
* \a frameFactory.
*/
// BIC: merge with the above constructor
File(const char *file, ID3v2::FrameFactory *frameFactory,
bool readProperties = true,
Properties::ReadStyle propertiesStyle = Properties::Average);
/*!
* Destroys this instance of the File.
*/
virtual ~File();
/*!
* Returns a pointer to a tag that is the union of the ID3v2 and ID3v1
* tags. The ID3v2 tag is given priority in reading the information -- if
* requested information exists in both the ID3v2 tag and the ID3v1 tag,
* the information from the ID3v2 tag will be returned.
*
* If you would like more granular control over the content of the tags,
* with the concession of generality, use the tag-type specific calls.
*
* \note As this tag is not implemented as an ID3v2 tag or an ID3v1 tag,
* but a union of the two this pointer may not be cast to the specific
* tag types.
*
* \see ID3v1Tag()
* \see ID3v2Tag()
* \see APETag()
*/
virtual Tag *tag() const;
/*!
* Returns the MPEG::Properties for this file. If no audio properties
* were read then this will return a null pointer.
*/
virtual Properties *audioProperties() const;
/*!
* Save the file. If at least one tag -- ID3v1 or ID3v2 -- exists this
* will duplicate its content into the other tag. This returns true
* if saving was successful.
*
* If neither exists or if both tags are empty, this will strip the tags
* from the file.
*
* This is the same as calling save(AllTags);
*
* If you would like more granular control over the content of the tags,
* with the concession of generality, use paramaterized save call below.
*
* \see save(int tags)
*/
virtual bool save();
/*!
* Save the file. This will attempt to save all of the tag types that are
* specified by OR-ing together TagTypes values. The save() method above
* uses AllTags. This returns true if saving was successful.
*
* This strips all tags not included in the mask, but does not modify them
* in memory, so later calls to save() which make use of these tags will
* remain valid. This also strips empty tags.
*/
bool save(int tags);
/*!
* 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 MPEG::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 MPEG::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
* an APE tag if one does not exist.
*
* \note The Tag <b>is still</b> owned by the MPEG::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 strip the tags that match the OR-ed together TagTypes from the
* file. By default it strips all tags. It returns true if the tags are
* successfully stripped.
*
* This is equivalent to strip(tags, true)
*
* \note This will also invalidate pointers to the ID3 and APE tags
* as their memory will be freed.
*/
bool strip(int tags = AllTags);
/*!
* This will strip the tags that match the OR-ed together TagTypes from the
* file. By default it strips all tags. It returns true if the tags are
* successfully stripped.
*
* If \a freeMemory is true the ID3 and APE tags will be deleted and
* pointers to them will be invalidated.
*/
// BIC: merge with the method above
bool strip(int tags, bool freeMemory);
/*!
* Set the ID3v2::FrameFactory to something other than the default.
*
* \see ID3v2FrameFactory
*/
void setID3v2FrameFactory(const ID3v2::FrameFactory *factory);
/*!
* Returns the position in the file of the first MPEG frame.
*/
long firstFrameOffset();
/*!
* Returns the position in the file of the next MPEG frame,
* using the current position as start
*/
long nextFrameOffset(long position);
/*!
* Returns the position in the file of the previous MPEG frame,
* using the current position as start
*/
long previousFrameOffset(long position);
/*!
* Returns the position in the file of the last MPEG frame.
*/
long lastFrameOffset();
private:
File(const File &);
File &operator=(const File &);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
long findID3v2();
long findID3v1();
long findAPE();
/*!
* MPEG frames can be recognized by the bit pattern 11111111 111, so the
* first byte is easy to check for, however checking to see if the second byte
* starts with \e 111 is a bit more tricky, hence this member function.
*/
static bool secondSynchByte(char byte);
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,253 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include <bitset>
#include <tbytevector.h>
#include <tstring.h>
#include <tdebug.h>
#include "mpegheader.h"
using namespace TagLib;
class MPEG::Header::HeaderPrivate : public RefCounter
{
public:
HeaderPrivate() :
isValid(false),
version(Version1),
layer(0),
protectionEnabled(false),
sampleRate(0),
isPadded(false),
channelMode(Stereo),
isCopyrighted(false),
isOriginal(false),
frameLength(0) {}
bool isValid;
Version version;
int layer;
bool protectionEnabled;
int bitrate;
int sampleRate;
bool isPadded;
ChannelMode channelMode;
bool isCopyrighted;
bool isOriginal;
int frameLength;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
MPEG::Header::Header(const ByteVector &data)
{
d = new HeaderPrivate;
parse(data);
}
MPEG::Header::Header(const Header &h) : d(h.d)
{
d->ref();
}
MPEG::Header::~Header()
{
if (d->deref())
delete d;
}
bool MPEG::Header::isValid() const
{
return d->isValid;
}
MPEG::Header::Version MPEG::Header::version() const
{
return d->version;
}
int MPEG::Header::layer() const
{
return d->layer;
}
bool MPEG::Header::protectionEnabled() const
{
return d->protectionEnabled;
}
int MPEG::Header::bitrate() const
{
return d->bitrate;
}
int MPEG::Header::sampleRate() const
{
return d->sampleRate;
}
bool MPEG::Header::isPadded() const
{
return d->isPadded;
}
MPEG::Header::ChannelMode MPEG::Header::channelMode() const
{
return d->channelMode;
}
bool MPEG::Header::isCopyrighted() const
{
return d->isCopyrighted;
}
bool MPEG::Header::isOriginal() const
{
return d->isOriginal;
}
int MPEG::Header::frameLength() const
{
return d->frameLength;
}
MPEG::Header &MPEG::Header::operator=(const Header &h)
{
if(&h == this)
return *this;
if(d->deref())
delete d;
d = h.d;
d->ref();
return *this;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void MPEG::Header::parse(const ByteVector &data)
{
if(data.size() < 4 || uchar(data[0]) != 0xff) {
debug("MPEG::Header::parse() -- First byte did not mactch MPEG synch.");
return;
}
std::bitset<32> flags(data.toUInt());
// Check for the second byte's part of the MPEG synch
if(!flags[23] || !flags[22] || !flags[21]) {
debug("MPEG::Header::parse() -- Second byte did not mactch MPEG synch.");
return;
}
// Set the MPEG version
if(!flags[20] && !flags[19])
d->version = Version2_5;
else if(flags[20] && !flags[19])
d->version = Version2;
else if(flags[20] && flags[19])
d->version = Version1;
// Set the MPEG layer
if(!flags[18] && flags[17])
d->layer = 3;
else if(flags[18] && !flags[17])
d->layer = 2;
else if(flags[18] && flags[17])
d->layer = 1;
d->protectionEnabled = !flags[16];
// Set the bitrate
static const int bitrates[2][3][16] = {
{ // Version 1
{ 0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0 }, // layer 1
{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0 }, // layer 2
{ 0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0 } // layer 3
},
{ // Version 2 or 2.5
{ 0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0 }, // layer 1
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 }, // layer 2
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0 } // layer 3
}
};
const int versionIndex = d->version == Version1 ? 0 : 1;
const int layerIndex = d->layer > 0 ? d->layer - 1 : 0;
// The bitrate index is encoded as the first 4 bits of the 3rd byte,
// i.e. 1111xxxx
int i = uchar(data[2]) >> 4;
d->bitrate = bitrates[versionIndex][layerIndex][i];
// Set the sample rate
static const int sampleRates[3][4] = {
{ 44100, 48000, 32000, 0 }, // Version 1
{ 22050, 24000, 16000, 0 }, // Version 2
{ 11025, 12000, 8000, 0 } // Version 2.5
};
// The sample rate index is encoded as two bits in the 3nd byte, i.e. xxxx11xx
i = uchar(data[2]) >> 2 & 0x03;
d->sampleRate = sampleRates[d->version][i];
if(d->sampleRate == 0) {
debug("MPEG::Header::parse() -- Invalid sample rate.");
return;
}
// The channel mode is encoded as a 2 bit value at the end of the 3nd byte,
// i.e. xxxxxx11
d->channelMode = ChannelMode(uchar(data[2]) & 0x3);
// TODO: Add mode extension for completeness
d->isCopyrighted = flags[0];
d->isOriginal = flags[1];
// Calculate the frame length
if(d->layer == 1)
d->frameLength = 24000 * 2 * d->bitrate / d->sampleRate + int(d->isPadded);
else
d->frameLength = 72000 * d->bitrate / d->sampleRate + int(d->isPadded);
// Now that we're done parsing, set this to be a valid frame.
d->isValid = true;
}

View file

@ -0,0 +1,155 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#ifndef TAGLIB_MPEGHEADER_H
#define TAGLIB_MPEGHEADER_H
namespace TagLib {
class ByteVector;
namespace MPEG {
//! An implementation of MP3 frame headers
/*!
* This is an implementation of MPEG Layer III headers. The API follows more
* or less the binary format of these headers. I've used
* <a href="http://www.mp3-tech.org/programmer/frame_header.html">this</a>
* document as a reference.
*/
class Header
{
public:
/*!
* Parses an MPEG header based on \a data.
*/
Header(const ByteVector &data);
/*!
* Does a shallow copy of \a h.
*/
Header(const Header &h);
/*!
* Destroys this Header instance.
*/
virtual ~Header();
/*!
* Returns true if the frame is at least an appropriate size and has
* legal values.
*/
bool isValid() const;
/*!
* The MPEG Version.
*/
enum Version {
//! MPEG Version 1
Version1 = 0,
//! MPEG Version 2
Version2 = 1,
//! MPEG Version 2.5
Version2_5 = 2
};
/*!
* Returns the MPEG Version of the header.
*/
Version version() const;
/*!
* Returns the layer version. This will be between the values 1-3.
*/
int layer() const;
/*!
* Returns true if the MPEG protection bit is enabled.
*/
bool protectionEnabled() const;
/*!
* Returns the bitrate encoded in the header.
*/
int bitrate() const;
/*!
* Returns the sample rate in Hz.
*/
int sampleRate() const;
/*!
* Returns true if the frame is padded.
*/
bool isPadded() const;
/*!
* There are a few combinations or one or two channel audio that are
* possible:
*/
enum ChannelMode {
//! Stereo
Stereo = 0,
//! Stereo
JointStereo = 1,
//! Dual Mono
DualChannel = 2,
//! Mono
SingleChannel = 3
};
/*!
* Returns the channel mode for this frame.
*/
ChannelMode channelMode() const;
/*!
* Returns true if the copyrighted bit is set.
*/
bool isCopyrighted() const;
/*!
* Returns true if the "original" bit is set.
*/
bool isOriginal() const;
/*!
* Returns the frame length.
*/
int frameLength() const;
/*!
* Makes a shallow copy of the header.
*/
Header &operator=(const Header &h);
private:
void parse(const ByteVector &data);
class HeaderPrivate;
HeaderPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,220 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include <tdebug.h>
#include <tstring.h>
#include "mpegproperties.h"
#include "mpegfile.h"
#include "xingheader.h"
using namespace TagLib;
class MPEG::Properties::PropertiesPrivate
{
public:
PropertiesPrivate(File *f, ReadStyle s) :
file(f),
style(s),
length(0),
bitrate(0),
sampleRate(0),
channels(0) {}
File *file;
ReadStyle style;
int length;
int bitrate;
int sampleRate;
int channels;
Header::Version version;
int layer;
Header::ChannelMode channelMode;
bool isCopyrighted;
bool isOriginal;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
MPEG::Properties::Properties(File *file, ReadStyle style) : AudioProperties(style)
{
d = new PropertiesPrivate(file, style);
if(file && file->isOpen())
read();
}
MPEG::Properties::~Properties()
{
delete d;
}
int MPEG::Properties::length() const
{
return d->length;
}
int MPEG::Properties::bitrate() const
{
return d->bitrate;
}
int MPEG::Properties::sampleRate() const
{
return d->sampleRate;
}
int MPEG::Properties::channels() const
{
return d->channels;
}
MPEG::Header::Version MPEG::Properties::version() const
{
return d->version;
}
int MPEG::Properties::layer() const
{
return d->layer;
}
MPEG::Header::ChannelMode MPEG::Properties::channelMode() const
{
return d->channelMode;
}
bool MPEG::Properties::isCopyrighted() const
{
return d->isCopyrighted;
}
bool MPEG::Properties::isOriginal() const
{
return d->isOriginal;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void MPEG::Properties::read()
{
// Since we've likely just looked for the ID3v1 tag, start at the end of the
// file where we're least likely to have to have to move the disk head.
long last = d->file->lastFrameOffset();
if(last < 0) {
debug("MPEG::Properties::read() -- Could not find a valid last MPEG frame in the stream.");
return;
}
d->file->seek(last);
Header lastHeader(d->file->readBlock(4));
long first = d->file->firstFrameOffset();
if(first < 0) {
debug("MPEG::Properties::read() -- Could not find a valid first MPEG frame in the stream.");
return;
}
if(!lastHeader.isValid()) {
long pos = last;
while(pos > first) {
pos = d->file->previousFrameOffset(pos);
if(pos < 0)
break;
d->file->seek(pos);
Header header(d->file->readBlock(4));
if(header.isValid()) {
lastHeader = header;
last = pos;
break;
}
}
}
// Now jump back to the front of the file and read what we need from there.
d->file->seek(first);
Header firstHeader(d->file->readBlock(4));
if(!firstHeader.isValid() || !lastHeader.isValid()) {
debug("MPEG::Properties::read() -- Page headers were invalid.");
return;
}
// Check for a Xing header that will help us in gathering information about a
// VBR stream.
int xingHeaderOffset = MPEG::XingHeader::xingHeaderOffset(firstHeader.version(),
firstHeader.channelMode());
d->file->seek(first + xingHeaderOffset);
XingHeader xingHeader(d->file->readBlock(16));
// Read the length and the bitrate from the Xing header.
if(xingHeader.isValid() &&
firstHeader.sampleRate() > 0 &&
xingHeader.totalFrames() > 0)
{
static const int blockSize[] = { 0, 384, 1152, 1152 };
double timePerFrame = blockSize[firstHeader.layer()];
timePerFrame = firstHeader.sampleRate() > 0 ? timePerFrame / firstHeader.sampleRate() : 0;
d->length = int(timePerFrame * xingHeader.totalFrames());
d->bitrate = d->length > 0 ? xingHeader.totalSize() * 8 / d->length / 1000 : 0;
}
// Since there was no valid Xing header found, we hope that we're in a constant
// bitrate file.
// TODO: Make this more robust with audio property detection for VBR without a
// Xing header.
else if(firstHeader.frameLength() > 0 && firstHeader.bitrate() > 0) {
int frames = (last - first) / firstHeader.frameLength() + 1;
d->length = int(float(firstHeader.frameLength() * frames) /
float(firstHeader.bitrate() * 125) + 0.5);
d->bitrate = firstHeader.bitrate();
}
d->sampleRate = firstHeader.sampleRate();
d->channels = firstHeader.channelMode() == Header::SingleChannel ? 1 : 2;
d->version = firstHeader.version();
d->layer = firstHeader.layer();
d->channelMode = firstHeader.channelMode();
d->isCopyrighted = firstHeader.isCopyrighted();
d->isOriginal = firstHeader.isOriginal();
}

View file

@ -0,0 +1,105 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#ifndef TAGLIB_MPEGPROPERTIES_H
#define TAGLIB_MPEGPROPERTIES_H
#include <audioproperties.h>
#include "mpegheader.h"
namespace TagLib {
namespace MPEG {
class File;
//! An implementation of audio property reading for MP3
/*!
* This reads the data from an MPEG Layer III stream found in the
* AudioProperties API.
*/
class Properties : public AudioProperties
{
public:
/*!
* Create an instance of MPEG::Properties with the data read from the
* MPEG::File \a file.
*/
Properties(File *file, ReadStyle style = Average);
/*!
* Destroys this MPEG Properties instance.
*/
virtual ~Properties();
// Reimplementations.
virtual int length() const;
virtual int bitrate() const;
virtual int sampleRate() const;
virtual int channels() const;
/*!
* Returns the MPEG Version of the file.
*/
Header::Version version() const;
/*!
* Returns the layer version. This will be between the values 1-3.
*/
int layer() const;
/*!
* Returns true if the MPEG protection bit is enabled.
*/
bool protectionEnabled() const;
/*!
* Returns the channel mode for this frame.
*/
Header::ChannelMode channelMode() const;
/*!
* Returns true if the copyrighted bit is set.
*/
bool isCopyrighted() const;
/*!
* Returns true if the "original" bit is set.
*/
bool isOriginal() const;
private:
Properties(const Properties &);
Properties &operator=(const Properties &);
void read();
class PropertiesPrivate;
PropertiesPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,111 @@
/***************************************************************************
copyright : (C) 2003 by Ismael Orenstein
email : orenstein@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 *
***************************************************************************/
#include <tbytevector.h>
#include <tstring.h>
#include <tdebug.h>
#include "xingheader.h"
using namespace TagLib;
class MPEG::XingHeader::XingHeaderPrivate
{
public:
XingHeaderPrivate() :
frames(0),
size(0),
valid(false)
{}
uint frames;
uint size;
bool valid;
};
MPEG::XingHeader::XingHeader(const ByteVector &data)
{
d = new XingHeaderPrivate;
parse(data);
}
MPEG::XingHeader::~XingHeader()
{
delete d;
}
bool MPEG::XingHeader::isValid() const
{
return d->valid;
}
TagLib::uint MPEG::XingHeader::totalFrames() const
{
return d->frames;
}
TagLib::uint MPEG::XingHeader::totalSize() const
{
return d->size;
}
int MPEG::XingHeader::xingHeaderOffset(TagLib::MPEG::Header::Version v,
TagLib::MPEG::Header::ChannelMode c)
{
if(v == MPEG::Header::Version1) {
if(c == MPEG::Header::SingleChannel)
return 0x15;
else
return 0x24;
}
else {
if(c == MPEG::Header::SingleChannel)
return 0x0D;
else
return 0x15;
}
}
void MPEG::XingHeader::parse(const ByteVector &data)
{
// Check to see if a valid Xing header is available.
if(data.mid(0, 4) != "Xing")
return;
// If the XingHeader doesn't contain the number of frames and the total stream
// info it's invalid.
if(!(data[7] & 0x02)) {
debug("MPEG::XingHeader::parse() -- Xing header doesn't contain the total number of frames.");
return;
}
if(!(data[7] & 0x04)) {
debug("MPEG::XingHeader::parse() -- Xing header doesn't contain the total stream size.");
return;
}
d->frames = data.mid(8, 4).toUInt();
d->size = data.mid(12, 4).toUInt();
d->valid = true;
}

View file

@ -0,0 +1,91 @@
/***************************************************************************
copyright : (C) 2003 by Ismael Orenstein
email : orenstein@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 *
***************************************************************************/
#ifndef TAGLIB_XINGHEADER_H
#define TAGLIB_XINGHEADER_H
#include "mpegheader.h"
namespace TagLib {
class ByteVector;
namespace MPEG {
//! An implementation of the Xing VBR headers
/*!
* This is a minimalistic implementation of the Xing VBR headers. Xing
* headers are often added to VBR (variable bit rate) MP3 streams to make it
* easy to compute the length and quality of a VBR stream. Our implementation
* is only concerned with the total size of the stream (so that we can
* calculate the total playing time and the average bitrate). It uses
* <a href="http://home.pcisys.net/~melanson/codecs/mp3extensions.txt">this text</a>
* and the XMMS sources as references.
*/
class XingHeader
{
public:
/*!
* Parses a Xing header based on \a data. The data must be at least 16
* bytes long (anything longer than this is discarded).
*/
XingHeader(const ByteVector &data);
/*!
* Destroy this XingHeader instance.
*/
virtual ~XingHeader();
/*!
* Returns true if the data was parsed properly and if there is a vaild
* Xing header present.
*/
bool isValid() const;
/*!
* Returns the total number of frames.
*/
uint totalFrames() const;
/*!
* Returns the total size of stream in bytes.
*/
uint totalSize() const;
/*!
* Returns the offset for the start of this Xing header, given the
* version and channels of the frame
*/
static int xingHeaderOffset(TagLib::MPEG::Header::Version v,
TagLib::MPEG::Header::ChannelMode c);
private:
void parse(const ByteVector &data);
class XingHeaderPrivate;
XingHeaderPrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,23 @@
SUBDIRS = vorbis flac
INCLUDES = -I$(top_srcdir)/taglib -I$(top_srcdir)/taglib/toolkit $(all_includes)
noinst_LTLIBRARIES = libogg.la
libogg_la_SOURCES = \
oggfile.cpp \
oggpage.cpp \
oggpageheader.cpp \
xiphcomment.cpp
taglib_include_HEADERS = \
oggfile.h \
oggpage.h \
oggpageheader.h \
xiphcomment.h
taglib_includedir = $(includedir)/taglib
libogg_la_LIBADD = ./vorbis/libvorbis.la ./flac/liboggflac.la
EXTRA_DIST = $(libogg_la_SOURCES) $(taglib_include_HEADERS)

View file

@ -0,0 +1,664 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
SUBDIRS = vorbis flac
INCLUDES = -I$(top_srcdir)/taglib -I$(top_srcdir)/taglib/toolkit $(all_includes)
noinst_LTLIBRARIES = libogg.la
libogg_la_SOURCES = \
oggfile.cpp \
oggpage.cpp \
oggpageheader.cpp \
xiphcomment.cpp
taglib_include_HEADERS = \
oggfile.h \
oggpage.h \
oggpageheader.h \
xiphcomment.h
taglib_includedir = $(includedir)/taglib
libogg_la_LIBADD = ./vorbis/libvorbis.la ./flac/liboggflac.la
EXTRA_DIST = $(libogg_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/ogg
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
libogg_la_LDFLAGS =
libogg_la_DEPENDENCIES = ./vorbis/libvorbis.la ./flac/liboggflac.la
am_libogg_la_OBJECTS = oggfile.lo oggpage.lo oggpageheader.lo \
xiphcomment.lo
#>- libogg_la_OBJECTS = $(am_libogg_la_OBJECTS)
#>+ 5
libogg_la_final_OBJECTS = libogg_la.all_cpp.lo
libogg_la_nofinal_OBJECTS = oggfile.lo oggpage.lo oggpageheader.lo \
xiphcomment.lo
@KDE_USE_FINAL_FALSE@libogg_la_OBJECTS = $(libogg_la_nofinal_OBJECTS)
@KDE_USE_FINAL_TRUE@libogg_la_OBJECTS = $(libogg_la_final_OBJECTS)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/oggfile.Plo ./$(DEPDIR)/oggpage.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/oggpageheader.Plo \
#>- @AMDEP_TRUE@ ./$(DEPDIR)/xiphcomment.Plo
#>+ 7
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@DEP_FILES = $(DEPDIR)/libogg_la.all_cpp.P ./$(DEPDIR)/oggfile.Plo ./$(DEPDIR)/oggpage.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/oggpageheader.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_TRUE@ @AMDEP_TRUE@ ./$(DEPDIR)/xiphcomment.Plo
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@DEP_FILES = ./$(DEPDIR)/oggfile.Plo ./$(DEPDIR)/oggpage.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/oggpageheader.Plo \
@AMDEP_TRUE@@KDE_USE_FINAL_FALSE@ @AMDEP_TRUE@ ./$(DEPDIR)/xiphcomment.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(libogg_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
RECURSIVE_TARGETS = info-recursive dvi-recursive pdf-recursive \
ps-recursive install-info-recursive uninstall-info-recursive \
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive \
check-recursive installcheck-recursive
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
DIST_SUBDIRS = $(SUBDIRS)
SOURCES = $(libogg_la_SOURCES)
#>- all: all-recursive
#>+ 1
all: docs-am all-recursive
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/ogg/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/ogg/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/ogg/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
libogg.la: $(libogg_la_OBJECTS) $(libogg_la_DEPENDENCIES)
$(CXXLINK) $(libogg_la_LDFLAGS) $(libogg_la_OBJECTS) $(libogg_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oggfile.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oggpage.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oggpageheader.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xiphcomment.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if (etags --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
else \
include_option=--include; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -f $$subdir/TAGS && \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d $(distdir)/$$subdir \
|| mkdir $(distdir)/$$subdir \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="$(top_distdir)" \
distdir=../$(distdir)/$$subdir \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs: installdirs-recursive
installdirs-am:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-recursive
#>+ 1
clean: kde-rpo-clean clean-recursive
#>- clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
#>- mostlyclean-am
#>+ 2
clean-am: clean-final clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-recursive
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-recursive
dvi-am:
info: info-recursive
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am clean \
clean-generic clean-libtool clean-noinstLTLIBRARIES \
clean-recursive ctags ctags-recursive distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-recursive distclean-tags distdir \
dvi dvi-am dvi-recursive info info-am info-recursive install \
install-am install-data install-data-am install-data-recursive \
install-exec install-exec-am install-exec-recursive \
install-info install-info-am install-info-recursive install-man \
install-recursive install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs installdirs-am \
installdirs-recursive maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
pdf pdf-am pdf-recursive ps ps-am ps-recursive tags \
tags-recursive uninstall uninstall-am uninstall-info-am \
uninstall-info-recursive uninstall-recursive \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/ogg/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/ogg/Makefile.in
#>+ 11
libogg_la.all_cpp.cpp: $(srcdir)/Makefile.in $(srcdir)/oggfile.cpp $(srcdir)/oggpage.cpp $(srcdir)/oggpageheader.cpp $(srcdir)/xiphcomment.cpp
@echo 'creating libogg_la.all_cpp.cpp ...'; \
rm -f libogg_la.all_cpp.files libogg_la.all_cpp.final; \
echo "#define KDE_USE_FINAL 1" >> libogg_la.all_cpp.final; \
for file in oggfile.cpp oggpage.cpp oggpageheader.cpp xiphcomment.cpp ; do \
echo "#include \"$$file\"" >> libogg_la.all_cpp.files; \
test ! -f $(srcdir)/$$file || egrep '^#pragma +implementation' $(srcdir)/$$file >> libogg_la.all_cpp.final; \
done; \
cat libogg_la.all_cpp.final libogg_la.all_cpp.files > libogg_la.all_cpp.cpp; \
rm -f libogg_la.all_cpp.final libogg_la.all_cpp.files
#>+ 3
clean-final:
-rm -f libogg_la.all_cpp.cpp
#>+ 2
final:
$(MAKE) libogg_la_OBJECTS="$(libogg_la_final_OBJECTS)" all-am
#>+ 2
final-install:
$(MAKE) libogg_la_OBJECTS="$(libogg_la_final_OBJECTS)" install-am
#>+ 2
no-final:
$(MAKE) libogg_la_OBJECTS="$(libogg_la_nofinal_OBJECTS)" all-am
#>+ 2
no-final-install:
$(MAKE) libogg_la_OBJECTS="$(libogg_la_nofinal_OBJECTS)" install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,15 @@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/flac \
$(all_includes)
noinst_LTLIBRARIES = liboggflac.la
liboggflac_la_SOURCES = oggflacfile.cpp
taglib_include_HEADERS = oggflacfile.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(liboggflac_la_SOURCES) $(taglib_include_HEADERS)

View file

@ -0,0 +1,522 @@
# Makefile.in generated by automake 1.7.6 from Makefile.am.
# KDE tags expanded automatically by am_edit - $Revision: 3 $
# @configure_input@
# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTODIRS = @AUTODIRS@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_FILES = @CONF_FILES@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO = @ECHO@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KDE_PLUGIN = @KDE_PLUGIN@
KDE_USE_CLOSURE_FALSE = @KDE_USE_CLOSURE_FALSE@
KDE_USE_CLOSURE_TRUE = @KDE_USE_CLOSURE_TRUE@
KDE_USE_FINAL_FALSE = @KDE_USE_FINAL_FALSE@
KDE_USE_FINAL_TRUE = @KDE_USE_FINAL_TRUE@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
NOOPT_CFLAGS = @NOOPT_CFLAGS@
NOOPT_CXXFLAGS = @NOOPT_CXXFLAGS@
NOREPO = @NOREPO@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
REPO = @REPO@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
TOPSUBDIRS = @TOPSUBDIRS@
USE_EXCEPTIONS = @USE_EXCEPTIONS@
USE_RTTI = @USE_RTTI@
VERSION = @VERSION@
WOVERLOADED_VIRTUAL = @WOVERLOADED_VIRTUAL@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_RANLIB = @ac_ct_RANLIB@
ac_ct_STRIP = @ac_ct_STRIP@
all_includes = @all_includes@
all_libraries = @all_libraries@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
link_zlib_FALSE = @link_zlib_FALSE@
link_zlib_TRUE = @link_zlib_TRUE@
localstatedir = @localstatedir@
mandir = @mandir@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target = @target@
target_alias = @target_alias@
target_cpu = @target_cpu@
target_os = @target_os@
target_vendor = @target_vendor@
INCLUDES = \
-I$(top_srcdir)/taglib \
-I$(top_srcdir)/taglib/toolkit \
-I$(top_srcdir)/taglib/ogg \
-I$(top_srcdir)/taglib/flac \
$(all_includes)
noinst_LTLIBRARIES = liboggflac.la
liboggflac_la_SOURCES = oggflacfile.cpp
taglib_include_HEADERS = oggflacfile.h
taglib_includedir = $(includedir)/taglib
EXTRA_DIST = $(liboggflac_la_SOURCES) $(taglib_include_HEADERS)
subdir = taglib/ogg/flac
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
mkinstalldirs = $(SHELL) $(top_srcdir)/admin/mkinstalldirs
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
LTLIBRARIES = $(noinst_LTLIBRARIES)
liboggflac_la_LDFLAGS =
liboggflac_la_LIBADD =
am_liboggflac_la_OBJECTS = oggflacfile.lo
#>- liboggflac_la_OBJECTS = $(am_liboggflac_la_OBJECTS)
#>+ 1
liboggflac_la_OBJECTS = oggflacfile.lo
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/admin/depcomp
am__depfiles_maybe = depfiles
#>- @AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/oggflacfile.Plo
#>+ 2
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/oggflacfile.Plo
#>- CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
#>- $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 2
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
#>- LTCXXCOMPILE = $(LIBTOOL) --mode=compile $(CXX) $(DEFS) \
#>- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
#>- $(AM_CXXFLAGS) $(CXXFLAGS)
#>+ 3
LTCXXCOMPILE = $(LIBTOOL) --mode=compile --tag=CXX $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS)
CXXLD = $(CXX)
#>- CXXLINK = $(LIBTOOL) --mode=link $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) \
#>- $(AM_LDFLAGS) $(LDFLAGS) -o $@
#>+ 2
CXXLINK = $(LIBTOOL) --mode=link --tag=CXX $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(KDE_CXXFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
DIST_SOURCES = $(liboggflac_la_SOURCES)
HEADERS = $(taglib_include_HEADERS)
DIST_COMMON = $(taglib_include_HEADERS) Makefile.am Makefile.in
SOURCES = $(liboggflac_la_SOURCES)
#>- all: all-am
#>+ 1
all: docs-am all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
#>- cd $(top_srcdir) && \
#>- $(AUTOMAKE) --gnu taglib/ogg/flac/Makefile
#>+ 3
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/ogg/flac/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/ogg/flac/Makefile.in
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)
clean-noinstLTLIBRARIES:
-test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES)
@list='$(noinst_LTLIBRARIES)'; for p in $$list; do \
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
test "$$dir" = "$$p" && dir=.; \
echo "rm -f \"$${dir}/so_locations\""; \
rm -f "$${dir}/so_locations"; \
done
liboggflac.la: $(liboggflac_la_OBJECTS) $(liboggflac_la_DEPENDENCIES)
$(CXXLINK) $(liboggflac_la_LDFLAGS) $(liboggflac_la_OBJECTS) $(liboggflac_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT) core *.core
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/oggflacfile.Plo@am__quote@
distclean-depend:
-rm -rf ./$(DEPDIR)
.cpp.o:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
.cpp.obj:
@am__fastdepCXX_TRUE@ if $(CXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(CXXCOMPILE) -c -o $@ `if test -f '$<'; then $(CYGPATH_W) '$<'; else $(CYGPATH_W) '$(srcdir)/$<'; fi`
.cpp.lo:
@am__fastdepCXX_TRUE@ if $(LTCXXCOMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" \
@am__fastdepCXX_TRUE@ -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<; \
@am__fastdepCXX_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Plo"; \
@am__fastdepCXX_TRUE@ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
@am__fastdepCXX_TRUE@ fi
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ depfile='$(DEPDIR)/$*.Plo' tmpdepfile='$(DEPDIR)/$*.TPlo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(LTCXXCOMPILE) -c -o $@ `test -f '$<' || echo '$(srcdir)/'`$<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
distclean-libtool:
-rm -f libtool
uninstall-info-am:
taglib_includeHEADERS_INSTALL = $(INSTALL_HEADER)
install-taglib_includeHEADERS: $(taglib_include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f"; \
$(taglib_includeHEADERS_INSTALL) $$d$$p $(DESTDIR)$(taglib_includedir)/$$f; \
done
uninstall-taglib_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(taglib_include_HEADERS)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f $(DESTDIR)$(taglib_includedir)/$$f"; \
rm -f $(DESTDIR)$(taglib_includedir)/$$f; \
done
ETAGS = etags
ETAGSFLAGS =
CTAGS = ctags
CTAGSFLAGS =
tags: TAGS
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$tags$$unique" \
|| $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
top_distdir = ../../..
distdir = $(top_distdir)/$(PACKAGE)-$(VERSION)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkinstalldirs) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
$(mkinstalldirs) $(DESTDIR)$(taglib_includedir)
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f Makefile $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
#>- clean: clean-am
#>+ 1
clean: kde-rpo-clean clean-am
clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \
mostlyclean-am
distclean: distclean-am
distclean-am: clean-am distclean-compile distclean-depend \
distclean-generic distclean-libtool distclean-tags
dvi: dvi-am
dvi-am:
info: info-am
info-am:
install-data-am: install-taglib_includeHEADERS
install-exec-am:
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-taglib_includeHEADERS
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libtool clean-noinstLTLIBRARIES ctags distclean \
distclean-compile distclean-depend distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am info \
info-am install install-am install-data install-data-am \
install-exec install-exec-am install-info install-info-am \
install-man install-strip install-taglib_includeHEADERS \
installcheck installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-info-am \
uninstall-taglib_includeHEADERS
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
#>+ 2
docs-am:
#>+ 6
force-reedit:
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu taglib/ogg/flac/Makefile
cd $(top_srcdir) && perl admin/am_edit taglib/ogg/flac/Makefile.in
#>+ 2
final:
$(MAKE) all-am
#>+ 2
final-install:
$(MAKE) install-am
#>+ 2
no-final:
$(MAKE) all-am
#>+ 2
no-final-install:
$(MAKE) install-am
#>+ 3
cvs-clean:
$(MAKE) admindir=$(top_srcdir)/admin -f $(top_srcdir)/admin/Makefile.common cvs-clean
#>+ 3
kde-rpo-clean:
-rm -f *.rpo

View file

@ -0,0 +1,245 @@
/***************************************************************************
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 *
***************************************************************************/
#include <tbytevector.h>
#include <tstring.h>
#include <tdebug.h>
#include <xiphcomment.h>
#include "oggflacfile.h"
using namespace TagLib;
using TagLib::FLAC::Properties;
class Ogg::FLAC::File::FilePrivate
{
public:
FilePrivate() :
comment(0),
properties(0),
streamStart(0),
streamLength(0),
scanned(false),
hasXiphComment(false),
commentPacket(0) {}
~FilePrivate()
{
delete comment;
delete properties;
}
Ogg::XiphComment *comment;
Properties *properties;
ByteVector streamInfoData;
ByteVector xiphCommentData;
long streamStart;
long streamLength;
bool scanned;
bool hasXiphComment;
int commentPacket;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Ogg::FLAC::File::File(const char *file, bool readProperties,
Properties::ReadStyle propertiesStyle) : Ogg::File(file)
{
d = new FilePrivate;
read(readProperties, propertiesStyle);
}
Ogg::FLAC::File::~File()
{
delete d;
}
Ogg::XiphComment *Ogg::FLAC::File::tag() const
{
return d->comment;
}
Properties *Ogg::FLAC::File::audioProperties() const
{
return d->properties;
}
bool Ogg::FLAC::File::save()
{
d->xiphCommentData = d->comment->render();
// Create FLAC metadata-block:
// Put the size in the first 32 bit (I assume no more than 24 bit are used)
ByteVector v = ByteVector::fromUInt(d->xiphCommentData.size());
// Set the type of the metadata-block to be a Xiph / Vorbis comment
v[0] = 4;
// Append the comment-data after the 32 bit header
v.append(d->xiphCommentData);
// Save the packet at the old spot
// FIXME: Use padding if size is increasing
setPacket(d->commentPacket, v);
return Ogg::File::save();
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
void Ogg::FLAC::File::read(bool readProperties, Properties::ReadStyle propertiesStyle)
{
// Sanity: Check if we really have an Ogg/FLAC file
/*
ByteVector oggHeader = packet(0);
if (oggHeader.mid(28,4) != "fLaC") {
debug("Ogg::FLAC::File::read() -- Not an Ogg/FLAC file");
setValid(false);
return;
}*/
// Look for FLAC metadata, including vorbis comments
scan();
if (!d->scanned) {
setValid(false);
return;
}
if(d->hasXiphComment)
d->comment = new Ogg::XiphComment(xiphCommentData());
else
d->comment = new Ogg::XiphComment;
if(readProperties)
d->properties = new Properties(streamInfoData(), streamLength(), propertiesStyle);
}
ByteVector Ogg::FLAC::File::streamInfoData()
{
scan();
return d->streamInfoData;
}
ByteVector Ogg::FLAC::File::xiphCommentData()
{
scan();
return d->xiphCommentData;
}
long Ogg::FLAC::File::streamLength()
{
scan();
return d->streamLength;
}
void Ogg::FLAC::File::scan()
{
// Scan the metadata pages
if(d->scanned)
return;
if(!isValid())
return;
int ipacket = 1;
long overhead = 0;
ByteVector metadataHeader = packet(ipacket);
if(metadataHeader.isNull())
return;
ByteVector header = metadataHeader.mid(0,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 lastBlock = header[0] & 0x80;
uint length = header.mid(1, 3).toUInt();
overhead += length;
// Sanity: First block should be the stream_info metadata
if(blockType != 0) {
debug("Ogg::FLAC::File::scan() -- Invalid Ogg/FLAC stream");
return;
}
d->streamInfoData = metadataHeader.mid(4,length);
// Search through the remaining metadata
while(!lastBlock) {
metadataHeader = packet(++ipacket);
header = metadataHeader.mid(0, 4);
blockType = header[0] & 0x7f;
lastBlock = header[0] & 0x80;
length = header.mid(1, 3).toUInt();
overhead += length;
if(blockType == 1) {
// debug("Ogg::FLAC::File::scan() -- Padding found");
}
else if(blockType == 4) {
// debug("Ogg::FLAC::File::scan() -- Vorbis-comments found");
d->xiphCommentData = metadataHeader.mid(4, length);
d->hasXiphComment = true;
d->commentPacket = ipacket;
}
else if(blockType > 5)
debug("Ogg::FLAC::File::scan() -- Unknown metadata block");
}
// End of metadata, now comes the datastream
d->streamStart = overhead;
d->streamLength = File::length() - d->streamStart;
d->scanned = true;
}

View file

@ -0,0 +1,113 @@
/***************************************************************************
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 *
***************************************************************************/
#ifndef TAGLIB_OGGFLACFILE_H
#define TAGLIB_OGGFLACFILE_H
#include <oggfile.h>
#include <xiphcomment.h>
#include <flacproperties.h>
namespace TagLib {
class Tag;
namespace Ogg {
//! An implementation of Ogg FLAC metadata
/*!
* This is implementation of FLAC metadata for Ogg FLAC files. For "pure"
* FLAC files look under the FLAC hiearchy.
*
* Unlike "pure" FLAC-files, Ogg FLAC only supports Xiph-comments,
* while the audio-properties are the same.
*/
namespace FLAC {
using TagLib::FLAC::Properties;
//! An implementation of TagLib::File with Ogg/FLAC specific methods
/*!
* This implements and provides an interface for Ogg/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 Ogg FLAC files.
*/
class File : public Ogg::File
{
public:
/*!
* Contructs an Ogg/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.
*/
File(const char *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 always be a XiphComment.
*/
virtual XiphComment *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 and update the XiphComment.
* Returns true if the save is successful.
*/
virtual bool save();
/*!
* Returns the length of the audio-stream, used by FLAC::Properties for
* calculating the bitrate.
*/
long streamLength();
private:
File(const File &);
File &operator=(const File &);
void read(bool readProperties, Properties::ReadStyle propertiesStyle);
void scan();
ByteVector streamInfoData();
ByteVector xiphCommentData();
class FilePrivate;
FilePrivate *d;
};
} // namespace FLAC
} // namespace Ogg
} // namespace TagLib
#endif

View file

@ -0,0 +1,332 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include <tbytevectorlist.h>
#include <tmap.h>
#include <tstring.h>
#include <tdebug.h>
#include "oggfile.h"
#include "oggpage.h"
#include "oggpageheader.h"
using namespace TagLib;
class Ogg::File::FilePrivate
{
public:
FilePrivate() :
streamSerialNumber(0),
firstPageHeader(0),
lastPageHeader(0),
currentPage(0),
currentPacketPage(0)
{
pages.setAutoDelete(true);
}
~FilePrivate()
{
delete firstPageHeader;
delete lastPageHeader;
}
uint streamSerialNumber;
List<Page *> pages;
PageHeader *firstPageHeader;
PageHeader *lastPageHeader;
std::vector< List<int> > packetToPageMap;
Map<int, ByteVector> dirtyPackets;
List<int> dirtyPages;
//! The current page for the reader -- used by nextPage()
Page *currentPage;
//! The current page for the packet parser -- used by packet()
Page *currentPacketPage;
//! The packets for the currentPacketPage -- used by packet()
ByteVectorList currentPackets;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Ogg::File::~File()
{
delete d;
}
ByteVector Ogg::File::packet(uint i)
{
// Check to see if we're called setPacket() for this packet since the last
// save:
if(d->dirtyPackets.contains(i))
return d->dirtyPackets[i];
// If we haven't indexed the page where the packet we're interested in starts,
// begin reading pages until we have.
while(d->packetToPageMap.size() <= i) {
if(!nextPage()) {
debug("Ogg::File::packet() -- Could not find the requested packet.");
return ByteVector::null;
}
}
// Start reading at the first page that contains part (or all) of this packet.
// If the last read stopped at the packet that we're interested in, don't
// reread its packet list. (This should make sequential packet reads fast.)
uint pageIndex = d->packetToPageMap[i].front();
if(d->currentPacketPage != d->pages[pageIndex]) {
d->currentPacketPage = d->pages[pageIndex];
d->currentPackets = d->currentPacketPage->packets();
}
// If the packet is completely contained in the first page that it's in, then
// just return it now.
if(d->currentPacketPage->containsPacket(i) & Page::CompletePacket)
return d->currentPackets[i - d->currentPacketPage->firstPacketIndex()];
// If the packet is *not* completely contained in the first page that it's a
// part of then that packet trails off the end of the page. Continue appending
// the pages' packet data until we hit a page that either does not end with the
// packet that we're fetching or where the last packet is complete.
ByteVector packet = d->currentPackets.back();
while(d->currentPacketPage->containsPacket(i) & Page::EndsWithPacket &&
!d->currentPacketPage->header()->lastPacketCompleted())
{
pageIndex++;
if(pageIndex == d->pages.size()) {
if(!nextPage()) {
debug("Ogg::File::packet() -- Could not find the requested packet.");
return ByteVector::null;
}
}
d->currentPacketPage = d->pages[pageIndex];
d->currentPackets = d->currentPacketPage->packets();
packet.append(d->currentPackets.front());
}
return packet;
}
void Ogg::File::setPacket(uint i, const ByteVector &p)
{
while(d->packetToPageMap.size() <= i) {
if(!nextPage()) {
debug("Ogg::File::setPacket() -- Could not set the requested packet.");
return;
}
}
List<int>::ConstIterator it = d->packetToPageMap[i].begin();
for(; it != d->packetToPageMap[i].end(); ++it)
d->dirtyPages.sortedInsert(*it, true);
d->dirtyPackets.insert(i, p);
}
const Ogg::PageHeader *Ogg::File::firstPageHeader()
{
if(d->firstPageHeader)
return d->firstPageHeader->isValid() ? d->firstPageHeader : 0;
long firstPageHeaderOffset = find("OggS");
if(firstPageHeaderOffset < 0)
return 0;
d->firstPageHeader = new PageHeader(this, firstPageHeaderOffset);
return d->firstPageHeader->isValid() ? d->firstPageHeader : 0;
}
const Ogg::PageHeader *Ogg::File::lastPageHeader()
{
if(d->lastPageHeader)
return d->lastPageHeader->isValid() ? d->lastPageHeader : 0;
long lastPageHeaderOffset = rfind("OggS");
if(lastPageHeaderOffset < 0)
return 0;
d->lastPageHeader = new PageHeader(this, lastPageHeaderOffset);
return d->lastPageHeader->isValid() ? d->lastPageHeader : 0;
}
bool Ogg::File::save()
{
if(readOnly()) {
debug("Ogg::File::save() - Cannot save to a read only file.");
return false;
}
List<int> pageGroup;
for(List<int>::ConstIterator it = d->dirtyPages.begin(); it != d->dirtyPages.end(); ++it) {
if(!pageGroup.isEmpty() && pageGroup.back() + 1 != *it) {
writePageGroup(pageGroup);
pageGroup.clear();
}
else
pageGroup.append(*it);
}
writePageGroup(pageGroup);
d->dirtyPages.clear();
d->dirtyPackets.clear();
return true;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
Ogg::File::File(const char *file) : TagLib::File(file)
{
d = new FilePrivate;
}
////////////////////////////////////////////////////////////////////////////////
// private members
////////////////////////////////////////////////////////////////////////////////
bool Ogg::File::nextPage()
{
long nextPageOffset;
int currentPacket;
if(d->pages.isEmpty()) {
currentPacket = 0;
nextPageOffset = find("OggS");
if(nextPageOffset < 0)
return false;
}
else {
if(d->currentPage->header()->lastPageOfStream())
return false;
if(d->currentPage->header()->lastPacketCompleted())
currentPacket = d->currentPage->firstPacketIndex() + d->currentPage->packetCount();
else
currentPacket = d->currentPage->firstPacketIndex() + d->currentPage->packetCount() - 1;
nextPageOffset = d->currentPage->fileOffset() + d->currentPage->size();
}
// Read the next page and add it to the page list.
d->currentPage = new Page(this, nextPageOffset);
if(!d->currentPage->header()->isValid()) {
delete d->currentPage;
d->currentPage = 0;
return false;
}
d->currentPage->setFirstPacketIndex(currentPacket);
if(d->pages.isEmpty())
d->streamSerialNumber = d->currentPage->header()->streamSerialNumber();
d->pages.append(d->currentPage);
// Loop through the packets in the page that we just read appending the
// current page number to the packet to page map for each packet.
for(uint i = 0; i < d->currentPage->packetCount(); i++) {
uint currentPacket = d->currentPage->firstPacketIndex() + i;
if(d->packetToPageMap.size() <= currentPacket)
d->packetToPageMap.push_back(List<int>());
d->packetToPageMap[currentPacket].append(d->pages.size() - 1);
}
return true;
}
void Ogg::File::writePageGroup(const List<int> &pageGroup)
{
if(pageGroup.isEmpty())
return;
ByteVectorList packets;
// If the first page of the group isn't dirty, append its partial content here.
if(!d->dirtyPages.contains(d->pages[pageGroup.front()]->firstPacketIndex()))
packets.append(d->pages[pageGroup.front()]->packets().front());
int previousPacket = -1;
int originalSize = 0;
for(List<int>::ConstIterator it = pageGroup.begin(); it != pageGroup.end(); ++it) {
uint firstPacket = d->pages[*it]->firstPacketIndex();
uint lastPacket = firstPacket + d->pages[*it]->packetCount() - 1;
List<int>::ConstIterator last = --pageGroup.end();
for(uint i = firstPacket; i <= lastPacket; i++) {
if(it == last && i == lastPacket && !d->dirtyPages.contains(i))
packets.append(d->pages[*it]->packets().back());
else if(int(i) != previousPacket) {
previousPacket = i;
packets.append(packet(i));
}
}
originalSize += d->pages[*it]->size();
}
const bool continued = d->pages[pageGroup.front()]->header()->firstPacketContinued();
const bool completed = d->pages[pageGroup.back()]->header()->lastPacketCompleted();
// TODO: This pagination method isn't accurate for what's being done here.
// This should account for real possibilities like non-aligned packets and such.
List<Page *> pages = Page::paginate(packets, Page::SinglePagePerGroup,
d->streamSerialNumber, pageGroup.front(),
continued, completed);
ByteVector data;
for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it)
data.append((*it)->render());
// The insertion algorithms could also be improve to queue and prioritize data
// on the way out. Currently it requires rewriting the file for every page
// group rather than just once; however, for tagging applications there will
// generally only be one page group, so it's not worth the time for the
// optimization at the moment.
insert(data, d->pages[pageGroup.front()]->fileOffset(), originalSize);
// Update the page index to include the pages we just created and to delete the
// old pages.
for(List<Page *>::ConstIterator it = pages.begin(); it != pages.end(); ++it) {
const int index = (*it)->header()->pageSequenceNumber();
delete d->pages[index];
d->pages[index] = *it;
}
}

View file

@ -0,0 +1,107 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include <tfile.h>
#include <tbytevectorlist.h>
#ifndef TAGLIB_OGGFILE_H
#define TAGLIB_OGGFILE_H
namespace TagLib {
//! A namespace for the classes used by Ogg-based metadata files
namespace Ogg {
class PageHeader;
//! An implementation of TagLib::File with some helpers for Ogg based formats
/*!
* This is an implementation of Ogg file page and packet rendering and is of
* use to Ogg based formats. While the API is small this handles the
* non-trivial details of breaking up an Ogg stream into packets and makes
* these available (via subclassing) to the codec meta data implementations.
*/
class File : public TagLib::File
{
public:
virtual ~File();
/*!
* Returns the packet contents for the i-th packet (starting from zero)
* in the Ogg bitstream.
*
* \warning The requires reading at least the packet header for every page
* up to the requested page.
*/
ByteVector packet(uint i);
/*!
* Sets the packet with index \a i to the value \a p.
*/
void setPacket(uint i, const ByteVector &p);
/*!
* Returns a pointer to the PageHeader for the first page in the stream or
* null if the page could not be found.
*/
const PageHeader *firstPageHeader();
/*!
* Returns a pointer to the PageHeader for the last page in the stream or
* null if the page could not be found.
*/
const PageHeader *lastPageHeader();
virtual bool save();
protected:
/*!
* Contructs an Ogg file from \a file. If \a readProperties is true the
* file's audio properties will also be read using \a propertiesStyle. If
* false, \a propertiesStyle is ignored.
*
* \note This constructor is protected since Ogg::File shouldn't be
* instantiated directly but rather should be used through the codec
* specific subclasses.
*/
File(const char *file);
private:
File(const File &);
File &operator=(const File &);
/*!
* Reads the next page and updates the internal "current page" pointer.
*/
bool nextPage();
void writePageGroup(const List<int> &group);
class FilePrivate;
FilePrivate *d;
};
}
}
#endif

View file

@ -0,0 +1,251 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#include <tstring.h>
#include "oggpage.h"
#include "oggpageheader.h"
#include "oggfile.h"
using namespace TagLib;
class Ogg::Page::PagePrivate
{
public:
PagePrivate(File *f = 0, long pageOffset = -1) :
file(f),
fileOffset(pageOffset),
packetOffset(0),
header(f, pageOffset),
firstPacketIndex(-1)
{
if(file) {
packetOffset = fileOffset + header.size();
packetSizes = header.packetSizes();
dataSize = header.dataSize();
}
}
File *file;
long fileOffset;
long packetOffset;
int dataSize;
List<int> packetSizes;
PageHeader header;
int firstPacketIndex;
ByteVectorList packets;
};
////////////////////////////////////////////////////////////////////////////////
// public members
////////////////////////////////////////////////////////////////////////////////
Ogg::Page::Page(Ogg::File *file, long pageOffset)
{
d = new PagePrivate(file, pageOffset);
}
Ogg::Page::~Page()
{
delete d;
}
long Ogg::Page::fileOffset() const
{
return d->fileOffset;
}
const Ogg::PageHeader *Ogg::Page::header() const
{
return &d->header;
}
int Ogg::Page::firstPacketIndex() const
{
return d->firstPacketIndex;
}
void Ogg::Page::setFirstPacketIndex(int index)
{
d->firstPacketIndex = index;
}
Ogg::Page::ContainsPacketFlags Ogg::Page::containsPacket(int index) const
{
int lastPacketIndex = d->firstPacketIndex + packetCount() - 1;
if(index < d->firstPacketIndex || index > lastPacketIndex)
return DoesNotContainPacket;
ContainsPacketFlags flags = DoesNotContainPacket;
if(index == d->firstPacketIndex)
flags = ContainsPacketFlags(flags | BeginsWithPacket);
if(index == lastPacketIndex)
flags = ContainsPacketFlags(flags | EndsWithPacket);
// If there's only one page and it's complete:
if(packetCount() == 1 &&
!d->header.firstPacketContinued() &&
d->header.lastPacketCompleted())
{
flags = ContainsPacketFlags(flags | CompletePacket);
}
// Or if the page is (a) the first page and it's complete or (b) the last page
// and it's complete or (c) a page in the middle.
else if((flags & BeginsWithPacket && !d->header.firstPacketContinued()) ||
(flags & EndsWithPacket && d->header.lastPacketCompleted()) ||
(!(flags & BeginsWithPacket) && !(flags & EndsWithPacket)))
{
flags = ContainsPacketFlags(flags | CompletePacket);
}
return flags;
}
TagLib::uint Ogg::Page::packetCount() const
{
return d->header.packetSizes().size();
}
ByteVectorList Ogg::Page::packets() const
{
if(!d->packets.isEmpty())
return d->packets;
ByteVectorList l;
if(d->file && d->header.isValid()) {
d->file->seek(d->packetOffset);
List<int> packetSizes = d->header.packetSizes();
List<int>::ConstIterator it = packetSizes.begin();
for(; it != packetSizes.end(); ++it)
l.append(d->file->readBlock(*it));
}
else
debug("Ogg::Page::packets() -- attempting to read packets from an invalid page.");
return l;
}
int Ogg::Page::size() const
{
return d->header.size() + d->header.dataSize();
}
ByteVector Ogg::Page::render() const
{
ByteVector data;
data.append(d->header.render());
if(d->packets.isEmpty()) {
if(d->file) {
d->file->seek(d->packetOffset);
data.append(d->file->readBlock(d->dataSize));
}
else
debug("Ogg::Page::render() -- this page is empty!");
}
else {
ByteVectorList::ConstIterator it = d->packets.begin();
for(; it != d->packets.end(); ++it)
data.append(*it);
}
// Compute and set the checksum for the Ogg page. The checksum is taken over
// the entire page with the 4 bytes reserved for the checksum zeroed and then
// inserted in bytes 22-25 of the page header.
ByteVector checksum = ByteVector::fromUInt(data.checksum(), false);
for(int i = 0; i < 4; i++)
data[i + 22] = checksum[i];
return data;
}
List<Ogg::Page *> Ogg::Page::paginate(const ByteVectorList &packets,
PaginationStrategy strategy,
uint streamSerialNumber,
int firstPage,
bool firstPacketContinued,
bool lastPacketCompleted,
bool containsLastPacket)
{
List<Page *> l;
int totalSize = 0;
for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it)
totalSize += (*it).size();
if(strategy == Repaginate || totalSize + packets.size() > 255 * 256) {
debug("Ogg::Page::paginate() -- Sorry! Repagination is not yet implemented.");
return l;
}
// TODO: Handle creation of multiple pages here with appropriate pagination.
Page *p = new Page(packets, streamSerialNumber, firstPage, firstPacketContinued,
lastPacketCompleted, containsLastPacket);
l.append(p);
return l;
}
////////////////////////////////////////////////////////////////////////////////
// protected members
////////////////////////////////////////////////////////////////////////////////
Ogg::Page::Page(const ByteVectorList &packets,
uint streamSerialNumber,
int pageNumber,
bool firstPacketContinued,
bool lastPacketCompleted,
bool containsLastPacket)
{
d = new PagePrivate;
ByteVector data;
List<int> packetSizes;
d->header.setFirstPageOfStream(pageNumber == 0 && !firstPacketContinued);
d->header.setLastPageOfStream(containsLastPacket);
d->header.setFirstPacketContinued(firstPacketContinued);
d->header.setLastPacketCompleted(lastPacketCompleted);
d->header.setStreamSerialNumber(streamSerialNumber);
d->header.setPageSequenceNumber(pageNumber);
// Build a page from the list of packets.
for(ByteVectorList::ConstIterator it = packets.begin(); it != packets.end(); ++it) {
packetSizes.append((*it).size());
data.append(*it);
}
d->packets = packets;
d->header.setPacketSizes(packetSizes);
}

View file

@ -0,0 +1,198 @@
/***************************************************************************
copyright : (C) 2003 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 *
***************************************************************************/
#ifndef TAGLIB_OGGPAGE_H
#define TAGLIB_OGGPAGE_H
#include <tbytevectorlist.h>
namespace TagLib {
namespace Ogg {
class File;
class PageHeader;
//! An implementation of Ogg pages
/*!
* This is an implementation of the pages that make up an Ogg stream.
* This handles parsing pages and breaking them down into packets and handles
* the details of packets spanning multiple pages and pages that contiain
* multiple packets.
*
* In most Xiph.org formats the comments are found in the first few packets,
* this however is a reasonably complete implementation of Ogg pages that
* could potentially be useful for non-meta data purposes.
*/
class Page
{
public:
/*!
* Read an Ogg page from the \a file at the position \a pageOffset.
*/
Page(File *file, long pageOffset);
virtual ~Page();
/*!
* Returns the page's position within the file (in bytes).
*/
long fileOffset() const;
/*!
* Returns a pointer to the header for this page. This pointer will become
* invalid when the page is deleted.
*/
const PageHeader *header() const;
/*!
* Returns the index of the first packet wholly or partially contained in
* this page.
*
* \see setFirstPacketIndex()
*/
int firstPacketIndex() const;
/*!
* Sets the index of the first packet in the page.
*
* \see firstPacketIndex()
*/
void setFirstPacketIndex(int index);
/*!
* When checking to see if a page contains a given packet this set of flags
* represents the possible values for that packets status in the page.
*
* \see containsPacket()
*/
enum ContainsPacketFlags {
//! No part of the packet is contained in the page
DoesNotContainPacket = 0x0000,
//! The packet is wholly contained in the page
CompletePacket = 0x0001,
//! The page starts with the given packet
BeginsWithPacket = 0x0002,
//! The page ends with the given packet
EndsWithPacket = 0x0004
};
/*!
* Checks to see if the specified \a packet is contained in the current
* page.
*
* \see ContainsPacketFlags
*/
ContainsPacketFlags containsPacket(int index) const;
/*!
* Returns the number of packets (whole or partial) in this page.
*/
uint packetCount() const;
/*!
* Returns a list of the packets in this page.
*
* \note Either or both the first and last packets may be only partial.
* \see PageHeader::firstPacketContinued()
*/
ByteVectorList packets() const;
/*!
* Returns the size of the page in bytes.
*/
int size() const;
ByteVector render() const;
/*!
* Defines a strategy for pagination, or grouping pages into Ogg packets,
* for use with pagination methods.
*
* \note Yes, I'm aware that this is not a canonical "Strategy Pattern",
* the term was simply convenient.
*/
enum PaginationStrategy {
/*!
* Attempt to put the specified set of packets into a single Ogg packet.
* If the sum of the packet data is greater than will fit into a single
* Ogg page -- 65280 bytes -- this will fall back to repagination using
* the recommended page sizes.
*/
SinglePagePerGroup,
/*!
* Split the packet or group of packets into pages that conform to the
* sizes recommended in the Ogg standard.
*/
Repaginate
};
/*!
* Pack \a packets into Ogg pages using the \a strategy for pagination.
* The page number indicater inside of the rendered packets will start
* with \a firstPage and be incremented for each page rendered.
* \a containsLastPacket should be set to true if \a packets contains the
* last page in the stream and will set the appropriate flag in the last
* rendered Ogg page's header. \a streamSerialNumber should be set to
* the serial number for this stream.
*
* \note The "absolute granule position" is currently always zeroed using
* this method as this suffices for the comment headers.
*
* \warning The pages returned by this method must be deleted by the user.
* You can use List<T>::setAutoDelete(true) to set these pages to be
* automatically deleted when this list passes out of scope.
*
* \see PaginationStrategy
* \see List::setAutoDelete()
*/
static List<Page *> paginate(const ByteVectorList &packets,
PaginationStrategy strategy,
uint streamSerialNumber,
int firstPage,
bool firstPacketContinued = false,
bool lastPacketCompleted = true,
bool containsLastPacket = false);
protected:
/*!
* Creates an Ogg packet based on the data in \a packets. The page number
* for each page will be set to \a pageNumber.
*/
Page(const ByteVectorList &packets,
uint streamSerialNumber,
int pageNumber,
bool firstPacketContinued = false,
bool lastPacketCompleted = true,
bool containsLastPacket = false);
private:
Page(const Page &);
Page &operator=(const Page &);
class PagePrivate;
PagePrivate *d;
};
}
}
#endif

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